Windbg是Microsoft在windows平台下,強大的用戶態和內核態調試工具。我們經常用它來分析DUMP文件,來解決線上服務器的疑難問題,比如CPU升高,內存溢出,響應時間慢等問題。
下面介紹下Windbg 的使用和常用命令
從MSDN下載 Debugging Tools for Windows
下載地址:http://www.microsoft.com/en-us/download/details.aspx?id=8279 里面包函了Windows 的軟件開發工具包,注意選擇系統的版本。
如果你只想下載Debugging Tools for Windows, 在安裝過程中, 選擇 Debugging Tools for Windows 勾選框,清除其他勾選框。
配置Windbg
打開運行Windbg Windows Kits\8.1\Debuggers\x64\windbg.exe
從工具欄選擇File>Symbol File path
設置Symbol File (.pdb 文件)路徑 SRV*c:\mysymbol* http://msdl.microsoft.com/download/symbols 調試的時候會從微軟網站上下載符號,並存放在c:\mysymbol目錄中
如果有其它符路徑用分號隔開,如 ;c:\pdb
抓取DUMP文件
如何抓取將在另一篇文章中說明。
從工具欄選擇File>Open Crash Dump 打開抓取的.DUMP 文件
加載DUMP后,調試屏幕會出現當前DUMP 的一些信息
加載調試擴展SOS
用Windbg 調試托管程序,需要加載SOS 調試擴展 (SOS.dll) 。
在windbg.exe的同級目錄已經自帶了SOS.dll 。但如果這個版本和服務器運行的Framework版本不一致,可以從系統目錄C:\Windows\Microsoft.NET中找到匹配的SOS版本。
我用的64 位 Framework4.0 ,所以從下面目錄中找到
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SOS.dll
在windbg.exe的同級目錄還有一個Psscor4目錄,里面包函了另一個擴展psscor4.dll。psscor 是對SOS 的升級,加載psscor4也是一樣的。
加載命令如下:
.load 目錄名/psscor4.dll
.load 目錄名/SOS.dll
!help 查看命令列表
如何分析
人個觀點:分析線上問題的第一步,是先從監控軟件中(比如zabbix,性能計數器)和系統日志獲取信息。觀察CPU使用率,CPU LOAD,內存,網絡連接數,線程數,響應時間等各種性能指數。
線上的各種性能指數的變化,都有其內在的聯系。比如,內存上漲過快同時也會導致CPU 升高。CPU升高,導致服務器性能下降,響應時間慢,網絡連接數上升。
通過觀察各種指標,然后再定位具體問題。明確了問題方向后,再通過Windbg 分析Dump驗證和查找問題的根源。
常用命令
命令很多,把從網上了解到的和用過的一些命令做一次整理,MSDN 對SOS調試命令的說明: http://msdn.microsoft.com/zh-cn/library/bb190764.aspx
基礎命令:
.load Psscor4/amd64/amd64/psscor4.dll 加載psscor4
.load SOS/SOS.dll
.sympath 設置符號路徑
.cls 清屏
version 查看版本信息
lm 列出加載模塊
!help 顯示命令幫助
!help EEHeap 顯示EEHeap命令幫助
!EEVersion 顯示公共語言運行時版本
內存狀態:
!EEHeap -GC 顯示托管堆統計信息
!EEHeap -loader 顯示加載程序數據結構統計信息
!DumpHeap -stat 顯示垃托管堆各類型統計信息
!DumpHeap -type Free -stat 顯示所有碎片類型統計信息
!DumpHeap -type System.String -min 150 -max 200 顯示所有System.String類型 -min -max 字節統計信息
!DumpHeap -min 85000 -stat 顯示大對象統計信息
!DumpHeap -mt 選項僅列出與指定的 MethodTable 結構對應的那些對象
!DumpHeap -mt 00000000022245b0 -min 85000 查看MT 00000000022245b0中大對象
!DumpHeap -stat 023e1000 033db630 按地址統計
!DumpArray 顯示數組對象
!DumpObj (!do) 顯示有關指定地址處的對象的信息
!ObjSize 顯示指定對象的大小
!DumpStackObjects (!dso) 顯示在當前線程內找到的所有托管對象
!GCRoot 顯示有關對指定地址處的對象的引用(或根)的信息。
!CLRUsage 顯示托管堆統計信息(GC堆大小,提交內存,虛擬內存),psscor4的擴展命令
!DumpMT 顯示有關指定地址處的方法表的信息。
!DumpMT -MD 顯示有關指定地址處的方法表所有方法的列表。
!address -summary 顯示最大可用區域
!vmstat 最大可用區域是 MAXIMUM 列中的最大值
線程調用:
!ThreadPool 顯示有關托管線程池的信息,包括隊列中工作請求的數目、完成端口線程的數目和計時器的數目
!Threads 顯示進程中的所有托管線程
!Threads -live 選項顯示與活動線程關聯的線程
!Threads -pecial 選項顯示由 CLR 創建的所有特殊線程
!ThreadState 顯示線程的狀態。 value 參數為 Threads 報告輸出中的 State 字段的值。
~54s 轉到54線程
!CLRStack 提供當前托管代碼的堆棧跟蹤。
!CLRStack -p 選項顯示托管函數的參數。
!CLRStack -l 選項顯示有關幀中的局部變量的信息。
!DumpStack 顯示堆棧跟蹤 包括非托管。
!DumpStack -EE 命令僅顯示托管函數。
!EEStack 對一個進程中的所有線程運行 DumpStack 命令。
k 顯示當前線程的call stack
kb 顯示當前線程的call stack
~*kb 顯示所有線程的call stack 可以 尋找線程中觸發GC的函數(mscorwks!SVR::GCHeap::GarbageCollectGeneration)
!ASPXPages 顯示當前處理的HttpContext,psscor4的擴展命令
!SyncBlk 顯示同步塊
其它:
!runaway 顯示線程cpu時間
vertarget 查看系統運行時間
!PrintException (!pe) 顯示在當前線程上引發的最后一個異常
!address 命令顯示某一地址上的頁信息
!SaveModule 將加載到內存中指定地址的圖像寫入指定文件,lm 列出的
!SaveModule 081f0000 d:\\commandobject.dll
!FinalizeQueue 顯示所有已進行終結注冊的對象。
!GCHandles 顯示有關進程中的垃圾回收器句柄的統計信息。
S 可以搜索內存 在內存中搜索sina.com: s –u 0012ff40 L?8000000 “sina.com”
r 顯示寄存器的信息
d 顯示內存地址上的值 使用d命令顯示esp寄存器指向的內存,默認為byte: d esp
用dd命令直接指定054efc14地址,第二個d表示用DWORD格式: dd 054efc14
域,程序集,類
!DumpDomain 枚舉在指定的 AppDomain 對象地址內加載的每個 Assembly 對象。若在調用 DumpDomain 命令時不提供任何參數,則將列出過程中的所有 AppDomain 對象
!DumpAssembly 顯示有關程序集的信息。DumpAssembly 命令將列出多個模塊(如果存在)。
!DumpModule 顯示有關指定地址處的模塊的信息。 可以使用 DumpDomain 或 DumpAssembly 命令檢索模塊的地址
!DumpModule [-mt] 選項顯示模塊中定義的類型和模塊所引用的類型
!FindAppDomain 確定指定地址處的對象的應用程序域
!IP2MD <Code address> 顯示已 JIT 編譯的代碼中指定地址處的 MethodDesc 結構。
!DumpMD <MethodDesc address>
!U <MethodDesc address> | <Code address> 顯示由方法的 MethodDesc 結構指針或方法體內的代碼地址指定的托管方法的反匯編(帶有批注)