9

我有一大堆 minidump,它们是在应用程序运行时通过 MiniDumpWriteDump 记录的。小型转储是在与我的开发机器具有不同操作系统版本的机器上创建的。

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

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

[编辑]

我忘了说 SymLoadModule64 只接受一个文件名,没有版本/校验和信息,所以显然单独使用 SymLoadModule64 dbghelp 不可能确定要下载哪个 pdb。

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

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

[编辑]

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

如果有人可以向我指出一些使用 dbgeng.dll 处理小型转储的介绍,这可能也会有所帮助,因为 MSDN 仅记录了各个组件,但没有记录它们如何协同工作。

4

2 回答 2

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 次左右转储重新启动进程,所以我没有调查更多的。

于 2011-11-14T09:14:19.950 回答
0

自动分析多个 minidump 文件的一种简单方法是使用 John Robbins 在他的文章“使用 WinDBG 和 PowerShell 自动分析大量 Minidump 文件”中编写的脚本(您可以在 GitHub 上获取代码)。

如果默认设置不够,这很容易调整以使其执行您想要的任何 WinDbg 命令。

于 2017-02-01T15:29:25.597 回答