這是本文件的舊版!
Trace BSOD with WinDbg
Introduction
本篇文章記錄使用WinDbg追蹤BSOD root cause的過程,目的在於透過minidump去找出發生問題的程式碼。而要透過minidump的主要原因,是因為完整的memory deump太大,不易從客戶手中獲得。本篇文章包含:
- Launch WinDbg: 使用WinDbg載入並分析minidump。
- Setup Symbol Path: 載入Symbol以獲得詳細的callstack內容。
- Analyze With Source Code: 找出問題程式碼的位置。
在本文章中,我寫一個測試用的driver叫testdriver當做範例。在其它章節補充遇到與想到的問題。
Launch WinDbg
Install WinDbg
起初我安裝7600版本的SDK,在Win2012上無法找出正確的root cause,後來改使用Win10 1703版本的SDK。可以直接到微軟網站下載並安裝,只要安裝WinDbg就好。
Fetch MiniDump File
The first analysis
首先打開從BSOD主機上抓到的minidump:
打開後會看到類似以下畫面,接著點擊!analyze -v或直接在下方kd>中輸入!analyze -v,就會開始分析:
CallStack是debug非常重要的依據,但因為目前沒載入symbol table,無法找到位置所對應的意義:
STACK_TEXT: ffffd000`eb981498 fffff801`3b5c389a : 00000000`00000038 00000000`00000000 00000000`00000030 00000000`00000000 : testdriver+0x19fa ffffd000`eb9814a0 00000000`00000038 : 00000000`00000000 00000000`00000030 00000000`00000000 ffffd000`eb981538 : testdriver+0x189a ffffd000`eb9814a8 00000000`00000000 : 00000000`00000030 00000000`00000000 ffffd000`eb981538 ffffe000`00000250 : 0x38
Setup Symbol Path
為了要讓debug資訊更清楚,我們必須要載入symbol資料。
Setup search path
打開file>symbol search path,並如下圖輸入,我把symbols給放在C:\symbols下:
SRV*c:\symbols*http://msdl.microsoft.com/download/symbols
完成後會出現載入testdriver.sys錯誤,這是因為缺少testdriver的symbol:
Enable symbol loading diagnostics mode
在kd>中輸入!sym noisy後,可以啟用診斷模式。
Reload symbol
啟用診斷模式後,輸入.reload /i testdriver.sys可以重新讀取symbol:
由上圖可以知道WinDbg到那些地方去載入symbol,所以只要把testdriver.sys放到對應目錄下並重新reload,即可通過這關。但下一關是pdb的問題:
通常build sys出來時,會伴隨著一個pdb,一樣把它放到對應目錄後並重新reload symbol。
The second analysis
Analyze With Source Code
Setup Source Search Path
The third analysis
其它
如何得知driver版本?
是否一定要載入發生問題的驅動sys與pdb?
這個要看發生問題的情況。我另外一隻驅動程式發生的BSOD問題,在只提供系統本身的symbol後,就已經知道問題的發生點:
STACK_TEXT: ffffd001`79154408 fffff800`4d5980e7 : 00000000`00000050 ffffffff`fffffff8 00000000`00000001 ffffd001`791545f0 : nt!KeBugCheckEx ffffd001`79154410 fffff800`4d47a9c9 : 00000000`00000001 ffffe001`dd3c3880 ffffd001`791545f0 fffff800`4d6a7d33 : nt! ?? ::FNODOBFM::`string'+0x20c37 ffffd001`791544b0 fffff800`4d57122f : 00000000`00000001 ffffffff`ffffffd0 00000000`00001000 ffffd001`791545f0 : nt!MmAccessFault+0x7a9 ffffd001`791545f0 fffff800`4d51eefd : 00000000`00000200 00000000`20206f49 e001e7f2`00000000 ffffe001`e521d210 : nt!KiPageFault+0x12f ffffd001`79154780 fffff801`72e0136c : 00000000`00000000 00000000`00000801 00000000`00000000 fffff800`4d6f07c8 : nt!IoWriteErrorLogEntry+0x25 ffffd001`791547b0 00000000`00000000 : 00000000`00000801 00000000`00000000 fffff800`4d6f07c8 ffffffff`80000b00 : testdriver2+0x136c當然這也和code本身的寫法與問題發生點有關。
Reference