在我的应用程序中,每当应用程序崩溃时,我都会使用 MiniDumpWriteDump 函数(请参阅 dbghelp.dll)写入故障转储文件。

我还使用符号服务器来存储所有可执行文件和 pdb 文件,以便每当客户向我发送故障转储文件时,调试器都会自动获取正确版本的可执行文件和调试信息。

我还将 Windows DLL(ntdll.dll、kernel32.dll...)及其调试信息存储在符号服务器中(使用 SymChk)。调试信息是从 Microsoft 的公共符号服务器获取的。

大多数时候这都可以完美工作,除非:

  • 一位客户在 Windows DLL 之一中崩溃
  • 客户使用了我没有放入符号服务器的 DLL

这是因为将每个 Windows DLL 的每种风格存储在符号服务器中是完全不可撤销的(尤其是每周的补丁)。

因此,如果客户在 NTDLL.DLL 版本 5.2.123.456 中崩溃,而我没有将这个版本的 DLL 放入我的符号服务器中,那么我就会陷入困境。即使是 Microsoft 的公共符号服务器也无济于事,因为它只提供调试信息,而不提供 DLL 本身。

我当前的解决方案是向客户询问他的 DLL,但这并不总是那么容易。因此我正在寻找更好的解决方案。

有没有办法让调试器显示正确的调用堆栈,或者加载特定 DLL 的调试信息,即使您没有 DLL 的确切版本?

或者,有没有办法获取所有(或重要的)Windows DLL(来自 Microsoft)的所有版本?

编辑:

与此同时,我找到了一个非常简单的方法来解决这个问题。使用实用程序 ModuleRescue(参见 http://www.debuginfo.com/tools/modulerescue.html)您可以从小型转储文件生成虚拟 DLL。有了这些虚拟 DLL,调试器就满意了,并正确地开始从 Microsoft 服务器加载调试符号。

有帮助吗?

解决方案

可以放宽WinDbg的符号解析;看看我的 回答 类似的问题。另一方面,我在这里提出的解决方案依赖于以下事实:DLL 是 完全相同的 除了使用不同的 GUID 来标识其调试符号之外。不同版本的 DLL 可能会有不同的二进制文件,因此即使您可以加载符号,它们也可能无法正确匹配。

其他提示

我很确定微软的符号服务器也提供了二进制文件。我在我的商店中查看,看到大量 Microsoft .dll 文件。我的 _NT_SYMBOL_PATH 定义为

SRV*F:\Symbols\Microsoft*http://msdl.microsoft.com/download/symbols

这样,它将首先搜索我的本地商店,然后再尝试从 Microsoft 的公共服务器复制它们。

你可以有 多种的 符号路径中的符号服务器。因此,只需将符号路径设置为指向您自己的私有模块的服务器,以及指向操作系统模块的公共 MS 服务器,请参阅 符号路径:

通过使用以下初始设置,可以轻松地将其与Microsoft公共符号商店结合在一起:

_NT_SYMBOL_PATH=srv*c:\mysymbols*http://msdl.microsoft.com/download/symbols;cache*c:\mysymbols

微软公共符号存储 被记录为 http://msdl.microsoft.com/download/symbols.

?哪一部分不起作用?

确切地说,我从来没有遇到过你的情况,但我希望调试器能够为你提供代码中调用堆栈的正确部分,直到调用黑暗的 dll。当然,从那里到实际的崩溃符号将不可用,但是您看不到正在调用哪个 NTDLL API 以及传递给该调用的参数吗?

您没有说明您使用哪个工具进行小型转储调试:WinDBG 或 VS。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top