在符号服务器中没有确切版本的Windows DLL的验尸崩溃转储debugging

在我的应用程序中,我使用MiniDumpWriteDump函数(请参阅dbghelp.dll)在应用程序崩溃时编写崩溃转储文件。

我还使用符号服务器来存储所有的可执行文件和pdb文件,以便每当客户向我发送崩溃转储文件时,debugging程序会自动选取正确版本的可执行文件和debugging信息。

我还将Windows DLL(ntdll.dll,kernel32.dll,…)及其debugging信息存储在符号服务器中(使用SymChk)。 debugging信息从微软的公共符号服务器中获取。

大多数情况下,这是完美的,除非:

  • 客户在Windows DLL中的一个崩溃
  • 而客户使用我没有放在符号服务器中的DLL

这是因为在Symbol Server中存储每个Windows DLL的所有风格(尤其是每周补丁)是非常容易解决的。

所以,如果客户崩溃了,比方说,NTDLL.DLL的版本5.2.123.456,我没有把这个确切版本的DLL放在我的Symbol Server中,然后我被卡住了。 即使微软的公共符号服务器也没有帮助,因为它只提供debugging信息,而不是DLL本身。

我目前的解决scheme是向客户询问他的DLL,但这并不容易。 所以我正在寻找更好的解决scheme。

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

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

编辑:

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

有可能放松WinDbg的符号解析; 看到我对类似问题的回答。 另一方面,我在这里提出的解决方案依赖于这样一个事实,即除了具有标识其调试符号的不同GUID之外,这些DLL是相同的 。 一个不同版本的DLL可能会有不同的二进制文件,所以即使你可以加载它们,这些符号可能也不会正确匹配。

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

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

这样它会先搜索我的本地商店,然后再从微软的公共服务器上复制它们。

您的符号路径中可以有多个符号服务器。 因此,简单地设置符号路径以指向您自己的私有模块的服务器,以及OS模块的公共MS服务器,请参阅符号路径 :

这可以通过使用以下初始设置轻松地与Microsoft公共符号存储相结合:

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

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

? 什么部分不工作?

我从来没有遇到过你的情况,但是我希望调试器给你的代码中的调用堆栈的正确部分,直到调用到黑暗的DLL。 当然,从那里到实际的崩溃符号将不可用,但是你不能看到哪个NTDLL API被调用,哪些参数传递给那个调用?

你不会说你正在使用Minidump调试的工具:WinDBG或VS.