Opened 11 years ago
Closed 11 years ago
#10459 closed bug (no change required)
[Debugger] Investigate anomalous single stepping behavior
Reported by: | anevilyak | Owned by: | anevilyak |
---|---|---|---|
Priority: | normal | Milestone: | R1 |
Component: | Applications/Debugger | Version: | R1/Development |
Keywords: | Cc: | stippi | |
Blocked By: | Blocking: | ||
Platform: | All |
Description
In certain instances, some unusual single stepping behavior can be observed, as seen in the attached example program. If one steps through the program until hitting line 19, the next single step would be expected to jump to either the closing scope line of the current block (line 22), or the closing line of the function (line 25).
With gcc2, the latter is observed as expected. With gcc4 however, the next step unexpectedly takes us to line 21 instead. There are some differences in the generated line number programs between the two compilers, but at least a cursory glance through our state machine implementation doesn't reveal any obvious problems in handling the involved opcodes. It should further be noted that this behavior is only observed when the locally scoped object is declared at line 15 ; without it, behavior similar to gcc2 is observed.
Needs further investigation, and probably some additional tracing output to allow us to better compare our state machine execution with the corresponding output of objdump for the line number program in question. One possible candidate that gcc4 emits that gcc2 does not is the discriminator, but the DWARF specification is quite vague on how to actually make use of that apart from simply parsing the corresponding instruction/value.
Objdump output for gcc2:
Raw dump of debug contents of section .debug_line: Offset: 0x0 Length: 252 DWARF Version: 2 Prologue Length: 46 Minimum Instruction Length: 4 Initial value of 'is_stmt': 1 Line Base: -10 Line Range: 245 Opcode Base: 10 Opcodes: Opcode 1 has 0 args Opcode 2 has 1 args Opcode 3 has 1 args Opcode 4 has 1 args Opcode 5 has 1 args Opcode 6 has 0 args Opcode 7 has 0 args Opcode 8 has 0 args Opcode 9 has 1 args The Directory Table is empty. The File Name Table: Entry Dir Time Size Name 1 0 0 0 steptest.cpp 2 0 0 0 <internal> Line Number Statements: Extended opcode 2: set Address to 0xa30 Special opcode 20: advance Address by 0 to 0xa30 and Line by 10 to 11 Extended opcode 2: set Address to 0xa43 Special opcode 11: advance Address by 0 to 0xa43 and Line by 1 to 12 Extended opcode 2: set Address to 0xa4a Special opcode 11: advance Address by 0 to 0xa4a and Line by 1 to 13 Extended opcode 2: set Address to 0xa4a Special opcode 11: advance Address by 0 to 0xa4a and Line by 1 to 14 Extended opcode 2: set Address to 0xa4a Special opcode 11: advance Address by 0 to 0xa4a and Line by 1 to 15 Extended opcode 2: set Address to 0xa59 Special opcode 11: advance Address by 0 to 0xa59 and Line by 1 to 16 Extended opcode 2: set Address to 0xa5f Special opcode 11: advance Address by 0 to 0xa5f and Line by 1 to 17 Extended opcode 2: set Address to 0xa80 Special opcode 11: advance Address by 0 to 0xa80 and Line by 1 to 18 Extended opcode 2: set Address to 0xa89 Special opcode 11: advance Address by 0 to 0xa89 and Line by 1 to 19 Extended opcode 2: set Address to 0xaa6 Special opcode 11: advance Address by 0 to 0xaa6 and Line by 1 to 20 Extended opcode 2: set Address to 0xaaf Special opcode 11: advance Address by 0 to 0xaaf and Line by 1 to 21 Extended opcode 2: set Address to 0xae8 Special opcode 13: advance Address by 0 to 0xae8 and Line by 3 to 24 Extended opcode 2: set Address to 0xb63 Special opcode 11: advance Address by 0 to 0xb63 and Line by 1 to 25 Extended opcode 2: set Address to 0xb6c Special opcode 14: advance Address by 0 to 0xb6c and Line by 4 to 29 Extended opcode 2: set Address to 0xb7f Special opcode 11: advance Address by 0 to 0xb7f and Line by 1 to 30 Extended opcode 2: set Address to 0xb84 Special opcode 12: advance Address by 0 to 0xb84 and Line by 2 to 32 Extended opcode 2: set Address to 0xb8c Special opcode 11: advance Address by 0 to 0xb8c and Line by 1 to 33 Extended opcode 2: set Address to 0xb97 Extended opcode 1: End of Sequence Extended opcode 2: set Address to 0xb98 Special opcode 12: advance Address by 0 to 0xb98 and Line by 2 to 3 Extended opcode 2: set Address to 0xbc7 Extended opcode 1: End of Sequence Extended opcode 2: set Address to 0xbd0 Special opcode 13: advance Address by 0 to 0xbd0 and Line by 3 to 4 Extended opcode 2: set Address to 0xc1d Extended opcode 1: End of Sequence Extended opcode 2: set Address to 0xc20 Special opcode 42: advance Address by 0 to 0xc20 and Line by 32 to 33 Extended opcode 2: set Address to 0xc6c Extended opcode 1: End of Sequence
Objdump output for gcc4:
Raw dump of debug contents of section .debug_line: Offset: 0x0 Length: 127 DWARF Version: 2 Prologue Length: 35 Minimum Instruction Length: 1 Initial value of 'is_stmt': 1 Line Base: -5 Line Range: 14 Opcode Base: 13 Opcodes: Opcode 1 has 0 args Opcode 2 has 1 args Opcode 3 has 1 args Opcode 4 has 1 args Opcode 5 has 1 args Opcode 6 has 0 args Opcode 7 has 0 args Opcode 8 has 0 args Opcode 9 has 1 args Opcode 10 has 0 args Opcode 11 has 0 args Opcode 12 has 1 args The Directory Table is empty. The File Name Table: Entry Dir Time Size Name 1 0 0 0 steptest.cpp Line Number Statements: Extended opcode 2: set Address to 0x952 Special opcode 7: advance Address by 0 to 0x952 and Line by 2 to 3 Special opcode 201: advance Address by 14 to 0x960 and Line by 0 to 3 Advance PC by 26 to 0x97a Extended opcode 1: End of Sequence Extended opcode 2: set Address to 0x97a Special opcode 8: advance Address by 0 to 0x97a and Line by 3 to 4 Advance PC by constant 17 to 0x98b Special opcode 19: advance Address by 1 to 0x98c and Line by 0 to 4 Extended opcode 4: set Discriminator to 1 Set is_stmt to 0 Advance PC by 36 to 0x9b0 Special opcode 5: advance Address by 0 to 0x9b0 and Line by 0 to 4 Special opcode 201: advance Address by 14 to 0x9be and Line by 0 to 4 Advance PC by 5 to 0x9c3 Extended opcode 1: End of Sequence Extended opcode 2: set Address to 0x9c4 Special opcode 8: advance Address by 0 to 0x9c4 and Line by 3 to 4 Advance PC by constant 17 to 0x9d5 Special opcode 19: advance Address by 1 to 0x9d6 and Line by 0 to 4 Advance PC by 33 to 0x9f7 Extended opcode 1: End of Sequence Extended opcode 2: set Address to 0x898 Advance Line by 10 to 11 Copy Advance PC by constant 17 to 0x8a9 Special opcode 48: advance Address by 3 to 0x8ac and Line by 1 to 12 Special opcode 106: advance Address by 7 to 0x8b3 and Line by 3 to 15 Special opcode 216: advance Address by 15 to 0x8c2 and Line by 1 to 16 Special opcode 90: advance Address by 6 to 0x8c8 and Line by 1 to 17 Special opcode 174: advance Address by 12 to 0x8d4 and Line by 1 to 18 Special opcode 132: advance Address by 9 to 0x8dd and Line by 1 to 19 Special opcode 174: advance Address by 12 to 0x8e9 and Line by 1 to 20 Special opcode 132: advance Address by 9 to 0x8f2 and Line by 1 to 21 Advance PC by 37 to 0x917 Special opcode 8: advance Address by 0 to 0x917 and Line by 3 to 24 Special opcode 104: advance Address by 7 to 0x91e and Line by 1 to 25 Special opcode 121: advance Address by 8 to 0x926 and Line by 4 to 29 Advance PC by constant 17 to 0x937 Special opcode 132: advance Address by 9 to 0x940 and Line by 1 to 30 Special opcode 77: advance Address by 5 to 0x945 and Line by 2 to 32 Special opcode 76: advance Address by 5 to 0x94a and Line by 1 to 33 Advance PC by 7 to 0x951 Extended opcode 1: End of Sequence
Attachments (2)
Change History (7)
by , 11 years ago
Attachment: | steptest.cpp added |
---|
follow-up: 2 comment:1 by , 11 years ago
Can you attach the disassembly for the program? It is possible that in the code gcc generates some function exits share instructions (other than the epilogue).
comment:2 by , 11 years ago
Replying to bonefish:
It is possible that in the code gcc generates some function exits share instructions (other than the epilogue).
Disassembly attached. If that's indeed the case, then that perfectly explains the presence of the aforementioned discriminator command, as its intended purpose is precisely to differentiate multiple source lines overlapping the same instruction address. The problem I have is simply that from the specification, it's not obvious how to actually determine which of said lines is the correct one while stepping, as no other reference is made to it beyond the line number program section (c.f. http://dwarfstd.org/doc/DWARF4.pdf section 6.2).
follow-up: 4 comment:3 by , 11 years ago
The three cases do use the same exit code:
318 8c2: 83 7d e4 05 cmpl $0x5,-0x1c(%ebp) 319 8c6: 75 0c jne 8d4 <_Z1av+0x3c> 320 8c8: be 03 00 00 00 mov $0x3,%esi 321 8cd: bf 00 00 00 00 mov $0x0,%edi 322 8d2: eb 2f jmp 903 <_Z1av+0x6b> 323 8d4: 81 7d e4 ef cd ab 00 cmpl $0xabcdef,-0x1c(%ebp) 324 8db: 75 0c jne 8e9 <_Z1av+0x51> 325 8dd: be 0c 00 00 00 mov $0xc,%esi 326 8e2: bf 00 00 00 00 mov $0x0,%edi 327 8e7: eb 1a jmp 903 <_Z1av+0x6b> 328 8e9: 81 7d e4 e0 2e 00 00 cmpl $0x2ee0,-0x1c(%ebp) 329 8f0: 75 0c jne 8fe <_Z1av+0x66> 330 8f2: be 05 00 00 00 mov $0x5,%esi 331 8f7: bf 00 00 00 00 mov $0x0,%edi 332 8fc: eb 05 jmp 903 <_Z1av+0x6b>
It's really just for the destruction of myA
and the epilogue, though:
334 903: 83 ec 0c sub $0xc,%esp 335 906: 8d 45 dc lea -0x24(%ebp),%eax 336 909: 50 push %eax 337 90a: e8 51 fd ff ff call 660 <_ZN1AD1Ev@plt> 338 90f: 83 c4 10 add $0x10,%esp 339 912: 83 ff 01 cmp $0x1,%edi 340 915: 75 05 jne 91c <_Z1av+0x84> 341 917: be 11 00 00 00 mov $0x11,%esi 342 91c: 89 f0 mov %esi,%eax 343 91e: 8d 65 f4 lea -0xc(%ebp),%esp 344 921: 5b pop %ebx 345 922: 5e pop %esi 346 923: 5f pop %edi 347 924: 5d pop %ebp 348 925: c3 ret
I haven't checked how the addresses match up with the line number info.
comment:4 by , 11 years ago
Replying to bonefish:
The three cases do use the same exit code: [...] It's really just for the destruction of
myA
and the epilogue, though:
That's more or less what I expected, what's odd to me is simply that said exit code is being computed as matching the address of the third return statement rather than the closing brace. That could simply be a quirk of gcc that we can't do anything about though, but I want to verify the line number program to be sure, as that behavior is a bit confusing.
comment:5 by , 11 years ago
Resolution: | → no change required |
---|---|
Status: | new → closed |
After digging a bit further, I'm forced to conclude that this is indeed simply a quirk of the line number program in question. Both objdump and our state machine agree that line 21 (aka "return 5") spans range 0x8f2-0x917, unrelocated. As you pointed out, 0x903 is the starting point of the object destructor + epilogue, aka in the middle of the aforementioned statement, and that is in fact precisely the address we wind up at after stepping over line 19. So yes, gcc has condensed that last return + destructor/epilogue into a single statement for debugging purposes, and there's unfortunately nothing we can really do to simplify the confusion there.
Test program that reproduces the described problem.