5

I am debugging an ARM microcontroller remotely and trying to modify a variable with gdb in the following block of code:

for (int i = 0; i < 100; i++) {
    __asm__("nop");
}

When I execute print i I can see the value of the variable

(gdb) print i
$1 = 0

Executing whatis i returns this

whatis i
~"type = int\n"

But when I try to change the variable I get the following error

(gdb) set variable i=99
Left operand of assignment is not an lvalue.

What am I doing wrong here?

UPDATE: here is the assembler code

!        for (int i = 0; i < 100; i++) {
main+38: subs\tr3, #1
main+40: bne.n\t0x80001d0 <main+36>
main+42: b.n\t0x80001c4 <main+24>
main+44: lsrs\tr0, r0, #16
main+46: ands\tr2, r0
!            __asm__("nop");
main+36: nop    
Ashton H.
  • 291
  • 1
  • 5
  • 15
  • 3
    FYI I get the same behavior with gcc 4.8.1 on amd64 ubuntu when I compile with `-O3` but not with `-O0`, so try compiling without optimizations. – user786653 Mar 10 '14 at 19:12
  • I tried compiling without optimization - no luck – Ashton H. Mar 10 '14 at 19:21
  • 1
    Can you modify any variables? How about if you make `i` volatile? You could also include a listing of the generated assembler code (with debugging information included i.e. `gcc -S` or equivalent). – user786653 Mar 10 '14 at 19:39
  • Strangely, after changing `i` to volatile gdb does allow me to modify it's value – Ashton H. Mar 10 '14 at 19:47
  • 2
    Seems like gdb won't let you set variable values unless the variable has a memory location (which `volatile` force it into). In your original case you could set the relevant CPU register in stead. In this case I think that would be `set $r3 = 1` ( since it looks like it's counting down and using `r3`. ). – user786653 Mar 10 '14 at 19:58
  • You are right, I can achieve this by modifying `r3` register. Another strange thing: I am able to modify a variable if I declare it outside of the main() scope. – Ashton H. Mar 10 '14 at 20:15
  • I think @user786653 should post an answer. – aschepler Mar 10 '14 at 20:25
  • I can't seem to find any good sources to quote ATM, so anyone (including the OP) is free to type up an answer. – user786653 Mar 10 '14 at 20:40
  • Are you using any compiler optimisation? I had the exact same problem as you. Some more info is here: http://stackoverflow.com/questions/1345338/gdb-behavior-value-optimized-out -- I would recommend turning off any optimisation before debugging. – oLas May 07 '15 at 13:24
  • 1
    @oLas - disabling optimizations was the first thing I tried. I did figure it out eventually - can't remember all the details, but the problem was related to the GNU toolchain that I used. – Ashton H. May 08 '15 at 13:11

4 Answers4

4

I had the same problem and making the variable volatile helped.

1

The command would be just set i = 99

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
0

Try it this way:

(gdb) print i
$1 = 3
(gdb) set var i=6
(gdb) print i
$2 = 6
eduardtm
  • 76
  • 6
0

There is two issue here change the variable name from i to var_i as there are some set command starting with i so set i=6 will gives the ambiguous command set error.

The "Left operand of assignment is not an lvalue." can be fixed with the code changes as shown below.

volatile int var_i = 1;
  TRACE((2255, 0, NORMAL, "Ravi I am sleeping here........."));
  do
  {
          sleep(5);
          var_i = 1;
  }while(var_i);
(gdb)bt
#1  0x00007f67fd7b9404 in sleep () from /lib64/libc.so.6
#2  0x00000000004cd410 in pgWSNVBUHandleGetUser (warning: Source file is more recent than executable.
ptRequest=<optimized out>, oRequest=<optimized out>,

(gdb) finish
Run till exit from #0  0x00007f67fd7b9550 in __nanosleep_nocancel () from /lib64/libc.so.6
0x00007f67fd7b9404 in sleep () from /lib64/libc.so.6
(gdb) finish
Run till exit from #0  0x00007f67fd7b9404 in sleep () from /lib64/libc.so.6
0x00000000004cd410 in pgWSNVBUHandleGetUser (ptRequest=<optimized out>, oRequest=<optimized out>,
    pptResponse=0x7fff839e8760) at /root/Checkouts/trunk/source/base/webservice/provnvbuuser.c:376
    (gdb)
      │372       volatile int var_i = 1;                                                                                           │
       │373       TRACE((2255, 0, NORMAL, "Ravi I am sleeping here........."));                                            │
       │374       do                                                                                                       │
       │375       {                                                                                                        │
      >│376         sleep(5);                                                                                              │
       │377         var_i = 1;                                                                                             │
       │378       }while(var_i);        

(gdb) set var_i=0
(gdb) n
(gdb) p var_i
$1 = 1
(gdb) set var_i=0
(gdb) p var_i
$2 = 0
(gdb) n
(gdb) n
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343