简体   繁体   中英

How does GDB know optimized out local variable values?

When I compile the following code with gcc -g -O1 t.c

int main()
{
    int a = 1;
    int b = 2;
    int c = 3;
    int d = 4;

    return 0;
}

GCC optimize out all unused local variables. This can be seen by GDB disassemble command, only instructions for return 0 were left:

(gdb) disassemble main 
Dump of assembler code for function main:
   0x0000000000401106 <+0>: mov    $0x0,%eax
   0x000000000040110b <+5>: ret    
End of assembler dump.

However, GDB somehow knows the values of variables from C code

(gdb) info locals 
a = 1
b = 2
c = 3
d = 4

How does GDB know about these values if they are absent in generated assembly code?

The message that a value was optimized out doesn't mean that a variable got optimized away. It means that the information needed to determine the variable's value is no longer available, possibly because it was overwritten or reused to hold a different variable. Here's an example of that happening:

#include <stdio.h>

int main(int argc, char **argv) {
    int x = argc + 42;
    getchar();
    return 0;
}

Compile that with gcc -g -O3 . If you do start and then step , you'll be able to do print x and see its value, even though it's never actually calculated by the program, because the debugging information says how the value would have been calculated. But if you then do next and hit Enter an extra time to let getchar return, now print x will tell you that the value was optimized out. That's because the only copy of argc the program had access to was in rdi , which got clobbered by getchar , and the compiler didn't bother to save its old value first since the program doesn't need it afterwards.

As already noted in comments, GCC stores variable values in debug info. It is possible to see them in GDB because GCC generates extra debug info when doing optimized build. Extra GCC options -fvar-tracking and -fvar-tracking-assignments are implicitly enabled in this case. If disable this extra debug info, GDB outputs <optimized out> as usual.

If to build with gcc -fno-var-tracking -g -O1 t.c , GDB output is:

(gdb) i locals 
a = <optimized out>
b = <optimized out>
c = <optimized out>
d = <optimized out>

However if to build without optimization and without var-tracking with gcc -fno-var-tracking -g -O0 t.c , GDB can get values from unoptimized code:

(gdb) i locals 
a = 1
b = 2
c = 3
d = 4

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM