Given the following code: #include "stdint.h" #include "string.h" #include <stdio.h> int a, b; char* c; static int func_1() { int i = 0; for (; i < 4; i++) ; for (; a <= 4;) { uint16_t d; b = 0; return b; { int i; } } return b; } int main() { func_1(); printf(c); } Compiled with gcc 12.2.0 and -O1 -g The DWARF says that i persists until func_1 exits Breakpoint 1, func_1 () at r.c:10 10 for (; a <= 4;) { (gdb) info addr i Symbol "i" is multi-location: Range 0x40112a-0x40112a: the constant 0 Range 0x40112a-0x40112a: the constant 1 Range 0x40112a-0x40112a: the constant 2 Range 0x40112a-0x40112a: the constant 3 Range 0x40112a-0x40113d: the constant 4 . (gdb) p i $1 = 4 But GDB says i is <optimized out> prematurely at line 12 with $pc = 0x401133 still in the range of func_1 (gdb) p i $2 = <optimized out> (gdb) p $pc $3 = (void (*)()) 0x401133 <main+13> (gdb)
It's picking up that second 'i' somehow here. It isn't obvious why, though, as that variable and its block don't seem to be referenced at all.
I've debugged it to this location of read_lexical_block_scope in dwarf2/read.c: ``` case PC_BOUNDS_NOT_PRESENT: /* DW_TAG_lexical_block has no attributes, process its children as if there was no wrapping by that DW_TAG_lexical_block. GCC does no longer produces such DWARF since GCC r224161. */ ``` The inner { int i; } block is optimized away, and apparently gcc produces this kind of block here in this case. Which means gdb moves up the i variable to the for{} block, and that's why it's found by print. As a test I've just put a return in this case block, then gdb found the correct i also in this location: ``` (gdb) n 12 b = 0; (gdb) p i $2 = 4 (gdb) info addr i Symbol "i" is multi-location: Base address 0x140001609 Range 0x13f2e1609-0x13f2e1609: the constant 0 Range 0x13f2e1609-0x13f2e1609: the constant 1 Range 0x13f2e1609-0x13f2e1609: the constant 2 Range 0x13f2e1609-0x13f2e1609: the constant 3 Range 0x13f2e1609-0x13f2e161c: the constant 4 ``` I'm not sure what the correct solution here is.
(In reply to Hannes Domani from comment #2) > I've debugged it to this location of read_lexical_block_scope in > dwarf2/read.c: > ``` > case PC_BOUNDS_NOT_PRESENT: > /* DW_TAG_lexical_block has no attributes, process its children as if > there was no wrapping by that DW_TAG_lexical_block. > GCC does no longer produces such DWARF since GCC r224161. */ > ``` This was added for PR15231.