Summary: | GDB prints a wrong value at -O3 | ||
---|---|---|---|
Product: | gdb | Reporter: | Qirun Zhang <helloqirun> |
Component: | gdb | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | NEW --- | ||
Severity: | normal | CC: | aoliva, mark, tromey |
Priority: | P2 | ||
Version: | unknown | ||
Target Milestone: | --- | ||
See Also: | https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89529 | ||
Host: | Target: | ||
Build: | Last reconfirmed: | 2019-04-17 00:00:00 |
Description
Qirun Zhang
2019-04-17 03:49:00 UTC
I can reproduce the `i = 9` behavior using the Fedora 29 system gcc. The DWARF for "i": <2><6b>: Abbrev Number: 6 (DW_TAG_variable) <6c> DW_AT_name : i <6e> DW_AT_decl_file : 1 <6f> DW_AT_decl_line : 3 <70> DW_AT_decl_column : 7 <71> DW_AT_type : <0xc2> <75> DW_AT_location : 0x16 (location list) <79> DW_AT_GNU_locviews: 0x0 So, let's look at location list 0x16: 00000016 v000000000000003 v000000000000000 views at 00000000 for: 0000000000400420 0000000000400431 (DW_OP_lit0; DW_OP_stack_value) 0000002a v000000000000000 v000000000000000 views at 00000002 for: 0000000000400431 000000000040043c (DW_OP_lit1; DW_OP_stack_value) 0000003e v000000000000000 v000000000000000 views at 00000004 for: 000000000040043c 0000000000400447 (DW_OP_lit2; DW_OP_stack_value) 00000052 v000000000000000 v000000000000000 views at 00000006 for: 0000000000400447 0000000000400452 (DW_OP_lit3; DW_OP_stack_value) 00000066 v000000000000000 v000000000000000 views at 00000008 for: 0000000000400452 000000000040045d (DW_OP_lit4; DW_OP_stack_value) 0000007a v000000000000000 v000000000000000 views at 0000000a for: 000000000040045d 0000000000400468 (DW_OP_lit5; DW_OP_stack_value) 0000008e v000000000000000 v000000000000000 views at 0000000c for: 0000000000400468 0000000000400473 (DW_OP_lit6; DW_OP_stack_value) 000000a2 v000000000000000 v000000000000000 views at 0000000e for: 0000000000400473 000000000040047e (DW_OP_lit7; DW_OP_stack_value) 000000b6 v000000000000000 v000000000000000 views at 00000010 for: 000000000040047e 0000000000400489 (DW_OP_lit8; DW_OP_stack_value) 000000ca v000000000000000 v000000000000000 views at 00000012 for: 0000000000400489 0000000000400495 (DW_OP_lit9; DW_OP_stack_value) 000000de v000000000000000 v000000000000000 views at 00000014 for: 0000000000400495 000000000040049c (DW_OP_lit2; DW_OP_stack_value) 000000f2 <End of list> Now in gdb, let's find the PC in question: (gdb) b 11 Breakpoint 1 at 0x400489: file abc.c, line 11. (gdb) r Starting program: /tmp/qq Breakpoint 1, main () at abc.c:11 11 optimize_me_not(); (gdb) p $pc $1 = (void (*)()) 0x400489 <main+105> Looking this up in the location list: 0000000000400489 0000000000400495 (DW_OP_lit9; DW_OP_stack_value) In other words, gcc tells gdb that the value is 9. Now, what is interesting is that lldb sets a different breakpoint location: (lldb) b 11 Breakpoint 1: where = qq`main + 4 at abc.c:11, address = 0x0000000000400424 Reproducing this in gdb: (gdb) b *0x400424 Breakpoint 1 at 0x400424: file abc.c, line 6. (gdb) r Starting program: /tmp/qq Missing separate debuginfos, use: dnf debuginfo-install glibc-2.28-27.fc29.x86_64 Breakpoint 1, 0x0000000000400424 in main () at abc.c:6 6 a = i; (gdb) p i $1 = 0 So maybe gdb is misinterpreting the line table somehow; but at the same time there is a gcc bug here IMO. > So maybe gdb is misinterpreting the line table somehow; but at the same
time there is a gcc bug here IMO.
I think what is happening is that gcc -O3 unrolls the second loop. In which case the value of i doesn't really matter, since it isn't actually used anymore in the code.
Also if you look at the linetable with eu-readelf --debug-dump=decodedline you'll see that line 11 expands to multiple addresses. Two of which have a statement marker, so are equally ok to set a breakpoint on.
I haven't looked at the location views, but maybe those can help determine which view the user expects of the variable?
There are actually 4 addresses that expand to line 11: CU [b] abc.c line:col SBPE* disc isa op address (Statement Block Prologue Epilogue *End) /tmp/abc.c (mtime: 0, length: 0) 2:12 S 0 0 0 +0x0000000000001040 <main> 3:3 S 0 0 0 +0x0000000000001040 <main> 4:3 S 0 0 0 +0x0000000000001040 <main> 5:3 S 0 0 0 +0x0000000000001040 <main> 6:5 S 0 0 0 +0x0000000000001040 <main> 2:12 0 0 0 +0x0000000000001040 <main> -> 11:7 0 0 0 +0x0000000000001044 <main+0x4> 6:7 0 0 0 +0x0000000000001046 <main+0x6> 6:5 S 0 0 0 +0x0000000000001051 <main+0x11> 6:7 0 0 0 +0x0000000000001051 <main+0x11> 6:5 S 0 0 0 +0x000000000000105c <main+0x1c> 6:7 0 0 0 +0x000000000000105c <main+0x1c> 6:5 S 0 0 0 +0x0000000000001067 <main+0x27> 6:7 0 0 0 +0x0000000000001067 <main+0x27> 6:5 S 0 0 0 +0x0000000000001072 <main+0x32> 6:7 0 0 0 +0x0000000000001072 <main+0x32> 6:5 S 0 0 0 +0x000000000000107d <main+0x3d> 6:7 0 0 0 +0x000000000000107d <main+0x3d> 6:5 S 0 0 0 +0x0000000000001088 <main+0x48> 6:7 0 0 0 +0x0000000000001088 <main+0x48> 6:5 S 0 0 0 +0x0000000000001093 <main+0x53> 6:7 0 0 0 +0x0000000000001093 <main+0x53> 6:5 S 0 0 0 +0x000000000000109e <main+0x5e> 6:7 0 0 0 +0x000000000000109e <main+0x5e> -> 11:7 S 0 0 0 +0x00000000000010a9 <main+0x69> -> 11:7 S 0 0 0 +0x00000000000010ae <main+0x6e> -> 11:7 0 0 0 +0x00000000000010b5 <main+0x75> 13:1 0 0 0 +0x00000000000010b5 <main+0x75> 13:1 * 0 0 0 +0x00000000000010bb <main+0x7b> So the two places where i = 0 were "merged" by the compiler. |