2

I am analyzing core dump of my application and as I go to frame #1, I print value of variable that is stored in EAX. Gdb prints value, which if was true program wouldn't call panic (disassemble shows, that it compares value from register, so no other thread could've changed it). I invoked info reg and apart of instruction pointer gave me the same result for both frame #0 and #1. Is it possible, that Gdb shows value of register EAX for frame #0 when in frame #1?

EDIT: code looks like that:

switch(myVar){
    case -1:
        break;
    default:
        panic();
}

gdb shows:

(gdb) bt
#0 panic()
#1 0x0891a3e9 in myFunc() at myFunc.c:10
(gdb) up
#1 0x0891a3e9 in myFunc() at myFunc.c:10
10    panic();
(gdb) print myVar
$1 = -1
(gdb) print &myVar
Address requested for identifier "myVar" which is in register $eax
jbulatek
  • 154
  • 10

1 Answers1

6

Is it possible, that Gdb shows value of register EAX for frame #0 when in frame #1?

Not only possible, but currently is.

GDB does not restore registers when stepping up / down in call stack, except for $EBP and $ESP and $EIP (and sometimes $EBX).

It can be argued that this is confusing (you don't get to see the actual value of non-restored registers when you navigate between frames).

GDB has behaved like that since ~forever, and people who debug at the assembly level know how to "fish" the right values from the stack.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • it surely is confusing when it prints wrong values of local variables – jbulatek Jul 02 '20 at 16:10
  • 1
    @jbulatek Local variables should _not_ be affected by this. If you can make https://stackoverflow.com/help/mcve, I suggest filing a bugzilla report. – Employed Russian Jul 02 '20 at 16:14
  • Strange thing is, that ```info local``` returns no results, while myVar is declared in myFunc(). Perhaps it is a result of optimalization. – jbulatek Jul 02 '20 at 16:41
  • @jbulatek: This is part of why `gcc -O0` keeps all variables in memory between statements: [Why does clang produce inefficient asm with -O0 (for this simple floating point sum)?](https://stackoverflow.com/q/53366394). I think it's new for debug info to even be able to find named variables in registers, IIRC GDB would always say "optimized out" when I've tried before. – Peter Cordes Jul 02 '20 at 17:32
  • I looked up ```disassemble myFunc``` and myVar is assigned return value of another function and it is also return value of myFunc, so there's really no reason to store it in memory. I can't reproduce it on my machine, then again my product uses some old compilers built with unusual flags – jbulatek Jul 02 '20 at 17:58
  • The information in this answer is out of date now for at least ~6 years. GDB doesn't store the registers in each frame as such, but the value of a register in frame #1 is obtained by asking frame #0 to unwind that register. Unwinding will use the debug information (or analysis of the assembly code) to return the previous value. If GDB can't find the previous value and the ABI says the register is not preserved over function calls then GDB should report the register an unavailable. In other cases you should get the correct value of the register in each frame. – Andrew Jul 05 '20 at 12:23