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

Debugger uvision5 failure when accessing an externally declared variable

Hi all,

I am stuck onto a rare problem that I try to expose next.

First, I got somewhere within the code the variable W_dp_0 declared like:

extern unsigned char    W_dp_0;

W_dp_0 is actually initialized inside a library into which I don't have access at all.

Now I show you the beginning code of function Compose_Prot(), the last line of which is the one that's causing the problem:

void Compose_Prot (void){
  bool is_valid = FALSE;
  char val[7];
  char st1, st2, st3;
  unsigned char j = (unsigned char) W_dp_0;

At the disassembler window I have the lines shown next, that correspond to the assignment to j:

0x080006BA 4882      LDR      r0,[pc,#520]  ; @0x080008C4
0x080006BC 7805      LDRB     r5,[r0,#0x00]

The memory map is like:

0x080008c4  C7 01 00 20
0x080008c8  13  01 00 20

and at the address of W_dp_0:

0x200001c6 02 03 04 01
0x200001ca 00 00 0A 00


So that after the execution, R0 is

0x200001C7

and R5, which corresponds to j variable:

0x00000003

But, if I now print values of variables in the command window I see that:

> W_dp_0
0x01040302
> &W_dp_0
0x200001C6
> (unsigned char) W_dp_0;
0x02
> j
0x03

So why j equals 0x03 and not 0x02 as expected and agreed to the Command Window?
What else can I do to find any clue that helps me find a reason?
And finally, why the disassembler computes the address 0x080008C4, instead of 0x80008c2 that would correspond to the addition of PC + 520 ( 0x080006ba + 520 ) ?

Thanks in advance,

Carles

  • Because by the time the computation occurs PC has already advanced.

    The assembler/compiler figure this out when encoding, the disassembler show the correct opcode/operand encodings, and it computes the correct address being accessed

  • First, I got somewhere within the code the variable W_dp_0 declared like:

    extern unsigned char    W_dp_0;
    


    W_dp_0 is actually initialized inside a library into which I don't have access at all.

    Two remarks to that.

    1) a declaration "somewhere within the code" is irrelevant. You need that declaration actually visible to the code snippet you're examining. I.e. that declaration had better be not "somewhere", but rather in a header file, and that header file had better be #included into the C source file you're looking at.

    2) are you absolutely certain that that variable's type is unsigned char? I ask because the debugger appears to disagree with you on that. Or why else would it print it as a 32-bit value?

    unsigned char j = (unsigned char) W_dp_0;
    


    That line of code is exremely suspicious. There's not really any sane reason why anybody would explicitly cast an unsigned char value to unsigned char, just to initialize an unsigned char variable with it. That just makes no sense whatsoever unless W_dp_0 is not, actually, of type unsigned char.

    Overall, this looks like the compiler and linker disagree with the debugger both about the type (32 bit vs. 8 bit) and the address (0x200001C7 in R0, vs. 0x200001C6 in the debugger printout) of the object called W_dp_0. One possibility how that could happen is if you have made a dog's dinner out of handling its declarations. My guess is you have more than one declaration of it "somewhere in your code", of conflicting types. That causes undefined behaviour, which in this case manifests as a confused debugger.