windbg分析dump-解决mscorwks不匹配

前言

在使用.net的生产环境时,有时候我们会碰到程序闪退或内存溢出等异常现象,这时就需要将程序导出dump文件进行分析。有时候服务器的环境和本地环境可能不一致,就会导致分析dump文件时出现异常。

正常情况下我们通过.loadby sos mscorwks加载默认路径下的mscorwks文件。加载成功后就可以同!threads!dumpheap等命令进行具体的分析。若在输入!threads等命令报如下的错误时,需要先解决环境不一致的问题。

0:000> .loadby sos mscorwks
0:000> !threads
PDB symbol for mscorwks.dll not loaded
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 mscorwks.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 mscorwks.dll as well.

在解释该错误之前,我们首先了解一下sos.dllmscorwks.dllmscordacwks.dll是什么。

什么是mscorwks

通用语言运行时 (CLR) 是执行托管代码的 Microsoft .NET 框架的核心引擎。mscorwks.dll是CLR 2.0实现的主要文件。此引擎在本机代码中实现。

什么是SOS

SOS.DLL可以提供关于CLR的信息,帮助我们在vs和windbg调试托管程序。例如,可以显示有关托管堆的信息、查找堆损坏情况、显示运行时使用的内部数据类型以及查看有关运行时内运行的所有托管代码的信息。

什么是mscordacwks

当我们想要使用本机调试器(如 CDB 或 WinDBG)调试 .NET 应用程序(如果我们想要使用事后内存转储文件来调试它,我们经常会执行很多这些操作),我们必须在本机调试器和托管世界之间使用一个"桥"进行连接,因为本机调试器本身并不了解托管代码。mscoradcwks是本机调试器,提供了连接本机和托管代码的“桥”。mscordacwks.dll提供了允许 SOS 的数据访问组件 (DAC),以解释维护 .NET 应用程序状态的内存中数据结构。

综上所述,mscorwks使用本机代码实现了CLR,SOS可以提供托管的CLR信息,而mscordacwks即为连接本机代码和托管代码之间的桥。SOS无需了解CLR底层细节。

上述错误是什么意思?

上面的错误表示SOS.DLL无法找到匹配的 mscordacwks.dll

什么时候会出现该错误

一般出现该错误提示有2个原因:

  1. 使用的应用程序和windbg的版本不一样,比如使用的是x64的程序但是却用x86版本的windbg加载进行分析。
  2. 另一个常见的原因是导出dump的计算机和分析dump文件的计算机的.net framework环境不一致。
  3. 当使用CLR不同版本时,若正确配置了符号文件服务器,则会尝试从符号文件服务器下载需要的mscordacwks.dll文件,若下载不到也会出现该错误。

如何修复错误

通过!sym noisy命令打开消息提醒。

通过.symfix c:mylocalsymcache尝试修复公共符号路径。

最后通过.cordll -ve -u -l显示CLR文件加载的结果。

若报如下的错误,可能是使用的是绿色的windbg或缺少了相关的导致的。

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

正常时会输出sos相关文件的加载信息

2:2:092> .cordll -ve -u -l
CLRDLL: C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscordacwks.dll:2.0.50727.9151 f:0
doesn't match desired version 2.0.50727.8745 f:0
SYMSRV:  BYINDEX: 0x1A
         e:\开发工具\分析工具\symbols
         mscordacwks_AMD64_AMD64_2.0.50727.8745.dll
         573D296C9a0000
SYMSRV:  UNC: e:\开发工具\分析工具\symbols\mscordacwks_AMD64_AMD64_2.0.50727.8745.dll\573D296C9a0000\mscordacwks_AMD64_AMD64_2.0.50727.8745.dll - path not found
SYMSRV:  UNC: e:\开发工具\分析工具\symbols\mscordacwks_AMD64_AMD64_2.0.50727.8745.dll\573D296C9a0000\mscordacwks_AMD64_AMD64_2.0.50727.8745.dl_ - path not found
SYMSRV:  UNC: e:\开发工具\分析工具\symbols\mscordacwks_AMD64_AMD64_2.0.50727.8745.dll\573D296C9a0000\file.ptr - path not found
SYMSRV:  RESULT: 0x80070003
CLRDLL: Unable to find mscordacwks_AMD64_AMD64_2.0.50727.8745.dll by mscorwks search
CLRDLL: Unable to find 'mscordacwks_AMD64_AMD64_2.0.50727.8745.dll' on the path
SYMSRV:  BYINDEX: 0x1B
         e:\开发工具\分析工具\symbols
         mscorwks.dll
         573D296C9a0000
SYMSRV:  UNC: e:\开发工具\分析工具\symbols\mscorwks.dll\573D296C9a0000\mscorwks.dll - path not found
SYMSRV:  UNC: e:\开发工具\分析工具\symbols\mscorwks.dll\573D296C9a0000\mscorwks.dl_ - path not found
SYMSRV:  UNC: e:\开发工具\分析工具\symbols\mscorwks.dll\573D296C9a0000\file.ptr - path not found
SYMSRV:  RESULT: 0x80070003
DBGHELP: C:\WINDOWS\system32\mscorwks.dll - file not found
DBGHELP: C:\WINDOWS\system32\mscorwks.dll - file not found
DBGHELP: C:\WINDOWS\system32\mscorwks.dll - file not found
DBGHELP: mscorwks.dll not found in e:\开发工具\分析工具\symbols
DBGHELP: mscorwks.dll not found in e:\开发工具\分析工具\symbols
DBGHELP: mscorwks.dll not found in e:\开发工具\分析工具\symbols
CLRDLL: Unable to find mscorwks.dll by search
Cannot Automatically load SOS
CLRDLL: ERROR: Unable to load DLL mscordacwks_AMD64_AMD64_2.0.50727.8745.dll, Win32 error 0n2
CLRDLL: Consider using ".cordll -lp <path>" command to specify .NET runtime directory.
CLR DLL status: ERROR: Unable to load DLL mscordacwks_AMD64_AMD64_2.0.50727.8745.dll, Win32 error 0n2

可以发现,我本地的mscorwks的版本为2.0.50727.9151,而dump文件需要的版本是2.0.50727.8745

此时我们可以将操作系统环境的mscorkws按照要求放到相应的目录下,比如把mscordacwks.dll重命名为mscordacwks_AMD64_AMD64_2.0.50727.8745.dll放到mscordacwks_AMD64_AMD64_2.0.50727.8745.dll\573D296C9a0000\目录下。

这时候重新在输入.cordll -ve -u -l就可以正常加载了。

0:000> .cordll -ve -u -l
CLRDLL: Loaded DLL e:\开发工具\分析工具\symbols\mscorwks.dll\573D296C9a0000\mscordacwks.dll
Automatically loaded SOS Extension
CLR DLL status: Loaded DLL e:\开发工具\分析工具\symbols\mscorwks.dll\573D296C9a0000\mscordacwks.dll

符号文件目录规则

可以看到我们的目录和文件名是mscordacwks_AAA_AAA_2.0.50727.xxxx.dll`格式,中间的AAA表示AI64或AMD64,后面的xxxx为dll的修订号。

573D296C9a0000是通过PE文件头计算出的一个值。在vs的develpment 命令行下输入dumpbin /headers 文件路径 可以查看dll文件的pe文件头。

C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise>dumpBIN /headers E:\开发工具\分析工具\Symbols\mscorwks.dll\573D296C9a0000\mscorwks.dll
Microsoft (R) COFF/PE Dumper Version 14.27.29111.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file E:\开发工具\分析工具\Symbols\mscorwks.dll\573D296C9a0000\mscorwks.dll

PE signature found

File Type: DLL

FILE HEADER VALUES
            8664 machine (x64)
               6 number of sections
        573D296C time date stamp Thu May 19 10:48:12 2016

			...

OPTIONAL HEADER VALUES
             
             ...
               0 Win32 version
          9A0000 size of image
             ...

可以发现time date stampsize of image拼起来恰好为573D296C9a0000

相关资料

  1. SOS.dll (SOS debugging extension)

  2. “Failed to load data access DLL, 0x80004005” – OR – What is mscordacwks.dll?

  3. mscordacwks.dll and mscorwks.dll confusions](https://stackoverflow.com/questions/670725/mscordacwks-dll-and-mscorwks-dll-confusions)

posted @ 2020-10-05 10:48  杰哥很忙  阅读(1742)  评论(0编辑  收藏  举报