面向.Net程式設計師的dump分析

發表於2014-08-01

背景

  Dump檔案是程式的記憶體映象。可以把程式的執行狀態通過偵錯程式儲存到dump檔案中。在 Windows 系統上, dump 檔案分為核心 dump 和使用者態 dump 兩種。前者一般用來分析核心相關的問題,比如驅動程式;後者一般用來分析使用者態程式的問題。

一般的程式設計師可能接觸不到dump檔案,反而是運維會用的多一些。不過如果你抗戰在第一線,學會dump的分析無疑是掌握一柄利器。因為很多場景下,線上下的單元測試或者效能測試中由於測試用例的不充分或者生產與測試環境的硬體以及pv量級的不同等等情況導致問題暴露不出,而在生產環境中又沒有足夠的日誌或者堆疊資訊來指向問題產生的原因。這個時候dump檔案的分析就顯得很有作用。

正文分3節 抓取dump以及dump的手動和自動分析。對於初學者自動分析dump是很方便的一種渠道。


一. 抓取dump

1. 最簡單的方法 通過工作管理員

301448140713419

 

301459076336417 301459223522621

 

2. 通過debugdiag

debugdiag是一個微軟提供的dump抓取和分析工具。可以建立各種規則在不同的條件下抓取dump,同時具有強大的dump分析功能。

下載地址:http://www.microsoft.com/en-us/download/details.aspx?id=26798

301503142909461 301534370244277

 

3. Adplus方式

執行 cmd ,進入 adplus.exe 檔案所在目錄,執行如下命令:
單個程式: adplus .exe – hang – p <PID> – o d: ¥
多個程式: adplus .exe – hang – p <PID1> -p <PID2> – o d: ¥
Mini Dump : adplus .exe – MiniOnSecond – hang – p <PID> – o d: ¥

  抓取方式的選擇:

工作管理員的抓取適合dump檔案不大,對應系統盤預設存放路徑的空間完全足夠的情況。

debugdiag的抓取可以適應多種情況,通過工具的配置來完成。

Adplus解決了工作管理員抓取方式的限制,可以處理對應多個程式大檔案的情況。


二. dump的手動分析

工具: winbdg

WinDBG不是專門用於除錯.Net程式的工具,它更偏向於底層,可用於核心和驅動除錯。進行普通的.Net程式除錯還是使用微軟專為.Net開發的除錯工具MDBG更方便一些。但是WinDBG能看到更多的底層資訊,對於某些特別疑難的問題除錯有所幫助,例如記憶體洩漏等問題。

工具下載: WinBdgTool.zip

測試程式碼下載 : MyDumpTest.7z

首先新增設定符號檔案路徑(Symbol Path),當你使用Visual Studio編譯程式時,是否有留意到在bin/Debug資料夾下會有.pdb字尾的檔案?這些檔案包含有dll程式集的除錯符號,pdb檔案並不包含有執行程式碼,只是使除錯工具能把程式碼執行指令翻譯為正確的可識別字元。微軟提供了包含大量pdb檔案的公共伺服器,地址如下:http://msdl.microsoft.com/download/symbols。開啟windbg程式,選擇“File->Symbol File Path…“,把下面的內容複製進去儲存。srv*c:\temp*http://msdl.microsoft.com/download/symbols。

301649271027966

 

下面這行命令 如果你發現出現Unable to verify checksum…或者的訊息 那是因為你沒有新增.net的sos擴充套件或者sos的版本沒有對應上。.Net1.1時代的SOS擴充套件已經自帶於下載安裝的WinDBG中,從.Net2.0以後,SOS擴充套件已經自帶到.Net框架中:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\SOS.dll,為了不至於引起混淆,最好的方法就是使用前面的loadby偵錯程式元命令來讓WinDBG自己決定載入什麼版本的SOS。

新增sos:.load C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\sos.dll。

載入SOS後,使用命令.chain來檢視除錯鏈中是否已經成功包含SOS擴充套件。

301705555081802 301706480872506

301658551801915

 

這表明當前dump裡記錄的執行緒數。如果要切換執行緒,用波浪線+序號+s來切換,如切換到執行緒2,那麼用~2s即可。

  lm 檢視你載入的模組

301710063999087

 

kb 檢視native code呼叫棧

用~現在只有執行緒資訊,對於每個執行緒,在被抓的那一刻,在執行什麼,我們有命令:kb。

301702043524089

 

看到clr大家應該很眼熟吧。這裡已經可以看到較詳細的除錯資訊了。

301712492274309

 

因為我們的測試程式是測試的是執行緒阻塞所以我們選一個執行時間為0的,例如415

301715006495926

 

!dso 檢視這個堆疊中的物件

301720366961062

 

!clrstack 檢視這個執行緒的託管程式碼呼叫棧

301727546497664

 

通過上面我們已經可以看出這個執行緒一直都是處於阻塞狀態。

到這裡基本上一個小的測試程式可以告一段落了,當然windbg的功能遠遠不止如此,這裡分享一些資源給大家。

資源下載 : WinDbg入門.rar  Windbg用法詳解.7z


三. dump的自動分析

1. debugdiag

301531220878364 301535311021723

 

這裡有幾種規則型別的選擇,一般我們常用的用crash來檢視鎖和堵塞的情況,performance來檢查效能的問題。

選擇完成後直接點選開始分析

301537013529683

 

生成報表

301747538686228

 

檢視描述

301749236802491

 

點選詳細

301552455718853

 

這樣,紅色字型就是問題的所在。然後根據具體問題下發到對應開發部門解決。

2. Hang自動化分析

在WinDbg輸入如下命令

  .shell -ci “~* kb;.echo MANAGED THREADS;!threads;.echo MANAGED CALLSTACKS;~* e !clrstack;” D:\xx.exe


本篇先到此 希望對大家有幫助

相關文章