Page 1 of 1

JTAG: Watch for optimized code and code paths

Posted: Sat Apr 28, 2018 2:59 pm
by kolban
I post this as much as learning that cost me an hours debugging as much as anything else. I was hunting a problem where an ESP32 API was returning an error code. I used JTAG to step through the source and found that the return was apparently here (see marked line):

Code: Select all

/*config ip information can't contain local ip*/
if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) {
    return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;                        <------------------- HERE
}

/*config ip information must be in the same segment as the local ip*/
softap_ip >>= 8;
if ((start_ip >> 8 != softap_ip)
        || (end_ip >> 8 != softap_ip)) {
    return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
}

if (end_ip - start_ip > DHCPS_MAX_LEASE) {
    return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
}
I had only been paying half attention and had been stepping through quickly. However, when I looked at the expression that, if true, would cause that statement to be executed, I couldn't convince myself that it was in fact true. I hunted and hunted. I then tested again using JTAG one more time ... this time I paid VERY close attention. We reached that "if" condition and .... stepped over it. When then moved onwards and reached the second "if" condition ... and stepped over that too. We reached the third "if" condition and THAT one was true. However, rather than step me into the return of the third "if" condition, JTAG then showed that I was at the return of the FIRST "if" condition. Is this a bug? I can hear some folks say yes and some folks say no.

Since all the body of the "if" statements are the same in each case (a simple return statement), I'm going to guess that the compiler has decided to "optimize" them to the first one encountered and that is why we are seeing that the return is the return belonging to the wrong if conditional.

My takeaway from this is to be a little bit careful when stepping through code because this is at least one occurrence where stepping doesn't appear to execute sequential code.