------- Comment #13 from jakub at gcc dot gnu dot org 2009-09-19 12:12 ------- Consider: __attribute__((noinline)) int bar (void) { const char *foo = "foo"; asm volatile ("nop" : : : "memory"); foo = "bar"; asm volatile ("nop" : : : "memory"); return 16; }
int main (void) { bar (); return 0; } -g -O2 we get: .LLST1: .quad .LVL0-.Ltext0 # Location list begin address (*.LLST1) .quad .LVL1-.Ltext0 # Location list end address (*.LLST1) .value 0xc # Location expression size .byte 0x3 # DW_OP_addr .quad .LASF0 .byte 0x9f # DW_OP_stack_value .byte 0x93 # DW_OP_piece .uleb128 0x8 .quad .LVL1-.Ltext0 # Location list begin address (*.LLST1) .quad .LFE0-.Ltext0 # Location list end address (*.LLST1) .value 0xc # Location expression size .byte 0x3 # DW_OP_addr .quad .LASF1 .byte 0x9f # DW_OP_stack_value .byte 0x93 # DW_OP_piece .uleb128 0x8 .quad 0x0 # Location list terminator begin (*.LLST1) .quad 0x0 # Location list terminator end (*.LLST1) gdb ./test b bar r (gdb) p foo $1 = 0x42 <Address 0x42 out of bounds> (gdb) n 7 asm volatile ("nop" : : : "memory"); (gdb) p foo $2 = 0x24 <Address 0x24 out of bounds> which isn't surprising, for all other references to .debug_str we want a relative offset into the section from the start of .debug_str section. Contents of section .debug_str: 0000 474e5520 4320342e 352e3020 32303039 GNU C 4.5.0 2009 0010 30393136 20286578 70657269 6d656e74 0916 (experiment 0020 616c2900 62617200 6d61696e 002f7573 al).bar.main./us 0030 722f7372 632f6763 632f6f62 6a2f6763 r/src/gcc/obj/gc 0040 6300666f 6f006368 617200 c.foo.char. BTW, if the foo = "bar"; line is commented out, we have: .uleb128 0x3 # (DIE (0x51) DW_TAG_variable) .ascii "foo\0" # DW_AT_name .byte 0x1 # DW_AT_decl_file (t.c) .byte 0x4 # DW_AT_decl_line .long 0x68 # DW_AT_type .ascii "foo\0" # DW_AT_const_value and gdb still won't do the right thing, but again it is IMHO gcc's fault: (gdb) p foo $1 = 0x5040400006f6f66 <Address 0x5040400006f6f66 out of bounds> the value of the variable isn't the const string, but an address of it... Now, if const char *foo = "foo"; is changed into const char foo[] = "foo"; (in which case using DW_AT_const_value "foo\0" would probably be the right thing), then current trunk will drop the location for the variable on the floor. -- jakub at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jan dot kratochvil at redhat | |dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41404