This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Local Watch Window variables have wrong values...

While using the uV2 dscope debugger (in bootstrap loader mode) on my C167 board, the variables in my local watch window seemed to be working just fine, for a while, and then one of the local var's didn't seem to work anymore. For example, in the below code snippet, the local var 'i' always shows that it has the value of '1' in the watch window, no matter what the value of 'x' is displayed as, as I step past the code that assigns the value of 'x' to 'i'; and as the code is stepped through the ++i statement. Anyone know why this might be, and how I can fix it?

// U1 is a 16-bit latch clocked by CS4-
// U1 inputs are connected to the uC data bus
#define U1 HVAR(unsigned int 0x400000)
void foo(unsigned int x){
    unsigned int i;
    i = x;
    while(i){
        U1=i++;
    }
}

The while(i) loop does execute the expected number of times (based on the value of 'x' passed to the function).

I'm stumped...!

Parents
  • Perhaps the compiler is too smart for the debugger to comprehend!

    Pretty close to the right answer. It's fairly common for debuggers to lose track of local variables once the code has been optimized. The variable may not stay in one place, after all -- but how does the debugger know that?

    That is, perhaps the compiler starts with i in some memory location (or register). The debugger decides that R0 is what it should display for i, because that's what the symbol table says. Once you get into the loop, it turns out that i has moved to the accumulator, and never gets written back to R0. Since the debugger is showing you R0 instead of A, you see the wrong value for i. (R0 might even get used for something else.)

    When you declare i "static", you're saying that it has a lifetime outside of this function call. Typically that will result in the variable being "nailed down" to one particular memory location; that location has to be updated with the value of i at least when the function exits. Like as not, it gets continually updated. Since i isn't moving around this time, the debugger can show you the right value.

    In theory, a compiler should be able to tell a debugger where a local is at all times. It would have to generate lots of symbol table records for limited scopes in the program. ("On line #1045, i is address 4. On line #1047, i is R0. On line #1048, i is A...") In practice, I've seen lots of symbolic debuggers simply lose track of locals, whether from lack of information or lack of proper use of the information. Makes them a lot less useful. Luckily, this sort of thing typically happens only a a small scale, so you've only got to follow your local (at assembly level) as it jumps through a fairly short series of hoops.

    The above is a hypothetical and general description. Study the assembly code that the compiler output, and you'll likely be enlightened at to what is actually going on with this particular compiler and debugger.

Reply
  • Perhaps the compiler is too smart for the debugger to comprehend!

    Pretty close to the right answer. It's fairly common for debuggers to lose track of local variables once the code has been optimized. The variable may not stay in one place, after all -- but how does the debugger know that?

    That is, perhaps the compiler starts with i in some memory location (or register). The debugger decides that R0 is what it should display for i, because that's what the symbol table says. Once you get into the loop, it turns out that i has moved to the accumulator, and never gets written back to R0. Since the debugger is showing you R0 instead of A, you see the wrong value for i. (R0 might even get used for something else.)

    When you declare i "static", you're saying that it has a lifetime outside of this function call. Typically that will result in the variable being "nailed down" to one particular memory location; that location has to be updated with the value of i at least when the function exits. Like as not, it gets continually updated. Since i isn't moving around this time, the debugger can show you the right value.

    In theory, a compiler should be able to tell a debugger where a local is at all times. It would have to generate lots of symbol table records for limited scopes in the program. ("On line #1045, i is address 4. On line #1047, i is R0. On line #1048, i is A...") In practice, I've seen lots of symbolic debuggers simply lose track of locals, whether from lack of information or lack of proper use of the information. Makes them a lot less useful. Luckily, this sort of thing typically happens only a a small scale, so you've only got to follow your local (at assembly level) as it jumps through a fairly short series of hoops.

    The above is a hypothetical and general description. Study the assembly code that the compiler output, and you'll likely be enlightened at to what is actually going on with this particular compiler and debugger.

Children
  • Thanks for the detailed theoretical explanation Drew. I'm sure that developing high quality tools for these embedded micros is quite a tough challenge. Fortunately, I'm not expecting perfection, nor an ideal world. I'm just glad that the debugger appears to be working okay, and I can get back to finishing my project.