------- 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