sos.dll/mscordacwks.dll
公共語言運行庫(CLR)是執行托管代碼的Microsoft.NET框架的核心引擎。簡單地說,它通過在托管程序集中使用中間語言和元數據,JIT按需編譯代碼,構建程序集定義和使用的類型的內存表示,並確保生成的代碼是安全的、安全的和可驗證的,並在需要時執行。這個引擎本身是用本機代碼實現的。當我們想使用本機調試器(如CDB或WinDBG)調試.NET應用程序時(如果我們想使用事后內存轉儲文件調試它,我們目前做了很多工作),我們必須在本機調試器和托管世界之間使用“橋”,因為本機調試器本身並不理解托管代碼。它是本機調試器。
為了提供這個橋,CLR附帶了一個調試擴展名SOS.DLL。這理解CLR的內部結構,因此允許我們執行諸如輸出托管調用堆棧、轉儲托管堆等操作。
但是,這些內部數據結構和CLR的詳細信息會不時發生變化,因此,從使.NET應用程序工作的CLR的實際內部實現中抽象出此調試器擴展所需的CLR接口是非常有用的。輸入mscordacwks.dll。這提供了數據訪問組件(DAC),該組件允許SOS.DLL調試器擴展解釋維護.NET應用程序狀態的內存中數據結構。
如果您在框架文件夾中查看,則應始終看到這些dll的匹配集:
- 32位的
C:\Windows\Microsoft.NET\Framework\v4.0.30319 - 64位的
C:\Windows\Microsoft.NET\Framework64\v4.0.30319
錯誤表現
很多時候當你這樣做的時候你會得到這個錯誤。
- .load sos
0:080> .load sos
The call to LoadLibrary(sos) failed, Win32 error 0n2
This is a different error
"The system cannot find the file specified."
Please check your debugger configuration and/or network access.
You can solve this by doing .loadby sos clr, this means you are trying to load sos.dll from the same location you loaded clr.dll from. - .loadby sos clr
0:091> .loadby sos clr
Unable to find module 'clr'
我問自己的第一個問題是,我是否在用64位調試器調試32位應用程序,如果不是,我要列出所有加載的模塊
在本例中,我看到沒有加載clr.dll,但mscorwks是因為我正在調試的應用程序使用的是.net framework 2.0
0:091> lm
start end module name
00000000`1b6d0000 00000000`1b9cf000 System_Data (deferred)
00000000`1e230000 00000000`1e279000 System_Transactions (deferred)
00000000`714b0000 00000000`71556000 System_Core (deferred)
00000000`77610000 00000000`777b9000 ntdll (private pdb symbols) d:\symbols\ntdll.pdb\15EB43E23B12409C84E3CC7635BAF5A32\ntdll.pdb
00000642`ffaf0000 00000642`ffb09000 mscorsec (deferred)
000007fe`dae40000 000007fe`db68b000 System_Data_ni (deferred)
000007fe`e07b0000 000007fe`e0945000 System_DirectoryServices_ni (deferred)
000007fe`e0950000 000007fe`e0a5d000 System_EnterpriseServices_ni (deferred)
000007fe`e0a60000 000007fe`e0b45000 System_Transactions_ni (deferred)
000007fe`eb380000 000007fe`ec25c000 mscorlib_ni (deferred)
000007fe`ec260000 000007fe`ecbfc000 mscorwks (deferred) - .loadby sos mscorwks
Failed to load data access DLL, 0x80004005
Verify that1) 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.
這些錯誤消息通常是人們在嘗試使用WinDBG/CDB使用SOS調試器擴展調試.NET/CLR應用程序轉儲時遇到的問題,這意味着SOS.DLL調試器擴展無法找到匹配的mscordacwks.DLL,它需要能夠調試您嘗試調試的轉儲文件。如果調試的是實時應用程序,調試器擴展將自動從框架目錄中查找並加載mscordacwks.dll。
如果您正在調試一個轉儲文件,該文件從使用不同版本(例如,不同安裝的服務包或修補程序)的CLR應用程序到本地系統上安裝的應用程序,或者.NET框架安裝在系統上與其安裝位置不同的位置,並且調試器無法通過其他方式找到正確的mscordacwks.dll。因為擁有匹配的mscordacwks.dll對於SOS.dll的正常工作非常重要,所以SOS有很多技巧可以找到它。特別是,如果對符號服務器進行了正確的索引,調試器將從那里加載它。調試器還將在調試器目錄中查找它,前提是它已以特殊方式重命名
怎么解決
大多數情況下,如果已正確設置了符號路徑(無論如何,在調試任何內容時都需要設置該路徑,更不用說托管應用程序),則調試器應能夠自動從符號服務器獲取正確的mscordacwks.dll,執行下面的指令系列:
- !sym noisy
- .symfix 路徑
- .cordll -ve -u -l
如果做了上述工作,還不起作用,我們還可以這樣做:
最簡單的方法是讓給您轉儲文件的人給您mscordacwks.dll的副本。一旦你有了它,檢查它的文件屬性的版本號。應該是2.0.50727.xxxx。然后將其重命名為mscordacwks_AAA_AAA_2.0.50727.xxxx.dll。其中,xxxx是版本號的適當位,AAA是x86還是AMD64,這取決於您處理的是32位還是64位應用程序轉儲。(在我們提到x64之前,AMD64是一個遺留的東西)。然后將這個重命名的副本放入調試器目錄(安裝WinDBG的目錄)。然后,根據錯誤消息,告訴調試器重試:.cordll -ve -u -l
盡管我們試圖確保發布的每個CLR版本(作為服務包、修補程序或其他版本)在公共符號服務器上都有其mscordacwks.dll索引,但不幸的是,有時不會發生這種情況。但由於它總是作為CLR的一部分發布,所以您總是可以選擇從轉儲的機器獲取它。
如果你按上面指示跑了.cordll -ve -u -l收到了這樣的信息:
CLR DLL status: ERROR: Unable to load DLL mscordacwks_AMD64_x86_2.0.50727.3053.dll, Win32 error 0n87
這意味着您很可能使用64位調試器在64位系統上轉儲32位進程(在WoW64下運行),現在您正嘗試使用64位調試器分析轉儲。這就是消息引用AMD64和x86的原因。這是行不通的。因為SOS.DLL擴展實際上在調試需要匹配的位時使用了框架。我強烈建議始終使用與進程相同位的調試器生成轉儲(因此,即使系統是x64系統,也要為WoW64進程生成x86調試器),並使用生成轉儲的調試器的相同位分析轉儲。當然,這意味着您不能在32位系統上調試64位轉儲。這還意味着您必須安裝框架來調試托管應用程序轉儲。
你還可能看到下面的信息輸出:
0:018> .cordll -ve -u -l
CLRDLL: ERROR: DLL C:WindowsMicrosoft.NETFrameworkv2.0.50727mscordacwks.dll init failure, Win32 error 0n87
CLR DLL status: ERROR: DLL C:WindowsMicrosoft.NETFrameworkv2.0.50727mscordacwks.dll init failure, Win32 error 0n87
這也意味着有點混亂。我在使用32位調試器分析使用64位調試器生成的WoW64進程的轉儲時看到了這一點。
