Here’s our situation, the 3rd party app we’re using in our company can be customized by loading a DLL into it, but we (obviously) cannot see the source code of the host exe program, we only have access to our DLL’s source code. The problem is how to debug our DLL when crashes occured?
Yes it’s unfortunate, if the DLL did cause a crash the host exe will go down together with it. Luckily the host exe record some kind of stack trace when it crashed, here’s what it looked like (let’s call our DLL cricket.dll to simplify things):
Filename : *******
Time : 2014.11.13 18:41 (74:37:03 elapsed)
Program : ******
Version : ******
Revision : ******
OS : Windows 7 Server 6.1 Service Pack 1 (Build 7601)
BIOS : DELL - 1 - PowerEdge R420
Explorer : 9.11
ID :
Processors : 24 x Intel Xeon E5-2420 0 @ 1.90GHz
Computer : LIVE-SERVER-1:WORKGROUP
Memory : 29253 free of 32690 Mb
Virtual : 2639 free of 4095 Mb
Handlers : 14569
Path : D:********
Disk D: : 169325 Mb of 224999 Mb free
Exception : C0000005 at 70606D91 read to 1FAF001A
Modules : 01080000 009DD000 d:************.exe (*****)
: 775A0000 00180000 c:\windows\syswow64\ntdll.dll (6.1.7601.18247)
: 76EB0000 00110000 c:\windows\syswow64\kernel32.dll (6.1.7601.18409)
....
: 705F0000 00047000 cricket.dll
Pay particular attention to the Modules section at the bottom. This tells us specific address in memory where our dll was loaded by the host exe. This information will be crucial to determine the relative address further down in the stack trace.
In this instance it told us cricket.dll was loaded at 0x705F0000 and it’s of 0x00047000 bytes length.
Further down the massive stack trace, we can see the record of the particular crash-causing thread:
crash : #213 0002EFF4 EIP: 70606D91 ESP: 23CEF448
70606D91:000000 [70606D91] unknown (cricket.dll)
705FF5E1:000000 [705FF5E1] unknown (cricket.dll)
705F90C9:000000 [705F90C9] unknown (cricket.dll)
705FF1A2:000000 [705FF1A2] unknown (cricket.dll)
7060D652:000000 [7060D652] unknown (cricket.dll)
7060D6D0:000000 [7060D6D0] unknown (cricket.dll)
76EC3378:000012 [76EC338A] AcquireSRWLockExclusive (kernel32.dll)
775D9F0F:000063 [775D9F72] RtlInsertElementGenericTableAvl (ntdll.dll)
775D9F0F:000036 [775D9F45] RtlInsertElementGenericTableAvl (ntdll.dll)
crash --> 70606D91 80780F00 cmp byte [eax+0xf], 0x0
70606D95 74EB jz 0x70606d82
70606D97 8B8310040000 mov eax, [ebx+0x410]
70606D9D 89BD24FDFFFF mov [ebp+0xfffffd24], edi
70606DA3 3BF8 cmp edi, eax
70606DA5 740E jz 0x70606db5
70606DA7 663B770C cmp si, [edi+0xc]
What I really wanted to know here is which line of my source code corresponds to the hex code above? First, find out the relative address. In this circumstances, since the DLL was loaded at 0x705F0000, we have to subtract that amount from the address, so 0x70606D91 - 0x705F0000 (in base 16) is 0x00016D91 (you can pull up Windows calculator, set it to Programmer mode if base 16 math is too hard).
Next, prepare the DLL source code of the same version against that crashed on production environment (git tagging will be very helpful here). This also requires the .pdb file of corresponding DLL which hopefully you’ve saved when releasing the code. Keep in mind recompiling the exact same source might produce incompatible .pdb.
Drop the .pdb file into your Release folder, and from Visual Studio select Debug -> Attach to Process... It’ll be easier if you run the exe locally loaded with the exact same DLL that crashed.
Next you’ll need to translate the relative address into the local address of the exe your debugger is attached to. To do this:
- Open the Modules window (Debug -> Windows -> Modules)
- Find your DLL, take note of its start address

Here my local DLL is loaded at 0F75000, so I just need to add that to the relative address to localize it: 0x0F75000 + 0x0x00016D91 = 0x0F766D91
Next is to find the source code corresponding to that address:
- Open Debug -> Windows -> Disassembly
- On the address bar, input the localized address 0x0F766D91
- Right click on the line, and select Go to Source
- Voila! You’ve managed locate the culprit line, now do this for the other location on the stack trace too

Big thanks to SO community for helping me with this technique.