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.dll
、mscorwks.dll
和mscordacwks.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个原因:
- 使用的应用程序和windbg的版本不一样,比如使用的是x64的程序但是却用x86版本的windbg加载进行分析。
- 另一个常见的原因是导出dump的计算机和分析dump文件的计算机的
.net framework
环境不一致。 - 当使用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 stamp
和size of image
拼起来恰好为573D296C9a0000