共用方式為


使用 !analyze 擴充功能

偵錯當機的目標計算機或應用程式的第一個步驟是使用 !analyze 擴充功能命令。 此延伸模組會執行大量的自動化分析。 此分析的結果會顯示在 [調試程式命令] 視窗中。

您應該使用 -v 選項來完整顯示數據。 如需其他選項的詳細資訊,請參閱 !analyze 參考頁面。

使用者模式 !analyze -v 範例

在此範例中,調試程式會附加至發生例外狀況的使用者模式應用程式。

0:000> !analyze -v
*******************************************************************************
*                                                                             *
*                        Exception Analysis                                   *
*                                                                             *
*******************************************************************************

Debugger SolutionDb Connection::Open failed 80004005

如果您連線到因特網,調試程式會嘗試存取由 Microsoft 維護的當機解決方案資料庫。 在此情況下,會顯示錯誤訊息,指出您的計算機無法存取因特網或網站無法運作。

FAULTING_IP: 
ntdll!PropertyLengthAsVariant+73
77f97704 cc               int     3

[FAULTING_IP] 欄位會顯示錯誤時的指令指標。

EXCEPTION_RECORD:  ffffffff -- (.exr ffffffffffffffff)
ExceptionAddress: 77f97704 (ntdll!PropertyLengthAsVariant+0x00000073)
   ExceptionCode: 80000003 (Break instruction exception)
  ExceptionFlags: 00000000
NumberParameters: 3
   Parameter[0]: 00000000
   Parameter[1]: 00010101
   Parameter[2]: ffffffff

[EXCEPTION_RECORD] 欄位會顯示此當機的例外狀況記錄。 您也可以使用 .exr (顯示例外狀況記錄) 命令來檢視這項資訊。

BUGCHECK_STR:  80000003

[BUGCHECK_STR] 欄位會顯示例外狀況代碼。 此名稱是誤判-錯誤檢查一詞實際上表示內核模式當機。 在使用者模式偵錯中,將會顯示例外狀況程式代碼,在此案例中為0x80000003。

DEFAULT_BUCKET_ID:  APPLICATION_FAULT

[DEFAULT_BUCKET_ID] 欄位會顯示此失敗所屬的一般失敗類別。

PROCESS_NAME:  MyApp.exe

[PROCESS_NAME] 欄位會指定引發例外狀況的進程名稱。

LAST_CONTROL_TRANSFER:  from 01050963 to 77f97704

[LAST_CONTROL_TRANSFER] 欄位會顯示堆疊上的最後一個呼叫。 在此情況下,位址上的程式代碼0x01050963在 0x77F97704呼叫函式。 您可以使用這些位址搭配 ln (列出最接近的符號) 命令來判斷這些位址所在的模組和函式。

STACK_TEXT:  
0006b9dc 01050963 00000000 0006ba04 000603fd ntdll!PropertyLengthAsVariant+0x73
0006b9f0 010509af 00000002 0006ba04 77e1a449 MyApp!FatalErrorBox+0x55 [D:\source_files\MyApp\util.c @ 541]
0006da04 01029f4e 01069850 0000034f 01069828 MyApp!ShowAssert+0x47 [D:\source_files\MyApp\util.c @ 579]
0006db6c 010590c3 000e01ea 0006fee4 0006feec MyApp!SelectColor+0x103 [D:\source_files\MyApp\colors.c @ 849]
0006fe04 77e11d0a 000e01ea 00000111 0000413c MyApp!MainWndProc+0x1322 [D:\source_files\MyApp\MyApp.c @ 1031]
0006fe24 77e11bc8 01057da1 000e01ea 00000111 USER32!UserCallWinProc+0x18
0006feb0 77e172b4 0006fee4 00000001 010518bf USER32!DispatchMessageWorker+0x2d0
0006febc 010518bf 0006fee4 00000000 01057c5d USER32!DispatchMessageA+0xb
0006fec8 01057c5d 0006fee4 77f82b95 77f83920 MyApp!ProcessQCQPMessage+0x3b [D:\source_files\MyApp\util.c @ 2212]
0006ff70 01062cbf 00000001 00683ed8 00682b88 MyApp!main+0x1e6 [D:\source_files\MyApp\MyApp.c @ 263]
0006ffc0 77e9ca90 77f82b95 77f83920 7ffdf000 MyApp!mainCRTStartup+0xff [D:\source_files\MyApp\crtexe.c @ 338]
0006fff0 00000000 01062bc0 00000000 000000c8 KERNEL32!BaseProcessStart+0x3d

[STACK_TEXT] 欄位會顯示錯誤元件的堆疊追蹤。

FOLLOWUP_IP: 
MyApp!FatalErrorBox+55
01050963 5e               pop     esi

FOLLOWUP_NAME:  dbg

SYMBOL_NAME:  MyApp!FatalErrorBox+55

MODULE_NAME:  MyApp

IMAGE_NAME:  MyApp.exe

DEBUG_FLR_IMAGE_TIMESTAMP:  383490a9

!analyze 判斷可能導致錯誤的指令時,它會在 [FOLLOWUP_IP] 字段中顯示它。 SYMBOL_NAME、MODULE_NAME、IMAGE_NAME和DEBUG_FLR_IMAGE_TIMESTAMP欄位會顯示與此指令對應的符號、模組、影像名稱和影像時間戳。

STACK_COMMAND:  .ecxr ; kb

[STACK_COMMAND] 欄位會顯示用來取得STACK_TEXT的命令。 您可以使用此命令重複此堆疊追蹤顯示,或加以變更以取得相關的堆疊資訊。

BUCKET_ID:  80000003_MyApp!FatalErrorBox+55

[BUCKET_ID] 欄位會顯示目前失敗所屬的特定失敗類別。 此類別可協助調試程式判斷要顯示在分析輸出中的其他資訊。

Followup: dbg
---------

如需FOLLOWUP_NAME和待處理字段的相關信息,請參閱 追蹤字段和triage.ini檔案

可能會顯示各種不同的其他欄位:

  • 如果控件已傳送至無效的位址,則 [FAULTING_IP] 字段會包含這個無效的位址。 FAILED_INSTRUCTION_ADDRESS欄位不會顯示這個位址的反組譯碼,但這個反組譯碼可能毫無意義。 FOLLOWUP_IP 在此情況下,SYMBOL_NAME、MODULE_NAME、IMAGE_NAME和DEBUG_FLR_IMAGE_TIMESTAMP欄位將參考此指示的呼叫端。

  • 如果處理器失火,您可能會看到SINGLE_BIT_ERROR、TWO_BIT_ERROR或POSSIBLE_INVALID_CONTROL_TRANSFER字段。

  • 如果記憶體損毀似乎已經發生,CHKIMG_EXTENSION欄位會指定 應該用來調查的 !chkimg 擴充功能命令。

Kernel-Mode !analyze -v 範例

在此範例中,調試程式會附加至剛當機的計算機。

kd> !analyze -v
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pagable (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: 00000004, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000001, value 0 = read operation, 1 = write operation
Arg4: f832035c, address which referenced memory

接下來會顯示錯誤檢查參數。 它們後面各有描述。 例如,第三個參數為 1,且下列批注會說明這表示寫入作業失敗。

## Debugging Details:


WRITE_ADDRESS:  00000004 Nonpaged pool

CURRENT_IRQL:  2

接下來的幾個欄位會根據墜機的性質而有所不同。 在此情況下,我們看到WRITE_ADDRESS和CURRENT_IRQL欄位。 這些只是重述錯誤檢查參數中顯示的資訊。 藉由比較語句 「Nonpaged pool」 與錯誤檢查文字,該文字會讀取「嘗試存取可分頁位址或完全無效的位址」,我們可以看到位址無效。 在此情況下,無效的位址0x00000004。

FAULTING_IP: 
USBPORT!USBPORT_BadRequestFlush+7c
f832035c 894204           mov     [edx+0x4],eax

[FAULTING_IP] 欄位會顯示錯誤時的指令指標。

DEFAULT_BUCKET_ID:  DRIVER_FAULT

[DEFAULT_BUCKET_ID] 欄位會顯示此失敗所屬的一般失敗類別。

BUGCHECK_STR:  0xD1

[BUGCHECK_STR] 欄位會顯示我們已經看到的錯誤檢查程式代碼。 在某些情況下,會附加額外的分級資訊。

TRAP_FRAME:  f8950dfc -- (.trap fffffffff8950dfc)
.trap fffffffff8950dfc
ErrCode = 00000002
eax=81cc86dc ebx=81cc80e0 ecx=81e55688 edx=00000000 esi=81cc8028 edi=8052cf3c
eip=f832035c esp=f8950e70 ebp=f8950e90 iopl=0         nv up ei pl nz ac po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010216
USBPORT!USBPORT_BadRequestFlush+7c:
f832035c 894204           mov     [edx+0x4],eax     ds:0023:00000004=????????
.trap
Resetting default context

TRAP_FRAME欄位會顯示此當機的陷阱框架。 您也可以使用 .trap (Display Trap Frame) 命令來檢視這項資訊。

LAST_CONTROL_TRANSFER:  from f83206e0 to f832035c

[LAST_CONTROL_TRANSFER] 欄位會顯示堆疊上的最後一個呼叫。 在此情況下,位址上的程式代碼0xF83206E0在 0xF832035C 呼叫函式。 您可以使用 ln (列出最接近的符號) 命令來判斷這些位址所在的模組和函式。

STACK_TEXT:  
f8950e90 f83206e0 024c7262 00000000 f8950edc USBPORT!USBPORT_BadRequestFlush+0x7c
f8950eb0 804f5561 81cc8644 81cc8028 6d9a2f30 USBPORT!USBPORT_DM_TimerDpc+0x10c
f8950fb4 804f5644 6e4be98e 00000000 ffdff000 nt!KiTimerListExpire+0xf3
f8950fe0 8052c47c 8053cf20 00000000 00002e42 nt!KiTimerExpiration+0xb0
f8950ff4 8052c16a efdefd44 00000000 00000000 nt!KiRetireDpcList+0x31

[STACK_TEXT] 欄位會顯示錯誤元件的堆疊追蹤。

FOLLOWUP_IP: 
USBPORT!USBPORT_BadRequestFlush+7c
f832035c 894204           mov     [edx+0x4],eax

[FOLLOWUP_IP] 欄位會顯示可能導致錯誤的指令反組譯碼。

FOLLOWUP_NAME:  usbtri

SYMBOL_NAME:  USBPORT!USBPORT_BadRequestFlush+7c

MODULE_NAME:  USBPORT

IMAGE_NAME:  USBPORT.SYS

DEBUG_FLR_IMAGE_TIMESTAMP:  3b7d868b

SYMBOL_NAME、MODULE_NAME、IMAGE_NAME和DBG_FLR_IMAGE_TIMESTAMP字段會顯示對應至此指令的符號、模組、影像和影像時間戳(如果有效),或此指令的呼叫者(如果不是的話)。

STACK_COMMAND:  .trap fffffffff8950dfc ; kb

[STACK_COMMAND] 欄位會顯示用來取得STACK_TEXT的命令。 您可以使用此命令重複此堆疊追蹤顯示,或加以變更以取得相關的堆疊資訊。

BUCKET_ID:  0xD1_W_USBPORT!USBPORT_BadRequestFlush+7c

[BUCKET_ID] 欄位會顯示目前失敗所屬的特定失敗類別。 此類別可協助調試程式判斷要顯示在分析輸出中的其他資訊。

如需FOLLOWUP_NAME和待處理字段的相關信息,請參閱 追蹤字段和triage.ini檔案

可能會顯示各種不同的其他欄位:

  • 如果控件已傳送至無效的位址,則 [FAULTING_IP] 字段會包含這個無效的位址。 FAILED_INSTRUCTION_ADDRESS欄位不會顯示這個位址的反組譯碼,但這個反組譯碼可能毫無意義。 FOLLOWUP_IP 在此情況下,SYMBOL_NAME、MODULE_NAME、IMAGE_NAME和DBG_FLR_IMAGE_TIMESTAMP字段將參考此指示的呼叫端。

  • 如果處理器失火,您可能會看到SINGLE_BIT_ERROR、TWO_BIT_ERROR或POSSIBLE_INVALID_CONTROL_TRANSFER字段。

  • 如果記憶體損毀似乎已經發生,CHKIMG_EXTENSION欄位會指定 應該用來調查的 !chkimg 擴充功能命令。

  • 如果錯誤檢查發生在設備驅動器的程式代碼內,其名稱可能會顯示在 [BUGCHECKING_DRIVER] 欄位中。

後續欄位和triage.ini檔案

在使用者模式和核心模式中,如果可以判斷,顯示中的 [後續] 字段會顯示目前堆棧框架擁有者的相關信息。 此資訊會以下列方式決定:

  1. 使用 !analyze 擴充功能時,調試程式會從堆棧中的頂端框架開始,並判斷它是否負責錯誤。 如果不是,則會分析下一個畫面。 此程式會繼續進行,直到找到可能發生錯誤的畫面為止。

  2. 調試程式會嘗試判斷此框架中模組和函式的擁有者。 如果可以判斷擁有者,此畫面會被視為發生錯誤。

  3. 如果無法判斷擁有者,調試程式會傳遞至下一個堆疊框架等等,直到決定擁有者為止(或完全檢查堆棧)。 在此搜尋中找到其擁有者的第一個框架被視為有錯誤。 如果堆棧用盡而找不到任何資訊,則不會顯示任何後續欄位。

  4. 錯誤畫面的擁有者會顯示在 [待處理] 欄位中。 如果使用 !analyze -v,FOLLOWUP_IP 、SYMBOL_NAME、MODULE_NAME、IMAGE_NAME和DBG_FLR_IMAGE_TIMESTAMP字段將參考此框架。

若要讓後續欄位顯示有用的資訊,您必須先建立包含模組和函式擁有者名稱的triage.ini檔案。

triage.ini檔案應該識別所有可能發生錯誤的模組擁有者。 您可以使用參考字串,而不是實際的擁有者,但此字串不能包含空格。 如果您確定模組不會發生錯誤,您可以省略此模組或指出應該略過它。 您也可以指定個別函式的擁有者,讓分級程式更精細的粒度。

如需triage.ini檔案語法的詳細資訊,請參閱 指定模組和函式擁有者

其他 !analyze 技術

如果沒有發生當機或例外狀況, !analyze 會顯示非常簡短的文字,提供目標的目前狀態。 在某些情況下,您可能會想要強制進行分析,就像發生當機一樣。 使用 !analyze -f 來完成這項工作。

在使用者模式中,如果發生例外狀況,但您認為基礎問題是已停止的線程,請將目前的線程設定為您正在調查的線程,然後使用 !analyze -hang。 此延伸模組會執行線程堆疊分析,以判斷是否有任何線程封鎖其他線程。

在核心模式中,如果發生錯誤檢查,但您認為基礎問題是懸空的線程,請使用 !analyze -hang。 此延伸模組會調查系統持有的鎖定,並掃描 DPC 佇列鏈結,並顯示任何已停止線程的指示。 如果您認為問題是內核模式資源死結,請使用 !deadlock 擴充功能以及驅動程序驗證工具的死結偵測選項。

您也可以自動忽略已知問題。 若要這樣做,您必須先建立包含已知問題格式化清單的 XML 檔案。 使用 !analyze -c -load KnownIssuesFile 擴充功能來載入此檔案。 然後發生例外狀況或中斷時,請使用 !analyze -c 擴充功能。 如果例外狀況符合其中一個已知問題,目標將會繼續執行。 如果目標未繼續執行,您可以使用 !analyze -v 來判斷問題的原因。

另請參閱

如需詳細資訊,請參閱這些主題。

!分析

錯誤檢查代碼參考

使用 Windows 調試程式進行損毀傾印分析 (WinDbg)

使用 WinDbg 分析內核模式傾印檔案