WinDbg x64:无法调试故障转储 - 无法加载数据访问 DLL

Posted

技术标签:

【中文标题】WinDbg x64:无法调试故障转储 - 无法加载数据访问 DLL【英文标题】:WinDbg x64: Cannot debug a crash dump - failed to load data access DLL 【发布时间】:2011-10-28 22:33:47 【问题描述】:

我将 WinDbg 附加到一个正在运行的进程并让该进程崩溃(我有一个单独的问题。那个案例)。程序崩溃后,WinDbg 停止并允许我调试程序。我使用“.dump /ma”命令进行了故障转储以进行进一步调查。

程序被编译为“Any CPU”,我使用 WinDbg x64 进行转储。现在我再次在同一台计算机上打开 WinDbg x64 并打开故障转储。它是这样说的:

Loading Dump File [C:\crashdump.dmp]
User Mini Dump File with Full Memory: Only application data is available

Symbol search path is: SRV*c:\symbols*http://msdl.microsoft.com/download/symbols
Executable search path is: 
Windows 7 Version 7601 (Service Pack 1) MP (8 procs) Free x64
Product: WinNt, suite: SingleUserTS
Machine Name:
Debug session time: Mon Aug 15 10:24:57.000 2011 (UTC + 1:00)
System Uptime: 17 days 0:54:39.021
Process Uptime: 12 days 14:01:31.000
................................................................
...............................................................
This dump file has an exception of interest stored in it.
The stored exception information can be accessed via .ecxr.
(1be0.b78): Access violation - code c0000005 (first/second chance not available)
*** WARNING: symbols timestamp is wrong 0x4dd2333e 0x4da4281c for clr.dll
clr!WKS::gc_heap::find_first_object+0x92:
000007fe`ea129a1d f70100000080    test    dword ptr [rcx],80000000h ds:00000000`00003d80=????????

然后我尝试通过“.load sos clr”加载 SOS,但出现错误:

The call to LoadLibrary(sos clr) failed, Win32 error 0n2
    "The system cannot find the file specified."
Please check your debugger configuration and/or network access.

尝试使用“.loadby sos clr”,它可以工作。现在我想用“!clrstack”查看堆栈并坚持在这里:

Failed to load data access DLL, 0x80004005
Verify that 1) you have a recent build of the debugger (6.2.14 or newer)
            2) the file mscordacwks.dll that matches your version of clr.dll is 
                in the version directory
            3) or, if you are debugging a dump file, verify that the file 
                mscordacwks_<arch>_<arch>_<version>.dll is on your symbol path.
            4) you are debugging on the same architecture as the dump file.
                For example, an IA64 dump file must be debugged on an IA64
                machine.

You can also run the debugger command .cordll to control the debugger's
load of mscordacwks.dll.  .cordll -ve -u -l will do a verbose reload.
If that succeeds, the SOS command should work on retry.

If you are debugging a minidump, you need to make sure that your executable
path is pointing to clr.dll as well.

我试过“.symfix”和“.reload”:

0:027> .symfix
0:027> .reload
..................*** WARNING: symbols timestamp is wrong 0x4dd2333e 0x4da4281c for clr.dll
..............................................
...............................................................

卡住了。同时当进程在WinDgb下运行时我可以暂停执行,加载SOS 并成功执行“!clrstack”命令。

有什么想法吗? 谢谢。

更新 - 按照第二个答案中提供的步骤操作,仍然无法正常工作。

1) 我的符号路径:SRV*c:\symbols*http://msdl.microsoft.com/download/symbols;srv*

2) CLR 加载:4.0.30319.237

0:027> lm v clr
Unknown option 'r'
start             end                 module name
00000000`77b60000 00000000`77d09000   ntdll      (pdb symbols)          c:\symbols\ntdll.pdb\6192BFDB9F04442995FFCB0BE95172E12\ntdll.pdb
    Loaded symbol image file: ntdll.dll
    Image path: C:\Windows\System32\ntdll.dll
    Image name: ntdll.dll
    Timestamp:        Sat Nov 20 13:11:21 2010 (4CE7C8F9)
    CheckSum:         001B55EA
    ImageSize:        001A9000
    File version:     6.1.7601.17514
    Product version:  6.1.7601.17514
    File flags:       0 (Mask 3F)
    File OS:          40004 NT Win32
    File type:        2.0 Dll
    File date:        00000000.00000000
    Translations:     0409.04b0
    CompanyName:      Microsoft Corporation
    ProductName:      Microsoft® Windows® Operating System
    InternalName:     ntdll.dll
    OriginalFilename: ntdll.dll
    ProductVersion:   6.1.7601.17514
    FileVersion:      6.1.7601.17514 (win7sp1_rtm.101119-1850)
    FileDescription:  NT Layer DLL
    LegalCopyright:   © Microsoft Corporation. All rights reserved.
000007fe`e9fb0000 000007fe`ea915000   clr      # (pdb symbols)          c:\symbols\clr.pdb\1A7EA01DA29549DAB2B0BD012A6C5BA12\clr.pdb
    Loaded symbol image file: clr.dll
    Image path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
    Image name: clr.dll
    Timestamp:        Tue May 17 09:35:10 2011 (4DD2333E)
    CheckSum:         00967144
    ImageSize:        00965000
    File version:     4.0.30319.237
    Product version:  4.0.30319.237
    File flags:       8 (Mask 3F) Private
    File OS:          4 Unknown Win32
    File type:        2.0 Dll
    File date:        00000000.00000000
    Translations:     0409.04b0
    CompanyName:      Microsoft Corporation
    ProductName:      Microsoft® .NET Framework
    InternalName:     clr.dll
    OriginalFilename: clr.dll
    ProductVersion:   4.0.30319.235
    FileVersion:      4.0.30319.235 (RTMGDR.030319-2300)
    PrivateBuild:     DDBLD240
    FileDescription:  Microsoft .NET Runtime Common Language Runtime - WorkStation
    LegalCopyright:   © Microsoft Corporation.  All rights reserved.
    Comments:         Flavor=Retail

3) “C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscordacwks.dll”的版本为 4.0.30319。239

4) 我发现当我将转储加载到 WinDbg 时,它会从网络加载正确的“mscordacwks.dll”,因此在文件夹“C:\symbols\mscordacwks_AMD64_AMD64_4.0.30319.237.dll\4DD2333E965000”中我有文件“mscordacwks_AMD64_AMD64_4.0.30319.237.dll”。

5)

0:027> .cordll -ve -u -l
CLR DLL status: No load attempts

6)

0:027> !sym noisy
noisy mode - symbol prompts on
0:027> .restart

Loading Dump File [C:\crashdump.dmp]
User Mini Dump File with Full Memory: Only application data is available

DBGHELP: Symbol Search Path: srv*;srv*c:\symbols*http://msdl.microsoft.com/download/symbols
DBGHELP: Symbol Search Path: cache*;SRV*http://msdl.microsoft.com/download/symbols;srv*c:\symbols*http://msdl.microsoft.com/download/symbols
DBGHELP: Symbol Search Path: cache*;SRV*http://msdl.microsoft.com/download/symbols;srv*c:\symbols*http://msdl.microsoft.com/download/symbols
Symbol search path is: srv*;SRV*c:\symbols*http://msdl.microsoft.com/download/symbols
Executable search path is: 
Windows 7 Version 7601 (Service Pack 1) MP (8 procs) Free x64
Product: WinNt, suite: SingleUserTS
Machine Name:
Debug session time: Mon Aug 15 10:24:57.000 2011 (UTC + 1:00)
System Uptime: 17 days 0:54:39.021
Process Uptime: 12 days 14:01:31.000
................................................................
...............................................................
DBGHELP: ntdll - public symbols  
         C:\Program Files\Debugging Tools for Windows (x64)\sym\ntdll.pdb\6192BFDB9F04442995FFCB0BE95172E12\ntdll.pdb
DBGHELP: Symbol Search Path: cache*;SRV*http://msdl.microsoft.com/download/symbols;srv*c:\symbols*http://msdl.microsoft.com/download/symbols
DBGHELP: Symbol Search Path: cache*;SRV*http://msdl.microsoft.com/download/symbols;srv*c:\symbols*http://msdl.microsoft.com/download/symbols
This dump file has an exception of interest stored in it.
The stored exception information can be accessed via .ecxr.
(1be0.b78): Access violation - code c0000005 (first/second chance not available)
*** WARNING: symbols timestamp is wrong 0x4dd2333e 0x4da4281c for clr.dll
DBGHELP: clr - public symbols  
         C:\Program Files\Debugging Tools for Windows (x64)\sym\clr.pdb\1A7EA01DA29549DAB2B0BD012A6C5BA12\clr.pdb
clr!WKS::gc_heap::find_first_object+0x92:
000007fe`ea129a1d f70100000080    test    dword ptr [rcx],80000000h ds:00000000`00003d80=????????

7)

0:027> !clrstack
SYMSRV:  C:\Program Files\Debugging Tools for Windows (x64)\sym\mscordacwks_AMD64_AMD64_4.0.30319.237.dll\4DD2333E965000\mscordacwks_AMD64_AMD64_4.0.30319.237.dll not found
SYMSRV:  mscordacwks_AMD64_AMD64_4.0.30319.237.dll from http://msdl.microsoft.com/download/symbols: 502892 bytes - copied         
DBGHELP: C:\Program Files\Debugging Tools for Windows (x64)\sym\mscordacwks_AMD64_AMD64_4.0.30319.237.dll\4DD2333E965000\mscordacwks_AMD64_AMD64_4.0.30319.237.dll cached to C:\Program Files\Debugging Tools for Windows (x64)\sym\mscordacwks_AMD64_AMD64_4.0.30319.237.dll\4DD233F317b000\mscordacwks_AMD64_AMD64_4.0.30319.237.dll
DBGHELP: C:\Program Files\Debugging Tools for Windows (x64)\sym\mscordacwks_AMD64_AMD64_4.0.30319.237.dll\4DD233F317b000\mscordacwks_AMD64_AMD64_4.0.30319.237.dll - OK
Failed to load data access DLL, 0x80004005
Verify that 1) you have a recent build of the debugger (6.2.14 or newer)
            2) the file mscordacwks.dll that matches your version of clr.dll is 
                in the version directory
            3) or, if you are debugging a dump file, verify that the file 
                mscordacwks_<arch>_<arch>_<version>.dll is on your symbol path.
            4) you are debugging on the same architecture as the dump file.
                For example, an IA64 dump file must be debugged on an IA64
                machine.

You can also run the debugger command .cordll to control the debugger's
load of mscordacwks.dll.  .cordll -ve -u -l will do a verbose reload.
If that succeeds, the SOS command should work on retry.

If you are debugging a minidump, you need to make sure that your executable
path is pointing to clr.dll as well.

【问题讨论】:

【参考方案1】:

在使用站点上的小型转储进行调试时,我经常遇到此问题。我不确定你的情况是如何发生的。通常,当进行转储时加载的 CLR 版本在您的调试机器上不可用时,就会发生这种情况。在你的情况下,它们是同一台机器,所以它应该都可以正常工作。我相信会有其他人可以确切地解释为什么不是。

与此同时,这就是我对网站转储所做的事情。 Windbg 正在寻找 mscordacwks.dll 的“正确版本”。所以我们给它那个版本并告诉它去哪里寻找它。

首先 - 如果我通过删除 mscordacwks.dll 来欺骗所有这些,windbg 会关闭并从 Microsoft 符号服务器加载它,因此请确保正确设置您的符号以从 Microsoft 符号服务器下载符号并给出再来一次。

现在 - 假设这不起作用,请准确检查哪个版本是“正确的版本”。使用“lm v clr”列出模块信息并检查实际加载的 CLR 版本。我的是 4.0.30319.239。好的 - 现在找到那个版本的 mscordacwks.dll。假设它可以在您机器上的正常 .NET 框架安装中找到 (C:\Windows\Microsoft.NET\Framework64\v4.0.30319)。请检查版本是否完全匹配(右键单击、属性等)!把它放在一个安全的地方(我使用 D:\Symbols\_Images)。按照 windbg 为您提供的重命名文件的说明进行操作。 mscordacwks_.dll 将是 mscordacwks_AMD64_AMD64_4.0.30319.239.dll。

现在设置您的可执行映像路径(“.exepath D:\Symbols\_Images”),以便 windbg 知道您将它放在哪里。

您现在已经获得了“正确版本的 mscordacwks”,并对其进行了重命名,以便 Windbg 知道它在寻找什么,并告诉它您将它放在哪里。

如果仍然无法正常工作,请尝试“.cordll -ve -u -l”和“!sym noise”以打开cordll 加载和符号服务器的详细日志记录,然后再次尝试!CLRStack .也许这两个命令的输出会告诉你它正在尝试加载的确切内容,并且你可以弄清楚为什么它不会这样做......

【讨论】:

按照您描述的步骤操作,仍然无法正常工作,请参阅更新后的问题。 没有立即的想法,除了想知道为什么加载的 CLR(可能来自正常的 .NET 安装)是 237,而加载的 mscordacwks.dll(可能来自同一个地方)是 239。我会考虑的。我想到了这个页面:Doug Stewart's version history of CLR 调试器说 clr.dll 的符号文件中的时间戳不匹配(但您使用的是微软的符号服务器)。此外,您在本地拥有 clr.dll 的 237 版本,在本地拥有 239 版本的 mscordacwks.dll(即使调试器的“正确”版本正常)。我想知道重新安装 .NET 4.0.20319.239 的更新(如 Doug 的博客文章中的链接)可能会使一切按预期工作。当然,除非您出于其他原因使用微软的“特殊”补丁。 或者你甚至被恶意软件攻击了——你的 clr.dll 与微软的符号不匹配,它确实应该匹配,所以所有的赌注都被取消了。使用一些受人尊敬的反恶意软件进行快速扫描不会有任何伤害! Doug Stewart 刚刚添加了 this post,它还链接到 this post,它还有许多其他链接可供试用 - 您可以快速浏览一下。【参考方案2】:

我刚刚花了一天时间调试我们遇到这种情况的一堆案例。与崩溃同框的 SOS+CLR 无法在 WinDbg 中加载,并且“lm v”报告了同一模块的两个不同版本:

0:011> lm vM *clr.dll
开始结束模块名称
000007fe`f2f50000 000007fe`f38b0000 clr #(pdb 符号)c:\symbols\clr.pdb\EDFF900AC9B94C1D9B32696A7759891A2\clr.pdb
    加载的符号图像文件:clr.dll
    图片路径:C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
    图片名称:clr.dll
    时间戳:2013 年 4 月 21 日星期日 03:36:04 (5173C114)
    校验和:0095F379
    图片尺寸:00960000
    文件版本:4.0.30319.18052
    产品版本:4.0.30319.18052
    文件标志:8(掩码 3F)私人
    文件操作系统:4 未知 Win32
    文件类型:2.0 DLL
    文件日期:00000000.00000000
    翻译:0409.04b0
    公司名称:微软公司
    产品名称:Microsoft® .NE​​T Framework
    内部名称:clr.dll
    原始文件名:clr.dll
    产品版本:4.0.30319.18047
    文件版本:4.0.30319.18047 构建者:FX45RTMGDR
    私有构建:DDBLD320
    文件描述:Microsoft .NET 运行时公共语言运行时 - 工作站
    法律版权:© Microsoft Corporation。版权所有。
    评论:风味=零售

支持细节

存储在 minidump 的模块列表流中 MINIDUMP_MODULE 结构中的文件时间戳 (0x5173C114)、校验和 (0x0095F379) 和版本 (4.0.30319.18052) 用于较新的 CLR。自己破解打开minidump文件,直接看流数据:

MINIDUMP_MODULE : (pack:8 size:112)
  +0x000 .BaseOfImage UInt64 : 8791579230208 (0x7FEF2F50000)
  +0x008 .SizeOfImage UInt32 : 9830400 (0x960000)
  +0x00C .CheckSum UInt32 : 9827193 (0x95F379)
  +0x010 .TimeDateStamp UInt32 : 1366540564 (0x5173C114)
  +0x014 .ModuleNameRva UInt32:107828 (0x1A534)
  +0x018 .VersionInfo tagVS_FIXEDFILEINFO : (pack:8 size:52)
    +0x000 .dwSignature UInt32 : 4277077181 (0xFEEF04BD)
    +0x004 .dwStrucVersion UInt32:65536 (0x10000)
    +0x008 .dwFileVersionMS UInt32 : 262144 (0x40000)
    +0x00C .dwFileVersionLS UInt32 : 1987004036 (0x766F4684)

从 dwFileVersionMS 中分离出高位和低位字,我们得到 4 和 0。 从 dwFileVersionLS 中拆分出高位和低位字,我们得到 30319 和 18052。

使用dumpchk.exe,并查看 PEB 中的模块详细信息,我们可以看到不同的时间戳 (0x515530CE),实际上对应于旧 (18047) 版本:

7fef2f50000 515530ce 2013 年 3 月 28 日 23:12:30 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll

查看加载了 clr.dll 的故障转储中的原始内存,可以看到 4.0.30319.18047 版本的 Checksum (0x00965F80) 和 Timestamp (0x515530CE):

0:011> db 000007fe`f2f50000
000007fe`f2f50000 4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00 MZ.......
000007fe`f2f50010 b8 00 00 00 00 00 00 00-40 00 00 00 00 00 00 00 ........@.......
000007fe`f2f50020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ...
000007fe`f2f50030 00 00 00 00 00 00 00 00-00 00 00 00 18 01 00 00 ......
000007fe`f2f50040 0e 1f ba 0e 00 b4 09 cd-21 b8 01 4c cd 21 54 68 ........!..L.!Th
000007fe`f2f50050 69 73 20 70 72 6f 67 72-61 6d 20 63 61 6e 6e 6f 是程序 canno
000007fe`f2f50060 74 20 62 65 20 72 75 6e-20 69 6e 20 44 4f 53 20 t 在 DOS 下运行
000007fe`f2f50070 6d 6f 64 65 2e 0d 0d 0a-24 00 00 00 00 00 00 00 模式......$......
0:011> 分贝
000007fe`f2f50080 39 e4 28 ed 7d 85 46 be-7d 85 46 be 7d 85 46 be 9.(..F..F..F.
000007fe`f2f50090 81 f2 f8 be 79 85 46 be-81 f2 fa be 74 85 46 be ....y.F.....t.F.
000007fe`f2f500a0 74 fd c5 是 73 85 46 be-74 fd c2 是 c9 85 46 是 t...s.F.t....F.
000007fe`f2f500b0 ee 41 8d 是 7f 85 46 是-e3 25 81 是 7c 85 46 是 .A....F..%..|.F.
000007fe`f2f500c0 ee 41 88 是 6b 85 46 be-ee 41 89 是 78 85 46 是 .A..k.F..A..x.F.
000007fe`f2f500d0 ee 41 8b 是 64 85 46 be-7d 85 47 是 ca 87 46 是 .A..d.F..G...F.
000007fe`f2f500e0 81 f2 ff 为 76 85 46 be-ee 41 9e 为 70 87 46 为 ....v.F..A..p.F.
000007fe`f2f500f0 ee 41 8c 是 7c 85 46 be-ee 41 8f 是 7c 85 46 是 .A..|.F..A..|.F.
0:011>
000007fe`f2f50100 ee 41 8a 是 7c 85 46 be-52 69 63 68 7d 85 46 是 .A..|.F.Rich.F.
000007fe`f2f50110 00 00 00 00 00 00 00 00-50 45 00 00 64 86 06 00 ....PE..d ...
000007fe`f2f50120 ce 30 55 51 00 00 00 00-00 00 00 00 f0 00 22 20 .0UQ...."
000007fe`f2f50130 0b 02 0b 00 00 90 69 00-00 c2 2b 00 00 00 00 00 ......我...... +......
000007fe`f2f50140 40 51 13 00 00 10 00 00-00 00 f5 f2 fe 07 00 00 @Q.......
000007fe`f2f50150 00 10 00 00 00 02 00 00-06 00 00 00 0a 00 00 00 ......
000007fe`f2f50160 06 00 00 00 00 00 00 00-00 e0 95 00 00 04 00 00 ......
000007fe`f2f50170 80 5f 96 00 02 00 60 01-00 00 10 00 00 00 00 00 ._....`.... 

我也在内存中往前跳,查看了内存中的Version资源,看到了18047版本字符串。

所以现在我们有了一个小型转储,其中包含关于实际使用的 clr.dll 版本的相互冲突的信息。

是什么原因造成的

我还发现我们的 IT 部门最近推出了一些 Windows 更新,所以:

在运行应用程序时,安装了 CLR 更新。 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ 中的文件已更新到较新的版本 (4.0.30319.18052) 应用程序崩溃 MiniDumpWriteDump 显然在将模块列表存储在故障转储文件 (4.0.30319.18052) 中时使用了磁盘上的文件信息 WinDbg 无法将故障转储中标记的版本与进程内存中的内容相关联,因为它有冲突的信息。

为了验证这一点,我手动修改了 clr.dll 的 MINIDUMP_MODULE 条目,将校验和、时间戳和版本从 18052 更改为 18047。在 WinDbg 中重新加载破解的 .dmp 文件并将 exepath 设置为正确的 sos+ clr dlls,我能够成功执行 sos 命令并获得有效的堆栈跟踪。

底线

我们最终得到了一个 minidump 文件,其中包含有关加载到进程中的 clr.dll 版本的信息冲突,从而阻止 SOS 识别正确的 clr 引擎。 这可能是 MiniDumpWriteDump 中的一个错误,因为它保存了故障转储文件。但只有在您的应用程序运行时更新了 CLR 的支持版本时才会发生。

【讨论】:

【参考方案3】:

听起来您对 windbg 进行了自定义安装,但没有选择您需要的所有扩展。 Win32 错误 n2 通常是这个问题的征兆。

【讨论】:

我刚刚检查并安装了所有组件。此外,当我将 WinDbg 附加到正在运行的进程然后让程序崩溃时,一切正常,这也意味着我认为所有组件都在那里。【参考方案4】:

您尝试调试的进程是 32 位的吗?任务管理器进程列表说明了什么?如果是 32 位进程,则需要使用 32 位的 windbg。 否则,我不明白为什么 .load sos clr 会失败。

ps:(windbg noob alert),所以如果这听起来很蹩脚,我深表歉意。只是想帮忙。

【讨论】:

该进程是为任何 CPU 编译的,它是一个 64 位进程。 它是 .loadby 或 .load ,但绝不是 .load sos clr.

以上是关于WinDbg x64:无法调试故障转储 - 无法加载数据访问 DLL的主要内容,如果未能解决你的问题,请参考以下文章

无法在 WinDbg 中加载 SOS

无法在 centos7 上设置故障转储以调试内核

windbg 怎么调试dmp文件

WinDbg 加载符号需要很长时间;正在搜索大型网络 UNC 符号存储中的每个目录

如何使用WinDbg调试进程信息

查找适当的调试符号