WinDbg x64:无法调试崩溃转储文件 - 未能加载数据访问 DLL。

21

我将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 中时,它会从 Web 加载正确的 "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.
4个回答

19

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

同时,这是我在站点转储中处理的方式。Windbg正在寻找“正确的版本”mscordacwks.dll。所以我们提供该版本并告诉它在哪里查找。

首先 - 如果我欺骗所有内容,即删除mscordacwks.dll,则windbg将从Microsoft符号服务器加载它,请确保正确设置了符号以从Microsoft符号服务器下载符号,并再次尝试。

现在 - 假设那没用,请检查“正确版本”是哪个版本。使用“lm v clr”列出模块信息并检查实际加载的CLR版本。我的版本是4.0.30319.239。好的 - 现在找到该版本的mscordacwks.dll。假设它可以在您的计算机上的普通.NET Framework安装中找到(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 noisy",以启用cordll加载和符号服务器的详细日志记录,然后再次尝试!CLRStack。也许这两个命令的输出会告诉您它正在尝试加载什么,您可以弄清楚为什么它无法执行...

按照您描述的步骤操作,仍然无法使其正常工作,请查看更新后的问题。 - net_prog
除了想知道为什么从正常的.NET安装中加载的CLR是237,而从同一位置加载的mscordacwks.dll是239之外,我没有其他的想法。我会好好思考一下。我想到了这个页面:Doug Stewart的CLR版本历史记录 - Pete
调试器显示 clr.dll 符号文件中的时间戳不匹配(但您正在使用 Microsoft 的符号服务器)。 此外,您本地有 clr.dll 版本 237 和 mscordacwks.dll 版本 239(尽管调试器正在正确获取“正确”的版本)。 我想知道重新安装 .NET 4.0.20319.239 的更新(如 Doug 博客文章中提供的链接)是否可以使一切按预期工作。 当然,除非您出于其他原因使用了来自 Microsoft 的“特殊”补丁。 - Pete
或许你甚至已经被恶意软件感染了——你的clr.dll与微软的符号不匹配,这真的应该匹配,所以一切都不能确定。使用一些可靠的反恶意软件进行快速扫描绝对不会有任何损失! - Pete
1
Doug Stewart刚刚添加了这篇文章,其中还链接到这篇文章,里面还有很多其他链接可以尝试一下 - 你可以快速浏览一下。 - Pete

13

我刚刚花了一整天时间对一系列遇到这种情况的问题进行调试。在WinDbg中,与崩溃发生在同一台计算机上的SOS+CLR无法加载,且“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
    时间戳:          Sun Apr 21 03:36:04 2013 (5173C114)
    校验和:          0095F379
    映像大小:         00960000
    文件版本:        4.0.30319.18052
    产品版本:        4.0.30319.18052
    文件标志:        8 (掩码3F) 私有的
    文件操作系统:     4 未知Win32
    文件类型:        2.0 Dll
    文件日期:        00000000.00000000
    翻译:           0409.04b0
    公司名称:        Microsoft Corporation
    产品名称:        Microsoft® .NET Framework
    内部名称:        clr.dll
    原始文件名:      clr.dll
    产品版本:        4.0.30319.18047
    文件版本:        4.0.30319.18047 由: FX45RTMGDR构建
    私有生成:        DDBLD320
    文件说明:        Microsoft .NET Runtime公共语言运行时 - 工作站
    版权所有:       © Microsoft Corporation.  保留所有权利。
    注释:            Flavor=Retail

备份细节

MINIDUMP_MODULE结构中存储的文件时间戳(0x5173C114)、校验和(0x0095F379)和版本(4.0.30319.18052)是针对较新的CLR。我自己打开了minidump文件并直接查看流数据:

MINIDUMP_MODULE : (包:8 大小: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:(包:8 大小: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 Mar 28 23:12:30 2013 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll


查看加载了clr.dll的崩溃转储中的原始内存,您可以看到版本4.0.30319.18047的校验和(0x00965F80)和时间戳(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  这是一个无法在DOS模式下运行的程序。
000007fe`f2f50050  69 73 20 70 72 6f 67 72-61 6d 20 63 61 6e 6e 6f  
000007fe`f2f50060  74 20 62 65 20 72 75 6e-20 69 6e 20 44 4f 53 20  
000007fe`f2f50070  6d 6f 64 65 2e 0d 0d 0a-24 00 00 00 00 00 00 00  
0:011> db
000007fe`f2f50080  39 e4 28 ed 7d 85 46 be-7d 85 46 be 7d 85 46 be  这里是16进制的数据,可能是某个程序的内存地址信息。
000007fe`f2f50090  81 f2 f8 be 79 85 46 be-81 f2 fa be 74 85 46 be  
000007fe`f2f500a0  74 fd c5 be 73 85 46 be-74 fd c2 be c9 85 46 be  
000007fe`f2f500b0  ee 41 8d be 7f 85 46 be-e3 25 81 be 7c 85 46 be  
000007fe`f2f500c0  ee 41 88 be 6b 85 46 be-ee 41 89 be 78 85 46 be  
000007fe`f2f500d0  ee 41 8b be 64 85 46 be-7d 85 47 be ca 87 46 be  
000007fe`f2f500e0  81 f2 ff be 76 85 46 be-ee 41 9e be 70 87 46 be  
000007fe`f2f500f0  ee 41 8c be 7c 85 46 be-ee 41 8f be 7c 85 46 be  
0:011> 
000007fe`f2f50100  ee 41 8a be 7c 85 46 be-52 69 63 68 7d 85 46 be  
000007fe`f2f50110  00 00 00 00 00 00 00 00-50 45 00 00 64 86 06 00  这里包含了PE文件的头信息。
000007fe`f2f50120  ce 30 55 51 00 00 00 00-00 00 00 00 f0 00 22 20  这个部分可能是某种加密算法生成的十六进制数据。
000007fe`f2f50130  0b 02 0b 00 00 90 69 00-00 c2 2b 00 00 00 00 00  
000007fe`f2f50140  40 51 13
我还跳到内存中查看了版本资源,并看到了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条目,将Checksum、Timestamp和Version从18052改为18047。在WinDbg中重新加载被黑客攻击的.dmp文件,并将exepath设置为适当的sos+clr dlls后,我能够成功执行sos命令并获得有效的堆栈跟踪。
底线是,我们最终得到了一个minidump文件,其中关于加载到进程中的clr.dll版本存在冲突的信息,阻止SOS识别正确的clr引擎。 这很可能是MiniDumpWriteDump保存崩溃转储文件时的一个错误。但只会在您的应用程序运行时备份的CLR版本已更新时发生。

0

看起来您进行了自定义安装windbg,并没有选择所有所需的扩展。Win32错误n2通常是此问题的迹象。


我刚刚检查了,所有组件都已安装。而且当我将WinDbg附加到正在运行的进程上,然后程序崩溃时一切都正常工作,这也意味着所有组件都已经存在。 - net_prog

0

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

附言:(windbg小白警告),所以如果听起来很弱,我道歉。只是想帮忙。


该进程是为任意 CPU 编译的,是一个 64 位进程。 - net_prog
它可以是.loadby <plugin> <module>或.load <plugin_full_path>,但永远不是.load sos clr。 - Thomas Weller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接