如何从minidumps中提取堆栈跟踪?

时间:2011-07-06 10:30:47

标签: windows debugging crash-dumps minidump dbghelp

我有一大堆minidump,它们是在应用程序运行时通过MiniDumpWriteDump录制的。 minidump是在具有与我的开发机器不同的OS版本的机器上创建的。

现在我正在尝试编写一个程序,使用dbghelp.dll从minidump中提取堆栈跟踪。我正在走MINIDUMP_MODULE_LIST并调用SymLoadModule64,但是无法从公共符号服务器下载pdbs(kernel32等)。如果我在符号路径中添加“C:\ Windows \ System32”,它会找到dll并下载符号,但当然它们与minidump中的dll不匹配,因此结果没用。

那么如何告诉dbghelp.dll下载并使用正确的pdbs?

[编辑]

我忘了声明SymLoadModule64只接受文件名而没有版本/校验和信息,所以很明显只有SymLoadModule64,dbghelp无法找出要下载的pdb。

该信息实际上可在MINIDUMP_MODULE_LIST中获得,但我不知道如何将其传递回dbghelp API。

SymLoadModuleEx需要额外的参数,但我不知道这是否是我需要的,或者我应该为附加参数传递什么。

[编辑]

到目前为止没有运气,虽然我注意到在调试SDK中还有dbgng.dll与dbghelp.dll一起分发。 MSDN看起来很好,并说它与windbg使用的引擎相同。也许我可以使用它来提取堆栈跟踪。

如果有人能指出我使用dbgeng.dll处理可能有用的minidump的一些介绍,因为MSDN只记录各个组件,但不记录它们如何协同工作。

2 个答案:

答案 0 :(得分:8)

以防万一其他人想要自动从转储中提取堆栈跟踪,这就是我最终做的事情:

就像我在更新中提到的那样,可以使用dbgeng.dll而不是dbghelp.dll,这似乎与WinDbg使用的引擎相同。经过一些试验和错误后,如何使用与WinDbg相同的符号加载机制获得良好的堆栈跟踪。

  • 调用DebugCreate以获取调试引擎的实例
  • 查询IDebugClient4,IDebugControl4,IDebugSymbols3
  • 使用IDebugSymbols3.SetSymbolOptions配置符号的加载方式(有关WinDbg使用的选项,请参阅MSDN
  • 使用IDebugSymbols3.SetSymbolPath设置符号路径,就像在WinDbg中一样设置
  • 使用IDebugClient4.OpenDumpFileWide打开转储
  • 使用IDebugControl4.WaitForEvent等待转储加载
  • 使用IDebugSymbols3.SetScopeFromStoredEvent选择存储在转储中的异常
  • 使用IDebugControl4.GetStackTrace来获取最后几个堆栈帧
  • 使用IDebugClient4.SetOutputCallbacks注册接收解码堆栈跟踪的侦听器
  • 使用IDebugControl4.OutputStackTrace处理堆栈帧
  • 使用IDebugClient4.SetOutputCallbacks取消注册回调
  • 发布接口

对WaitForEvent的调用似乎很重要,因为没有它,以下调用无法提取堆栈跟踪。

此外似乎还有一些内存泄漏,无法判断是不是我没有正确清理或dbgeng.dll内部的东西,但我可以每20次转储重启该过程左右,所以我没有再调查一下。

答案 1 :(得分:0)

自动分析多个minidump文件的一种简单方法是使用John Robbins在他的文章"Automating Analyzing Tons Of Minidump Files With WinDBG And PowerShell"中编写的脚本(您可以获取code on GitHub)。

如果默认设置不足,可以轻松调整它以执行您喜欢的任何WinDbg命令。