Windows下獲取Dump文件以及進程下各線程調用棧的方法總結

1. Dump文件的用途

Dump文件, 主要用於診斷一個進程的運行狀態,尤其是碰到崩潰(Crash)或者掛起(hang)不響應時,需要分析它的工作狀態.  除了平時常見的attach到這個進程, 分析Dump文件就成了一個重要的手段了.

相信一些做軟件維護和支持的工程師在這方面深有體會, 比如某天某時,客戶說, 呀, 糟糕, 服務器進程掛掉了, 怎麼回事? 然後,看看了日誌文件,也沒有什麼可用的信息.  技術支持告訴他, 按某步驟生成一個dump文件來看看......

2. 如何生成Dump文件, 如何獲取調用棧

生成dump文件, 可以按照進程的狀態要求, 分兩種情況:
1) 這個進程並不會Crash, 它一直處於運行狀態, 
    那麼如何在不終止進程的情況下抓取dump文件呢?Debugging Tools for Windows裏提供了一個非常好的工具,adplus.vbs。從名字可以看出,實際上是一個vb腳本,只是對cdb調試器作的一個包裝腳本。
    其路徑與Debugging Tools for Windows的安裝路徑相同,使用的方法也很簡單,如下所示:
     adplus.vbs -hang -p 1234 -o d:/dump
     其中-hang指明使用hang模式,亦即在進程運行過程中附加上去snapshot抓取一個dump文件,完成之後detach。 
     使用sysinternals中的procdump命令,一樣可以得到運行狀態的的進程的dump文件:
     如:
procdump -s 20 -n 1 OBMO.exe c:\OBMO.dmp
procdump -s 20 -n 1 AMPService.exe c:\AMPService.dmp
procdump -s 20 -n 1 OBServiceManager.exe c:\OBServiceManager.dmp
procdump -s 20 -n 1 MlSrvWrapper.exe c:\MlSrvWrapper.dmp
procdump -s 20 -n 1 AdminWebServices.exe c:\AdminWebServices.dmp

      
 
2) 進程起來之後,很快就會Crash, 要獲取它Crash時的dump文件
     與之對應的是-crash崩潰模式,用戶先啓動adplus,然後由它啓動要監控的程序,在出現異常崩潰時自動生成dump文件,或者通過Ctrl-C人爲發出抓取指 令。但是-crash模式在抓取完成之後,被監控的進程就必須終止。因此我們在這裏只選用-hang模式。
-p是要調試的進程ID,-o 指定要output的dump文件路徑。另外,與adplus類似的,有個UserDump工具,但是抓取用戶模式的進程,而adplus則是內核模式和用戶模式兩者皆可。

     再就是使用Dr. Waston工具自動創建dump文件 (Crash的時候)
【抓dump】
1、一般抓法
adplus -hang -p 3230 -quiet 抓3230 pid進程,hang模式,相當於把那個進程暫停住,取內存快照
adplus -crash -pn w3wp -quiet 抓w3wp進程,crash模式,當那個進程崩潰結束的時候自動抓取當時的內存
adplus -hang -iis -quiet 抓IIS相關進程,包括其上host的web應用,以及iis自身
2、抓window服務
http://support.microsoft.com/kb/824344/zh-cn
3、遠程抓
http://blog.joycode.com/tingwang/archive/2006/08/11/79763.aspx
4、抓藍屏和死機的dump
電腦無故重啓或者藍屏會在C:\WINDOWS\Minidump\下保存一個minidump,但是這個minidump可用的命令很少,一般只打!analyze –v看到是哪個進程引起的,還有相關的驅動模塊就基本定位問題了。
5、IIS回收的時候抓
http://blog.yesky.com/blog/omakey/archive/2006/12/17/1618015.html
6、計劃任務抓
比如一個進程起來後不知道它什麼時候會意外崩潰,可以在計劃任務裏用crash裏抓,當那個進程意外終止的時候,cdb可以直接附加上去,抓取當時的dump,如果要抓一些會自動重啓的進程,而且要抓每次重啓前的dump,可以參考附錄裏一節。

3. 如何分析Dump文件

【常用命令】

1、先path C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727,把.net路徑設置爲path環境變量,一遍在windbg裏可以直接.load sos,而不必.load C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\sos.dll
2、ld demo,加載你程序的pdb文件,調試.net程序一般要把kernel32和mscorwks的符號加載上,關於這兩個東西大家可以查資料,尤其是後者有哪些函數可以多瞭解一些。
3、在windbg的file/symbol file path對話框裏輸入以下文字,以便自動加載和下載符號
C:\WINDOWS\Symbols;d:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\symbols;.sympath SRV*d:\localsymbols*http://msdl.microsoft.com/download/symbols
其中有windows、.net2.0和自動從網上下載的調試符號,注意根據自己的情況適當修改目錄

【調試死鎖】
1、!syncblk,查看哪些線程拿到了鎖
2、~67e!clrstack 跳到某個拿到鎖的線程看它正在幹什麼操作,遲遲不肯釋放鎖
3、!runaway 查看這個佔有鎖的線程運行了多長時間。
4、~*e!clrstack查看所有線程的託管堆棧,看看哪些是正在等待鎖的,比如hang在System.Threading.Monitor.Enter(System.Object) 
5、~136s選擇該線程,顯示如下
0:000> ~136s eax=00005763 ebx=08deeb5c ecx=03eff0d4 edx=5570ab69 esi=08deeb5c edi=7ffd6000 eip=7c95ed54 esp=08deeb10 ebp=08deebb8 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 ntdll!KiFastSystemCallRet: 7c95ed54 c3 ret
找到ecx寄存器的值,複製後ctrl+f,向上查找,會找到!syncblk的地方,如下
0:000> !syncblk Index SyncBlock MonitorHeld Recursion Owning Thread Info SyncBlock Owner 1906 03ee4be4 5 1 03ee8f88 22c8 67 185e2ef0 System.Object 5390 052ca39c 3 1 05292b30 1dd4 49 1060d3ac System.Object 9372 0530702c 15 1 0012d3a8 1aa8 80 185e7704 System.Object 11428 03eff0d4 35 1 053b8fa8 169c 120 166acd98 System.Object 15278 0531c6b4 61 1 06bc1430 26d8 86 1a5bea88 System.Object
可以看到136線程等待的鎖被120號線程佔着不放(格式有點亂,湊合看),
6、有時候通過ecx寄存器找鎖不是很確定,可以用~* kb來把所有線程堆棧打出來,然後根據!syncblk出來的同步快的值去搜索大概有多少個線程在等那個鎖。因爲同樣是等待鎖,可等的狀態不一樣,有的在Q裏,有的鎖已經升級,有的去嘗試去拿鎖了,所以不一定當時ecx寄存器指向那塊內存,具體如何找到某個正在等待鎖的線程等待的鎖的內存地址,以及它正等待的這個鎖被哪個線程拿着,我還沒琢磨出規律來,但一般情況下,如果有其它同步對象的話,更難查。.net裏用我上面說的幾步就能查出鎖的問題了。

更詳細的內容,可以參照這篇文章:http://www.cppblog.com/tgh621/archive/2010/10/27/131525.html

4.  獲取調用棧

這裏,可以使用幾個工具:
1. 使用StraceNT這個trace工具

StraceNT - A System Call Tracer for Windows 

http://www.intellectualheaven.com/default.asp?BH=projects&H=strace.htm 

2. 直接使用procexp.exe也可以看到進程的調用棧信息,如果符號庫比較全,則調用棧很清晰.
3. MSE (Managed Stack Explorer)
    這個工具對於dotnet進程非常實用.http://mse.codeplex.com/, 直接可以看到dotnet進程的託管棧細節.

工具基本上也就這麼多了,具體分析還得看怎麼用.

  


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章