Windbg 調試 SOS 版本問題

程序發生了崩潰,我抓了一個mini Dump,Mini dump 有一個優勢就是很是的小。比full dump 要小不少。 php

複製代碼
0:020> .loadby sos clr                       //首先加載sos 0:020> !threads The version of SOS does not match the version of CLR you are debugging. Please load the matching version of SOS for the version of CLR you are debugging. CLR Version: 4.0.30319.1008 SOS Version: 4.0.30319.1022


0:020> .cordll -ve -u -l CLRDLL: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscordacwks.dll:4.0.30319.1022 f:8 doesn't match desired version 4.0.30319.1008 f:8 CLRDLL: Loaded DLL c:\symbols\mscordacwks_AMD64_AMD64_4.0.30319.1008.dll\517A18FF965000\mscordacwks_AMD64_AMD64_4.0.30319.1008.dll CLR DLL status: Loaded DLL c:\symbols\mscordacwks_AMD64_AMD64_4.0.30319.1008.dll\517A18FF965000\mscordacwks_AMD64_AMD64_4.0.30319.1008.dll

還有一種錯誤:


If you are debugging a minidump, you need to make sure that your executable
path is pointing to clr.dll as well.
The version of SOS does not match the version of CLR you are debugging. Please
load the matching version of SOS for the version of CLR you are debugging.
CLR Version: 4.0.30319.1026
SOS Version: 4.0.30319.34209
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 or on the symbol path
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 supported cross platform architecture as 
the dump file. For example, an ARM dump file must be debugged
on an X86 or an ARM machine; an AMD64 dump file must be
debugged on an AMD64 machine. html

複製代碼

 

 

.cordll –ve –u –l (小寫的L ) 這個命令是控制調試和控制CLR的命令,-ve是顯示詳細信息,-u 卸載模塊,-l (小寫的L) 是加載模塊,上面這個命令就是卸載CLR 調試模塊,而後再加載CLR調試模塊,並顯示詳細信息。 windows

這個命令提示個人mscordacwks.dll 版本不對。而後有提示從 C:\symbols 加載了  mscordacwks_<arch>_<arch>_<version>.dll 這個文件。 緩存

我windbg的符號文件路徑的設置是: 數據結構

srv*c:\symbols*http://msdl.microsoft.com/download/symbols

經過windbg的快捷鍵 Ctrl+S 能夠設置符號文件的路徑。 架構

 

雖然看似上面的mscodacwks.dll 加載了,可是運行命令仍是報錯: app

複製代碼
0:033> !clrstack The version of SOS does not match the version of CLR you are debugging. Please load the matching version of SOS for the version of CLR you are debugging. CLR Version: 4.0.30319.1008 SOS Version: 4.0.30319.1022 OS Thread Id: 0x6e54 (33) Child SP IP Call Site 000000000540a968 000007fefaab8e4f [PrestubMethodFrame: 000000000540a968] Unknown MethodDesc (Module 000007ff00a613b0, mdToken 060000aa) 000000000540a9d0 000007ff00b829fd Unknown MethodDesc (Module 000007ff00a613b0, mdToken 06000096)
複製代碼

CLR.dll 是一個原生C++ Win32 Native code 編寫的託管代碼運行時,它是託管代碼的運行環境,它從咱們.net編寫的生成的dll中抽取IL中間代碼和元數據,經過JIT即時編譯來生成內存中的原生native Code. Windbg是一個針對原生Native code 的調試器。那在原生調試器和託管代碼世界之間,咱們須要一座「橋樑」這就是SOS.dll。可是CLR的內部數據結構多是要不斷變化的,這時若是有一個針對調試器的一個抽象層就很是重要,調試器經過一個抽象層來訪問CLR的內部數據結構。mscordacwks.dll  就是這樣一個抽象層 ( Data-Access-Component  (DAC) ),它實現了讓調試器SOS.dll 以比較穩定的接口來訪問CLR內部不斷的數據結構的目的。但CLR和SOS.dll 以及 mscordacwkd.dll 仍是耦合的很是緊密的,以致乎 他們的版本必須一致才能夠正常工做。 cors

 

通常,咱們的機器上安裝好.net 運行時後,都有 clr.dll ,sos.dll 和mscordacwk.dll 三個版本一致的dll。 工具

通常在調試dump文件纔會出現這類不匹配的錯誤。由於若是是調試一個活生生的進程,調試器能自動的從.net Framework的安裝目錄來找到正確的mscordacwks.dll。 網站

能夠嘗試

!sym noisy                                                               //顯示詳細信息

.symfix+ c:\symbols                                              //強制下載symbols

.reload /f;                                                                // Force reloading symbols 強制加載符號文件

.cordll -ve -u –l                                                         //從新加載調試DLL,這是加載DLL,不是符號

 

上面的命令試了後也可能不起做用。

遇到這種問題,你須要到抓取dump文件的機器上,把 mscordacwks.dll   和Sos.dll 拷貝下來,若是是別人傳給你dump,則最好讓他將這3個文件一塊兒拷貝給你。拿到DLL後,確認版本正確後,改成相似一下的名字:

mscordacwks_AMD64_AMD64_4.0.30319.1008.dll

 

AMD64 這個字符串對應的是CPU架構信息,由於AMD公司先作出64位架構,Intel公司雖然也有本身的64位架構,但好像沒有流行開,他仍是沿用了AMD兼容的64位。而這個AMD64的遺留名字就一直使用下來了。

 

文件重命名後,能夠放到windbg的exe目錄下,與windbg.exe 同一個目錄,也能夠放到一個指定的目錄下。

而後運行:

.cordll -u -ve -lp  c:\clr1008    // C盤有個clr1008文件夾,我從那裏加載調試DLL,-lp 指定目錄

.cordll -ve -u –l                           //從默認路徑加載調試DLL。

 

 

若是遇到以下錯誤:

CLR DLL status: ERROR: Unable to load DLL mscordacwks_AMD64_x86_4.0.30319.1008.dll,

或者

CLRDLL: ERROR: DLL C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscordacwks.dll init failure, Win32 error 0n87 CLR DLL status: ERROR: DLL C:\Windows\Microsoft.NET\Framework\ v4.0.30319\mscordacwks.dll init failure, Win32 error 0n87

說明 32位、64位這個搞錯了。

你可能抓了一個32位進程的dump。64位系統上的任務管理器中,32位進程的名字相似:w3wp.exe*32,後面帶一個 *32 字樣,它們是運行在WoW64模式下的。同時你用了一個64位的windbg調試器在嘗試調試這個dump。Dump分析必須3二、64嚴格區分開,64位系統抓64位進程dump,用64位windbg來分析。64位系統抓32位進程dump,用32位windbg來分析。

 

還有 第三種方法,本身去獲取匹配版本的關鍵dll。 Mscordacwk 全名是指Ms-core-Data-Access-Component (DAC) -Work.dll,是sos 訪問clr數據須要的一個核心dll。

用「sos 4.0.30319.1008 」 去網上搜索找到對應的 微軟補丁包:

例如,我找到了這樣一個網站: http://www.mskbfiles.com/sos.dll.php

我要的版本他這裏列出來了:

Sos.dll version 4.0.30319.1008:

  • 2835393 MS13-052: Description of the security update for the .NET Framework 4 on Windows XP, Windows Server 2003, Windows Vista, Windows Server 2008, Windows 7, and Windows Server 2008 R2: July 9, 2013 Q2835393 KB2835393

點擊這個連接進去,找到「下載信息」

下載信息

此更新可從 Microsoft 下載中心下載:

http://www.microsoft.com/zh-cn/download/details.aspx?id=39418, 點擊這個連接去下載補丁文件

 

個人dump文件是運行在X64系統上的,那我就下載了「NDP40-KB2835393-x64.exe」。

下載這個文件,它是一個子解壓的exe文件,能夠用 WinRAR 或 7-Zip 打開,打開後在目錄裏找到 *.msp 結尾的文件,右鍵菜單繼續打開,而後找到 *.cab文件,選中 *.cab 文件,經過右鍵菜單繼續打開,查找裏面的 sos_dll_amd64,mscordacwks_dll_am64,clr_dll_amd64文件,把他們導出到普通文件夾下,從新命名爲 sos.dll,mscordacwks.dll,clr.dll,而後查看版本是否是 4.0.30319.1008。若是不是這個版本繼續在 *cab 裏面找dll,應該是能找到正確的文件版本。                   

我就經過這種方法找到了對應 我須要的三個正確版本的dll文件。把他們放在一個clr1008的文件夾下,而後把clr1008 放與windbg.exe 同一級的目錄下。這樣加載敲命令就方便多了。

 

我已經將文件版本保存好後,我從新加載sos.dll

複製代碼
0:033> .load clr1008\sos.dll 0:033> .chain Extension DLL search Path: D:\Users\Downloads\windbg\WINXP;.... //環境變量的 PATH 值  Extension DLL chain: clr1008\sos.dll: image 4.0.30319.1008, API 1.0.0, built Fri Apr 26 14:21:22 2013 [path: D:\Users \Downloads\windbg\clr1008\sos.dll] C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos: [path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dll] [path: D:\Users \Downloads\windbg\dbghelp.dll] ....
複製代碼

我如今有2個sos.dll, 我須要把默認路徑下的卸載掉

0:033> .unload C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos Unloading C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos extension DLL 0:033> .setdll clr1008\sos.dll

這兩個命令的做用是1)卸載dll,2)設置默認dll。

而後加載調試DLL:

0:020> .cordll -u -ve -lp clr1008 CLRDLL: Loaded DLL clr1008\mscordacwks.dll CLR DLL status: Loaded DLL clr1008\mscordacwks.dll

 

若是沒法正確加載PDB文件,就沒法正確的顯示堆棧Stack信息,問題:

複製代碼
0:024> !clrstack PDB symbol for clr.dll not loaded OS Thread Id: 0x8158 (24) Unable to walk the managed stack. The current thread is likely not a managed thread. You can run !threads to get a list of managed threads in 0:024> kb //stack 信息沒法正確顯示 RetAddr : Args to Child : Call Site 000007fe`f9b1c841 : 00000000`77359b6e ... : clr+0x1fde45 00000000`77359b6e : 00000000`00000000 ... : clr+0x1c841 000007fe`f9cfba57 : 00000000`02340850 ... : ntdll!RtlLookupFunctionTable+0xaa 00000000`02340850 : 00000001`0000001f ...: clr+0x1fba57 0:024> .exepath+ clr1008  //+ 是表示附加 Executable image search path is: clr1008 Expanded Executable image search path is: clr1008 0:024> .reload //必須Reload .............. 0:024> kb //以後的堆棧信息已經能正確顯示了 RetAddr : Args to Child : Call Site 000007fe`f9cfba57 : 00000000`02340850 ... : clr!SVR::gc_heap::mark_object_simple1+0xbd6 000007fe`f9cf9aa9 : 00000000`02340850 ... : clr!SVR::gc_heap::mark_object_simple+0x4d7 000007fe`f9b8cf6e : 00000001`c0e4fbc8 ... : clr!SVR::GCHeap::Promote+0x161 000007fe`f9b8ec95 : 00000000`0475dd90 ... : clr!GcEnumObject+0x37 000007fe`f9b8e585 : ffffffff`00000000 ... : clr!GcInfoDecoder::EnumerateLiveSlots+0x5dd
複製代碼

 

必須保證exepath指向正確的路徑,默認指向的是.net Framework的安裝目錄,但我如今須要的是1008版本的clr.dl路徑,因此須要將exepath 額外加上一個路徑。

If you are debugging a minidump, you need to make sure that your executable
path is pointing to clr.dll as well.

 

在沒有將clr1008目錄下的clr.dll 加載到exepath時,下面的輸出是這樣的:

複製代碼
0:000> !EEVersion 4.0.30319.1022 free Workstation mode SOS Version: 4.0.30319.1022 retail build 0:000> lmv m clr start end module name 000007fe`f77f0000 000007fe`f8155000 clr (pdb symbols) c:\symbols\clr.pdb\14AD6AF3D1B64799A5908CBBBA0E9C482\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: Wed Jan 08 14:28:31 2014 (52CCF00F) CheckSum: 0096784D ImageSize: 00965000 File version: 4.0.30319.1022 Product version: 4.0.30319.1022 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.1022 FileVersion: 4.0.30319.1022 (RTMGDR.030319-1000)
複製代碼

 

在將clr1008目錄下的clr.dll 附加到 exepath後,命令輸出以下:

複製代碼
0:020> lmv m clr start end module name 000007fe`f9b00000 000007fe`fa465000 clr (pdb symbols) c:\symbols\clr.pdb\118B3CCCBA4A4A709B496CFB294BF5162\clr.pdb Loaded symbol image file: clr.dll Mapped memory image file: clr1008\clr.dll Image path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll Image name: clr.dll Timestamp: Fri Apr 26 14:04:47 2013 (517A18FF) CheckSum: 0095CE19 ImageSize: 00965000 File version: 4.0.30319.1008 Product version: 4.0.30319.1008 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.1008 FileVersion: 4.0.30319.1008 (RTMGDR.030319-1000) 
複製代碼

 

能夠看到 pdb 符號文件已經有了,並且有了一個Mapped memory image file: clr1008\clr.dll 這一項。並且個人symbol path下緩存的clr.pdb文件也已經對應到正確的版本了。

 

額外的:

lm 能夠檢查你的.net 程序是否運行在 .net 4或.net 2,仍是混合着 4.0 和 2.0, 就是經過 查看輸出內容是否 包含 clr, mscorwk, mscorsrv 這些模塊,4.0 的核心dll 是clr.dll。2.0 的核心dll是 mscorwks.dll 或者mscorsrv.dll。下面只有clr 模塊,說明只工做在.net 4.0下。

複製代碼
0:000> lm start end module name …… 00000000`77530000 00000000`7764f000 kernel32 (pdb symbols) 00000000`77650000 00000000`7774a000 user32 (pdb symbols) 00000000`77750000 00000000`778f9000 ntdll (export symbols) 000007fe`f24e0000 000007fe`f2653000 clrjit (pdb symbols) 000007fe`f77f0000 000007fe`f8155000 clr  (pdb symbols)
複製代碼

 

 

在這裏補充一點:這篇文章是將windbg如何去正確加載 sos.dll,同時有可能須要去正確加載 clr.dll 這個exe 可執行路徑。若是使用DebugDiag這類自動化工具,由於自動化工具沒有能夠配置去哪一個路徑加載exe可執行路徑。須要在環境變量裏設置這些參數:

_NT_EXECUTABLE_IMAGE_PATH = c:\clr1008

例如我這裏就設置了這樣一個環境變量,讓DebugDiag 啓動分析時,知道去這裏找正確的clr版本。參見:http://msdn.microsoft.com/en-us/library/windows/hardware/hh439335(v=vs.85).aspx

 

 

參考資料:

http://blogs.msdn.com/b/dougste/archive/2009/02/18/failed-to-load-data-access-dll-0x80004005-or-what-is-mscordacwks-dll.aspx

http://stackoverflow.com/questions/23636764/clr-dll-exception-causes-the-iis-crashed

http://stackoverflow.com/questions/7430769/what-to-do-with-the-version-of-sos-does-not-match-the-version-of-clr-you-are-de

http://voneinem-windbg.blogspot.com/2007/10/failed-to-load-data-access-dll.html

http://blogs.msdn.com/b/tess/archive/2008/05/13/failed-to-start-stack-walk-80004005-following-frames-may-be-wrong-and-other-errors-you-may-see-in-windbg.aspx

相關文章
相關標籤/搜索