天天看點

Windbg核心調試之四: Dump檔案分析

Dump 檔案分析很大程度上就是分析藍屏産生的原因。這種系統級的錯誤算是Windows提示錯誤中比較嚴重的一種(更嚴重的還有啟動黑屏等硬體或軟體相容性錯誤等等)。說它是比較嚴重,是因為畢竟Windows還提供了dump檔案給使用者分析,至少能比較容易的找到錯誤的原因。一般藍屏要麼是核心程式中的異常或違規,要麼是資料結構的損壞,也有boot或shutdown的時候核心出錯。有時候藍屏是一閃而過,緊接着是系統重新開機;有時候是藍屏等待。總之藍屏的時候都提示了一些停止代碼和錯誤資訊,不過這些提示是不全面的,最多知道哪個子產品出錯(比如驅動)。想了解進一步的資訊,或者通過搜尋引擎,最好的方式當然是dump檔案分析。當然,如果有更進一步研究的欲望,核心調試是更好的方法,不過這需要某些軟體支援和調試技巧。

類型

Dump檔案有三種:完整記憶體轉儲,核心記憶體轉儲,小記憶體轉儲。System Properties中的進階選項中可以看到這些設定。

完整記憶體轉儲太大,一般是實體記憶體大小或多一些,包括了使用者程序頁面,這種方式不實用,2GB的實體記憶體轉儲出來至少要2GB的磁盤空間(還有檔案頭資訊)。核心轉儲一般是200MB大小(實體記憶體小于4GB),它隻是包含了所有屬于核心模式的實體記憶體。小記憶體轉儲一般是64KB(64位上是 128KB),這兩種方式是更常用的。

小記憶體轉儲在\Windows\Minidump下生成了一個叫Mini日期+序列号.dmp的檔案,這個珍貴的資源就是系統Crash時刻的狀态,隻不過小記憶體轉儲隻記錄的有限的資訊,而且在你分析時,如果windbg沒有設定符号伺服器的路徑(關于符号伺服器,請參考Windbg核心調試之二: 常用指令),那麼你的目前系統必須和發生藍屏的系統的Ntoskrnl.exe版本相同,否則就有找不到符号的問題産生。

啟動windbg,用Open Crash Dump打開dump檔案,或者直接拖動檔案到windbg中,windbg顯示如下資訊: 

<a></a>

Loading Dump File [C:\dbg\Mini052809-01.dmp]

Mini Kernel Dump File: Only registers and stack trace are available

Symbol search path is: SRV*d:/temp/*http://msdl.microsoft.com/download/symbols

Executable search path is:

Windows Vista Kernel Version 6000 (Service Pack 1) UP Free x86 compatible

Kernel base = 0x80400000 PsLoadedModuleList = 0x8046e8f0

Debug session time: Thu May 28 16:12:29.031 2009 (GMT+8)

System Uptime: not available

Loading Kernel Symbols...............................................................

Loading unloaded module list.....................................................................

Loading UserSymbols

********************************************************************************                                                                                                                                           **                        Bugcheck Analysis                                                                                         **                                                                                                                                           ********************************************************************************

Use !analyze -v to get detailed debugging information.

BugCheck 7F, {0, 0, 0, 0}

大緻上提示了Crash系統的版本,加載符号的過程,如果找不到符号檔案,還會提示Unable to load image。如下錯誤就是找不到ntoskrnl.exe的符号檔案:

Unable to load image \SystemRoot\system32\ntoskrnl.exe, Win32 error 0n2

*** WARNING: Unable to verify timestamp for ntoskrnl.exe

*** ERROR: Module load completed but symbols could not be loaded for ntoskrnl.exe 

指令

通過lm指令檢視子產品清單。另外,如果出現Unable to load image,說明沒有找到這個檔案,這個時候需要檢視是否加載了正确的符号檔案。設定符号伺服器路徑(.symfix指令)是很有必要的,因為調試機器和Crash機器的環境很可能不一緻。

運作指令kb,顯示調用棧的資訊。如果有正确的符号設定,可以看到調用的函數名。如果你在調試自己驅動程式的藍屏問題,請確定設定正确該驅動程式的符号路徑,不然就會出現Stack unwind information not available的問題。加入正确的符号檔案(pdb)後,可以用指令!reload重新加載符号檔案。

通過!thread和!process,可以顯示目前程序和線程。或者通過dt nt!_KTHREAD 位址和dt nt!_EPROCESS位址來檢視線程和程序結構。

Windbg提供了自動分析dump檔案的機制。通過指令!analyze –v,windbg可以自動做分析,顯示如下資訊:

*******************************************************************************

*                                                                                                                                          *

*                         Bugcheck Analysis                                                                                       *

DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)

An attempt was made to access a pageable (or completely invalid) address at an

interrupt request level (IRQL) that is too high.   This is usually

caused by drivers using improper addresses.

If kernel debugger is available get stack backtrace.

Arguments:

Arg1: e1147008, memory referenced

Arg2: 0000001c, IRQL

Arg3: 00000000, value 0 = read operation, 1 = write operation

Arg4: fbe93403, address which referenced memory

Debugging Details:

------------------

READ_ADDRESS:   e1147008 Paged pool

CURRENT_IRQL:   1c

FAULTING_IP:

myfault+403

fbe93403 8b06             mov      eax,dword ptr [esi]

DEFAULT_BUCKET_ID:   DRIVER_FAULT

BUGCHECK_STR:   0xD1

PROCESS_NAME:   NotMyfault.exe

TRAP_FRAME:   f9357b80 --(trap fffffffff9357b80)

ErrCode = 00000000

eax=00000000 ebx=8111f330 ecx=000000d1 edx=0000001c esi=e1147008 edi=00000000

eip=fbe93403 esp=f9357bf4 ebp=f9357c58 iopl=0          nv up ei pl zr na pe nc

cs=0008   ss=0010   ds=0023   es=0023   fs=0030   gs=0000              efl=00010246

myfault+0x403:

fbe93403 8b06             mov      eax,dword ptr [esi]   ds:0023:e1147008=????????

Resetting default scope

LAST_CONTROL_TRANSFER:   from 804f880d to 80527da8

STACK_TEXT:

f9357734 804f880d 00000003 f9357a90 00000000 nt!RtlpBreakWithStatusInstruction

f9357780 804f93fa 00000003 e1147008 fbe93403 nt!KiBugCheckDebugBreak+0x19

f9357b60 80540853 0000000a e1147008 0000001c nt!KeBugCheck2+0x574

f9357b60 fbe93403 0000000a e1147008 0000001c nt!KiTrap0E+0x233

WARNING: Stack unwind information not available. Following frames may be wrong.

f9357c58 805759d1 ffb5c3b0 8111f318 811d9130 myfault+0x403

f9357d00 8056e33c 00000090 00000000 00000000 nt!IopXxxControlFile+0x5e7

f9357d34 8053d808 00000090 00000000 00000000 nt!NtDeviceIoControlFile+0x2a

f9357d34 7c92eb94 00000090 00000000 00000000 nt!KiFastCallEntry+0xf8

0012f9f0 7c92d8ef 7c801671 00000090 00000000 ntdll!KiFastSystemCallRet

0012f9f4 7c801671 00000090 00000000 00000000 ntdll!ZwDeviceIoControlFile+0xc

0012fa54 004018c2 00000090 83360018 00000000 0x7c801671

STACK_COMMAND:   kb

FOLLOWUP_IP:

SYMBOL_STACK_INDEX:   4

FOLLOWUP_NAME:   MachineOwner

MODULE_NAME: myfault

IMAGE_NAME:   myfault.sys

DEBUG_FLR_IMAGE_TIMESTAMP:   43774e1d

SYMBOL_NAME:   myfault+403

FAILURE_BUCKET_ID:   0xD1_myfault+403

BUCKET_ID:   0xD1_myfault+403

Followup: MachineOwner

一般是按照如下:停止碼解釋,陷阱幀寄存器資訊,藍屏屬性(有些除零錯誤就在這裡顯示),棧調用,錯誤指令位置(FOLLOWUP_IP),出錯源代碼和彙編代碼行,錯誤代碼行,出錯子產品資訊(包括負責人等資訊),來組織自動分析資訊。

通過r指令,可以顯示Crash時刻寄存器的狀态和最後的指令狀态。

通過d指令,可以顯示目前記憶體的位址。在定位了錯誤代碼行了之後,就可以進一步進行核心調試和系統調試了。

繼續閱讀