如何从崩溃转储中确定导致错误的指令

时间:2012-09-24 10:37:00

标签: .net debugging crash-dumps

当引发异常时,我为带有参数

的.NET应用程序创建了一个小型转储

MiniDumpNormal | MiniDumpWithProcessThreadData | MiniDumpWithThreadInfo | MiniDumpWithUnloadedModules

提取托管调用栈所需的

(来自What is minimum MINIDUMP_TYPE set to dump native C++ process that hosts .net component to be able to use !clrstack in windbg)。迷你转储生成在here

所述的异常过滤器中执行

在WinDBG中的崩溃转储上执行!dumpstack时,可以看到类似

的内容
ChildEBP RetAddr  Caller,Callee
...
001dccc0 09b301a3 (MethodDesc 0x274268c +0x133 MyNameSpace.ErrorObject.FaultyMethod(Int32))
...

如果我没弄错,这意味着错误是在方法FaultyMethod中的偏移量0x133处生成的,其中0x133是JIT编译的机器代码中的偏移量。

如何将此偏移量转换回源代码或IL行号以识别导致异常的指令?

2 个答案:

答案 0 :(得分:1)

您是否尝试使用windbg中的SOS.dll进行调试?您可以使用CLRStack命令获取托管代码堆栈跟踪。有关加载它的说明,请参阅Unable to load SOS in WinDbg。但是,如您所说,dumpstack给出指令偏移量。

要转换指令偏移量,一种笨重但可行的方法是将可疑程序集加载到ILDASM中,深入查看类和方法/属性并查看IL。指令前面是IL_XXXX,其中XXXX是方法开头的十六进制偏移量。它不会为您提供确切的代码,但它会为您提供更多信息,尤其是方法调用。

答案 1 :(得分:0)

如果有人有兴趣,这是我解决问题的方法。首先将MiniDumpWithIndirectlyReferencedMemory添加到MiniDumpWriteDump调用。这将导致包含由堆栈上的指针引用的内存页面。虽然MSDN声明"这个选项可以显着增加minidump文件的大小"在我的测试中,迷你转储文件的大小增长不超过几百KB。

现在转储中提供了抛出异常的方法的已编译机器代码。这意味着可以在WinDBG / SOS中使用!u来反汇编代码。虽然这不完全是IL或源代码,但是将机器代码指令与IL /源代码相匹配应该不会太难。 This blog post以如何操作为例。