前言
在使用.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