When an exception was raised I created a mini dump for a .NET application with parameters
MiniDumpNormal | MiniDumpWithProcessThreadData | MiniDumpWithThreadInfo | MiniDumpWithUnloadedModules
which are required to extract the managed callstack (from What is minimum MINIDUMP_TYPE set to dump native C++ process that hosts .net component to be able to use !clrstack in windbg). The mini dump generation is executed in an exception filter as described here
When executing !dumpstack
on the crash dump in WinDBG a can see something like
ChildEBP RetAddr Caller,Callee
...
001dccc0 09b301a3 (MethodDesc 0x274268c +0x133 MyNameSpace.ErrorObject.FaultyMethod(Int32))
...
If I'm not mistaken this means that the error was generated at offset 0x133 in method FaultyMethod where 0x133 is the offset in the JIT compiled machine code.
How can I translate this offset back to the source code or IL line number to identify the instruction that caused the exception?
In case anyone is interested, here is my approach to the problem. It starts with adding MiniDumpWithIndirectlyReferencedMemory
to the MiniDumpWriteDump
call. That will lead to the inclusion of memory pages referenced by pointers on the stack. Although MSDN states "This option can increase the size of the minidump file significantly" in my tests the size of the mini dump file grew by no more than a few 100 KB.
Now the compiled machine code of the method that threw the exception is available in the dump. This means !u
can be used in WinDBG/SOS to disassemble the code. While this is not exactly the IL or source code it should not be too hard to match the machine code instructions with the IL/source code. This blog post features an example how to do it.