生產環境偶爾會出現一些異常問題,WinDbg或GDB是解決此類問題的利器。調試工具WinDbg如同醫生的聽診器,是系統生病時作問題診斷的逆向分析工具,Dump文件相似於飛機的黑匣子,記錄着生產環境程序運行的狀態。本文主要介紹了調試工具WinDbg和抓包工具ProcDump的使用,並分享一個真實的案例。N年前不知誰寫的代碼,致使每一兩個月偶爾出現CPU飆高的現象。咱們先使用ProcDump在生產環境中抓取異常進程的Dump文件,而後在不瞭解代碼的狀況下經過WinDbg命令進行分析,最終定位到有問題的那行代碼。git
WinDbg是在Windows平臺下的、強大的用戶態和內核態調試工具。相比較於Visual Studio,它是一個輕量級的調試工具,所謂輕量級指的是它的安裝文件大小較小,可是其調試功能,卻比VS更爲強大。它的另一個用途是能夠用來分析Dump數據。WinDbg是Microsoft公司免費調試器調試集合中的GUI的調試器,支持Source和Assembly兩種模式的調試。WinDbg不只能夠調試應用程序,還能夠進行Kernel Debug。結合Microsoft的Symbol Server,能夠獲取系統符號文件,便於應用程序和內核的調試。WinDbg支持的平臺包括x8六、IA6四、AMD64。雖然WinDbg也提供圖形界面操做,但它最強大的地方仍是有着強大的調試命令,通常狀況會結合GUI和命令行進行操做,經常使用的視圖有:局部變量、全局變量、調用棧、線程、命令、寄存器、白板等。其中「命令」視圖是默認打開的。github
DebugDiag最初是爲了幫助分析IIS的性能問題而開發的,它一樣能夠用於任何其餘的進程。DebugDiag工具主要用於幫助解決如掛起、 速度慢、 內存泄漏或內存碎片,和任何用戶模式進程崩潰等問題。該工具包括附加調試腳本,側重於互聯網信息服務(IIS)應用程序、 Web數據訪問組件、 COM+和相關Microsoft技術、SharePoint和.NET。它提供可擴展對象模型中的COM對象的形式,並具備一個內置的報告框架提供的腳本主機。它由3 部分組成,包括調試服務、 調試器主機和用戶界面。數據庫
ProcDump是System Internal提供的一個專門用來監測程序CPU高使用率從而生成進程Dump文件的工具。ProcDump能夠根據系統的CPU使用率或者指定的性能計數器來針對特定進程生成一系列的Dump文件,以便調試者對事故緣由進行分析。session
有如下四種方式獲取Dump文件,具體以下:框架
如今重點介紹經過ProcDump抓取異常線程Dump文件,使用方法以下:工具
procdump [-a] [[-c|-cl CPU usage] [-u] [-s seconds]] [-n exceeds] [-e [1 [-b]] [-f <filter,...>] [-g] [-h] [-l] [-m|-ml commit usage] [-ma | -mp] [-o] [-p|-pl counter threshold] [-r] [-t] [-d <callback DLL>] [-64] <[-w] <process name or service name or PID> [dump file] | -i <dump file> | -u | -x <dump file> <image file> [arguments] >] [-? [ -e]
procdump -c 70 -s 5 -ma -n 3 w3wp性能
當系統CPU使用率持續5秒超過70%時,連續抓3個Full Dump。this
procdump outlook -p "\Processor(_Total)\% Processor Time" 80命令行
當系統CPU使用率超過80%,抓取Outlook進程的Mini Dump。線程
procdump -ma outlook -p "\Process(Outlook)\Handle Count" 10000
當Outlook進程Handle數超過10000時抓取Full Dump
procdump -ma 4572
直接生成進程號爲4572的Full Dump。
下圖是在WindgbHighCpu進程中形成High CPU時運行ProcDump命令的運行效果,能夠看到在CPU每次持續5秒達到5%後就會生成相應的Dump文件,共生成了3份Full Dump文件:
0:000> !runaway ERROR: !runaway: extension exception 0x80004002. "Unable to get thread times - dumps may not have time information"
解決的方法是將Debugging Tools for Windows (WinDbg)安裝目錄下的dbghelp.dll拷貝到procdump.exe所在目錄下,而後再運行命令抓取Dump。
操做步驟以下:
符號表是WinDbg關鍵的「數據庫」,若是沒有它,WinDbg基本上就是個廢物,沒法分析更多問題。因此使用WinDbg設置符號表,是必需要走的一步。
a、運行WinDbg軟件,而後按【Ctrl+S】彈出符號表設置窗。
b、將符號表地址:SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols 粘貼在輸入框中,點擊肯定便可。點擊肯定以前,請先確認紅色字的文件夾是否已被新建。
注:紅色字表示符號表本地存儲路徑,建議固定路徑,可避免符號表重複下載。
當你拿到一個Dump文件後,可以使用【Ctrl+D】快捷鍵來打開一個Dump文件,或者點擊WinDbg界面上的【File=>Open Crash Dump...】按鈕,來打開一個Dump文件。第一次打開Dump文件時,可能會收到以下提示,出現這個提示時,勾選「Don't ask again in this WinDbg session」,而後點否便可。
當你想打開第二個Dump文件時,可能由於上一個分析記錄未清除,致使沒法直接分析下一個Dump文件,此時你可使用快捷鍵【Shift+F5】來關閉上一個對Dump文件的分析記錄。
分享一個數據庫鏈接超時的Dump案例的分析過程:
當你打開一個Dump文件後,可能由於太多信息,讓你無所適從,不過不要緊,咱們只須要關注幾個關鍵信息就能夠了。
加載SOS以前,先肯定SOS的位置和版本,肯定方法以下:
若是安裝了Visual Studio,那麼先按照以下步驟打開VS的命令行:
而後,在打開的VS命令行中輸入【where sos.dll】,使得到SOS的位置和版本:
肯定完SOS位置和版本號後,開始加載SOS擴展命令:
.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SOS.dll
以下圖所示:
以下圖所示:
以下圖所示:
綜合以上分析能夠大膽地猜想Common.cs 中第16行「Data Source=***;Initial Catalog=***;Persist Security Info=True;User ID=sa;Password=***」的這個數據庫鏈接字符串應該有問題,而後到代碼中相應的地方進一步確認和修改就能夠了。
分享筆者工做過的一家公司某業務系統CPU飆高90%以上的Dump分析過程案例,步驟以下:
.load C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll
執行!runaway命令,查看線程使用CPU時間狀況,以下圖所示。着重分析前面幾個線程。
執行~22s命令,進入到線程22,以下圖所示:
執行!clrstack命令查看當前線程堆棧變量值的信息,從圖中能夠猜出大概是ExecuteNonQuery()這方法有點問題,以下圖所示:
再執行!dso命令能夠查看堆棧上的全部對象詳細信息,以下圖所示:
從圖中看,形成CPU飆高的罪魁禍首多半由SQL Server執行
INSERT INTO [dbo].[tbl_Interface_ProcessLog] (IKey,Username,ClientIP,Module,OrderNo,LogType,Content) VALUES (@IKey,@Username,@ClientIP,@Module,@OrderNo,@LogType,@Content)
這條語句時產生異常引發,而後到源代碼中找出相應的語句,通過進一步的確認、修改和從新發布後就解決了CPU飆高的問題。
至此,掌握幾個簡單的WinDbg命令以後,基本上絕大多數Dump你們均可以獨立分析了。固然WinDbg是個強大的工具,同時產生CPU飆高和內存泄漏的緣由也有不少。若是想分析得足夠準確,那麼就只有多學多練,多去分析。由於掌握WinDbg分析除了須要懂得幾個命令以外,經驗更加劇要,最後再補充兩點: