Crash Dump Debugging
Suspension of Disbelief: I know your first instinct may be to announce that "It isn't possible!" since this isn't how MS suggests solving the problem and they don't make tools available to accomplish it (easily). Forget that hurdle for a moment and ask yourself, "Is there some way to do this?"
I have a Windows binary I support in production that was built with debug information (MSVC 14.1 /Zi
) but the debugger reports "was not built with debug information." This not wholly true—I think it was stripped by some tool during a post-build/pre-release process that I do not control, because I do have a PDB file for it. I have a memory dump from a run (crash) of that executable. Visual Studio and WinDbg both claim that the module has "no debug info," though WinDbg will attempt to load symbols for it anyway, if it finds some that match.
DBGHELP: No debug info for MyDll.dll. Searching for dbg file
DBGHELP: r:\crashes\symbols\MyDll.dbg - file not found
DBGHELP: r:\crashes\symbols\dll\MyDll.dbg - path not found
DBGHELP: r:\crashes\symbols\symbols\dll\MyDll.dbg - path not found
DBGHELP: MyDll.dll missing debug info. Searching for pdb anyway
*** WARNING: Unable to verify checksum for MyDll.dll
DBGENG: MyDll.dll has mismatched symbols - type ".hh dbgerr003" for details
DBGHELP: MyDll - private symbols & lines
r:\crashes\symbols\MyDll.pdb - unmatched
Here's the result of !chksym MyDll
in WinDbg
MyDll.dll
Timestamp: 5CF5ABF8
SizeOfImage: 2437000
pdb sig: 0
age: 0
Loaded pdb is r:\crashes\symbols\MyDll.pdb
MyDll.pdb
pdb sig: 944F882B-73AE-45D0-9043-44C899BE09C5
age: 1
sig MISMATCH: MyDll.pdb and MyDll.dll
Is there a way to modify the memory dump (or the binary—assuming I can reproduce the problem) so as to re-inject whatever is necessary for the debugger to acknowledge that the symbols file I have matches the binary?
If your answer is "Nope!" I would appreciate some references to support that conclusion.
In the end, I want to be able to make sense of the call stack. Looking at variables/memory would be cool, too, but the call stack itself would be a gold mine in terms of debugging this problem.
Is "debug info" in this regard just a PE header (i.e. revealed by dumpbin /HEADERS
) or is it more? Can I inject this header back into the binary/module? Is there more information that the debugger needs besides the symbols file to make sense of function addresses?
The tools for resolving symbol mismatches seem to work by modifying the PDB file. In my case, that doesn't seem to work because the binary module has no PDB signature in it to match to.
References- Crash dump - WinDbg - force PDB files to match doesn't work? (StackOverflow)
- CHKMATCH (debuginfo.com)
- How to Inspect the Content of a Program Database (PDB) File (codeproject.com)
- microsoft-pdb (microsoft.com)
Corollary Questions
This is a problem I would like to solve one way or another (debugging a crash dump from a run of this "stripped" executable). So, it's possible that I'm asking the wrong question. Is there another way to solve this problem?
- Can I decode memory addresses "outside" the Visual Studio debugger using the data in the PDB file?
- Is there some other way to have the debugger use the symbols in a PDB file as if there was a match (assuming the module "has no debug info")?