SOS.DLL、SOSEX.DLL這兩個就是用來對.NET程序在Windows調試工具中起到翻譯作用的調試器擴展。簡單講就是,這兩個組件是.NET項目組專門開發(fā)出來用來對.NET應用程序進行方便調試用的,當然不用這兩個擴展也能調試.NET程序,只不過就會很困難,會被很多細節(jié)束縛住。有了這個調試擴展之后,我們就可以讓原生Windows調試器正確的翻譯出.NET相關概念。
圖1:(Windows調試工具執(zhí)行流程)
所有對.NET程序發(fā)起的調試會話都要經過.NET調試擴展組件進行翻譯才行,也就是要使用.NET調試擴展的調試命令來調試.NET程序。上圖中,我們如果要想調試.NET程序就需要將.NET調試擴展組件加載到Windows調試工具中去,然后才能方便在Windows調試工具中使用。
.NET調試擴展包,SOS.DLL、SOSEX.DLL:
.NET調試擴展包分為兩個,一個是SOS.DLL,該擴展包是.NET平臺的一部分,屬于官方版本。而SOSEX.DLL是微軟的一名叫“Steve Johnson”軟件工程師開發(fā),屬于個人維護的,用來增強SOS.DLL功能的,在SOSEX.DLL有很多功能比較強大的擴展命令。
具體的幫助文檔可以查看該工程師的博客來了解詳情。這兩個版本用來調試不同環(huán)境的程序的,如果你的程序是運行在32位環(huán)境下,就用32位的SOSEX,同理,用在64位下就用64位SOSEX。
而SOS.DLL擴展包是跟著.NETFramework一起安裝的,地址位于:C:\Windows\Microsoft.NET\Framework\v4.0.30319。如果你是64位系統(tǒng)的話地址就是:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319。在這兩個地址下面都可以找到SOS.dll文件,不同的目錄下對應于調試不同機器類型的.NET程序。
有了這兩個擴展包之后就可以在WinDbg中對.NET程序進行分析了,具體使用我們后面會介紹。
2.3.調試系統(tǒng)的基本流程及架構(.NETDAC概念、mscordacwks.dll)
有一個很重要的原理我覺得很有必要講一下,就是.NETDAC概念。
其實.NETDAC也就是.NET Data Access .NET數(shù)據(jù)訪問層,這個是專門用來提供給SOS.DLL\SOSEXDLL或者其他調試擴展包使用的,所有的調試擴展組件必須通過這個DAC才能訪問到.NET運行時的數(shù)據(jù),所以在初次使用SOS的時候會經常碰見加載錯誤的mscordacwks.dll文件,此文件就是DAC的物理文件。
這個文件和SOS擴展文件一樣,都有這不同的版本,當加載不同類型的.NET程序時會使用到不同版本的mscordacwks.dll文件,當然大部分情況下此文件時自動加載的,只有出現(xiàn)你分析的文件與生成調試文件的環(huán)境不一致時才會出現(xiàn)頭疼的問題。
圖5:(mscordacwks.dll位置)
當你知道這個組件是工作于此位置時,當出現(xiàn)跟它相關的錯誤提示時你就不需要擔心了,無非就是文件加載的位置或者版本不匹配而已。
VisualStudio中集成擴展調試:
SOS擴展也是可以和VisualStudio進行集成的,這樣真的方便了我們調試一些性能要求比較高的程序,當程序運行一段時間后我們用VS附加到進程,然后查看一些重要的對象數(shù)據(jù),但是此時我們看不到.NET運行時的一些數(shù)據(jù),比如:對象的代齡,托管堆的大小,線程池的任務等。通過集成SOS擴展會讓我們對程序的運行時有了一個更加方便的跟蹤。
圖10:(打開本地代碼調試)
設置斷點,然后在”即時窗口“(調試->窗口->即時)中加載擴展SOS.DLL。
圖11:(在VisualStudio2012中加載SOS.dll擴展)
這樣的便利性大大提高我們在調試程序內存方面、線程方面的好處,我們可以適當?shù)淖鰤毫y試,然后Attach process,執(zhí)行SOS擴展命名來查看內存問題,當需要調試程序邏輯時在單步調式C#代碼,一舉兩得。
加載.NET程序擴展調試包(SOS.DLL、SOSEX.DLL)
對.NET程序分析當然是需要加載SOS擴展了。加載SOS擴展有兩個命令可以使用,第一個是.load C:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll,.load命令是要給出sos.dll絕對路徑的。第二個是.loadby sos modulename,.loadby 命令是可以根據(jù)已經加載的模塊名稱來加載SOS.dll擴展。使用第一個命令有一個問題就是,我們需要人工的判斷當前環(huán)境到底是需要什么版本的SOS擴展,而使用.loadby是可以根據(jù)已經加載的模塊來自動的查找對應的SOS擴展。
0:000> .load C:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll
0:000> .loadby sos.dll clrjit
使用.loadby 命令很容易的就可以加載SOS擴展,而不需要自己去判斷當前程序是.NET什么版本的。