Issue 15432 - Win64: bad code offset in debug line number info
Summary: Win64: bad code offset in debug line number info
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86_64 Windows
: P1 major
Assignee: No Owner
URL:
Keywords: DebugInfo, pull
Depends on:
Blocks:
 
Reported: 2015-12-11 07:58 UTC by Rainer Schuetze
Modified: 2017-08-16 13:23 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Rainer Schuetze 2015-12-11 07:58:39 UTC
This program:

//////////////
import std.stdio;

enum AnotherColor { Red, }

enum Color { red, }

int main(string[] argv)
{
    Color c = Color.red;    
    writeln(AnotherColor.Red.stringof); // line 10
    return 0;
}
//////////////

compiled with "dmd -m64 -g main.d"

generates this disassembly for main (dumpbin):

_Dmain:
  0000000000000000: 55                 push        rbp
  0000000000000001: 48 8B EC           mov         rbp,rsp
  0000000000000004: 48 83 EC 28        sub         rsp,28h
  0000000000000008: 53                 push        rbx
  0000000000000009: 48 89 4D 10        mov         qword ptr [rbp+10h],rcx
  000000000000000D: 31 C0              xor         eax,eax
  000000000000000F: 89 45 E0           mov         dword ptr [rbp-20h],eax
  0000000000000012: 48 8D 0D 00 00 00  lea         rcx,[_TMP0]
                    00
  0000000000000019: BB 03 00 00 00     mov         ebx,3
  000000000000001E: 48 89 5D F0        mov         qword ptr [rbp-10h],rbx
  0000000000000022: 48 89 4D F8        mov         qword ptr [rbp-8],rcx
  0000000000000026: 48 8D 4D F0        lea         rcx,[rbp-10h]
  000000000000002A: 48 83 EC 20        sub         rsp,20h
  000000000000002E: E8 00 00 00 00     call        _D3std5stdio16__T7writelnTAyaZ7writelnFNfAyaZv
  0000000000000033: 48 83 C4 20        add         rsp,20h
  0000000000000037: 31 C0              xor         eax,eax
  0000000000000039: 5B                 pop         rbx
  000000000000003A: 48 8D 65 00        lea         rsp,[rbp]
  000000000000003E: 5D                 pop         rbp
  000000000000003F: C3                 ret

and these line number infos ("c:\Program Files (x86)\VisualD\cv2pdb\dumplines"):

Sym: _Dmain
File: main.d
	Off 0x0: Line 7
	Off 0xd: Line 9
	Off 0x12: Line 10
	Off 0x36: Line 12

Please note, that the code offset for line 12 is not at the beginning of an address, so setting a breakpoint there corrupts execution (the debugger changes the respective code byte to 0xcc).
Comment 1 yazan.dabain 2015-12-11 11:14:25 UTC
I understand that you are talking about the debug symbols, right? If so, the following is not the cause of this bug.

This bug reminded me of a change I made in the stack trace addresses generation (https://github.com/D-Programming-Language/druntime/commit/8822115bc8d52fa61c15cef38fe77349f18747b9) that I did not test the effect of on Windows.

I made this change so that the addresses coming from the stack trace point before the return address (i.e. to point at the call instruction even though it most probably won't point at the start of it). I don't know if the address to line handler on Windows produces correct mappings for such addresses.
Comment 2 Rainer Schuetze 2015-12-12 07:45:01 UTC
Yes, I'm referring to the debug information generated by dmd, so libraries cannot cause this.
Comment 3 Vladimir Panteleev 2017-07-03 17:31:50 UTC
I reproduced this with 2.074.1.

Detailed steps to reproduce (without assuming prior knowledge):

1. You need:
  - dumpbin.exe (Visual Studio or Windows SDK)
  - dumplines.exe (build from source from https://github.com/rainers/cv2pdb, install Visual D from https://github.com/dlang/visuald/releases, or download stand-alone binary I compiled from https://dump.thecybershadow.net/3d28f947dd7aeeb30325935bc2463d5d/dumplines.exe)

2. Save code to test.d
3. Run: dmd -g -m64 -c test.d 
4. Run: dumpbin.exe /DISASM test.obj > test.asm
5. Run: dumplines.exe test.obj > test-lines.txt
6. In test-lines.txt, note the offsets (Off 0x### numbers) for the _Dmain function (should be the first in the file)
7. In test.asm, note the offsets (first column of hex numbers) for the instructions for the _Dmain function (should be the first in the file)

If there are any offsets in test-lines.txt's _Dmain which do not appear in test.asm's _Dmain, then it is an instance of this bug.

A self-contained example would be nice. Would it be possible to reproduce this issue e.g. by throwing an exception and looking at the stack trace for an address not mapped to a line number OSLT?
Comment 4 Rainer Schuetze 2017-07-03 18:37:58 UTC
Here's a further reduction:

///////////////////
void call15432(string col) {}

int test15432() // line 8
{
    call15432(null);
    return 0;
}
///////////////////

dumpbin:
_D7testpdb9test15432FZi:
  0000000000000000: 55                 push        rbp
  0000000000000001: 48 8B EC           mov         rbp,rsp
  0000000000000004: 48 83 EC 10        sub         rsp,10h
  0000000000000008: 48 C7 45 F0 00 00  mov         qword ptr [rbp-10h],0
                    00 00
  0000000000000010: 48 C7 45 F8 00 00  mov         qword ptr [rbp-8],0
                    00 00
  0000000000000018: 48 8D 4D F0        lea         rcx,[rbp-10h]
  000000000000001C: 48 83 EC 20        sub         rsp,20h
  0000000000000020: E8 00 00 00 00     call        _D7testpdb9call15432FAyaZv
  0000000000000025: 48 83 C4 20        add         rsp,20h
  0000000000000029: 31 C0              xor         eax,eax
  000000000000002B: 48 8B E5           mov         rsp,rbp
  000000000000002E: 5D                 pop         rbp
  000000000000002F: C3                 ret

cvdump (https://github.com/Microsoft/microsoft-pdb/blob/master/cvdump/cvdump.exe):
*** LINES
      8 00000000     10 00000008     11 00000029     12 0000002A

You could get the offset to the line number before a stack address, but the return adress is still in the preceding line because there is some cleanup code after the call. In this code, the bad adress is even after the line with "return".

Enumerating the line number info is possible in test/runnable/testpdb.d, but a test will have to check specific code to be generated. At least, I don't have an idea what to test for instead.
Comment 5 Rainer Schuetze 2017-07-09 10:20:01 UTC
https://github.com/dlang/dmd/pull/6979
Comment 6 github-bugzilla 2017-07-26 06:57:21 UTC
Commits pushed to master at https://github.com/dlang/dmd

https://github.com/dlang/dmd/commit/399b12d8d6feaf43ced88c2559404f29ab70c496
fix issue 15432: Win64: bad code offset in debug line number info

pinhole optimization should not yield different results if run twice

https://github.com/dlang/dmd/commit/a7867ca72bf51a6db9e3ed44428e142a21d3de75
Merge pull request #6979 from rainers/issue15432

fix issue 15432: Win64: bad code offset in debug line number info
merged-on-behalf-of: Rainer Schuetze <rainers@users.noreply.github.com>
Comment 7 github-bugzilla 2017-08-07 13:17:27 UTC
Commits pushed to newCTFE at https://github.com/dlang/dmd

https://github.com/dlang/dmd/commit/399b12d8d6feaf43ced88c2559404f29ab70c496
fix issue 15432: Win64: bad code offset in debug line number info

https://github.com/dlang/dmd/commit/a7867ca72bf51a6db9e3ed44428e142a21d3de75
Merge pull request #6979 from rainers/issue15432
Comment 8 github-bugzilla 2017-08-16 13:23:37 UTC
Commits pushed to stable at https://github.com/dlang/dmd

https://github.com/dlang/dmd/commit/399b12d8d6feaf43ced88c2559404f29ab70c496
fix issue 15432: Win64: bad code offset in debug line number info

https://github.com/dlang/dmd/commit/a7867ca72bf51a6db9e3ed44428e142a21d3de75
Merge pull request #6979 from rainers/issue15432