windbg分析dump-解決mscorwks不匹配

傑哥很忙發表於2020-10-05

前言

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

相關文章