尋找失敗的程式
在尋找失敗的程式之前,請確定您位於接受處理器的內容中。 若要判斷接受的處理器,請在 每個處理器上使用 !np 擴充功能,並尋找已載入例外狀況處理程序的處理器。 接受處理器的例外狀況處理程式具有 0xFFFFFFFF 以外的位址。
例如,因為此處理器上的 NtTib.ExceptionList 位址是0xFFFFFFFF,因此這不是具有失敗進程的處理器:
0: kd> !pcr
PCR Processor 0 @ffdff000
NtTib.ExceptionList: ffffffff
NtTib.StackBase: 80470650
NtTib.StackLimit: 8046d860
NtTib.SubSystemTib: 00000000
NtTib.Version: 00000000
NtTib.UserPointer: 00000000
NtTib.SelfTib: 00000000
SelfPcr: ffdff000
Prcb: ffdff120
Irql: 00000000
IRR: 00000000
IDR: ffffffff
InterruptMode: 00000000
IDT: 80036400
GDT: 80036000
TSS: 80257000
CurrentThread: 8046c610
NextThread: 00000000
IdleThread: 8046c610
DpcQueue:
不過,處理器 1 的結果會大不相同。 在此情況下,NtTib.ExceptionList 的值是 f0823cc0,而不是0xFFFFFFFF,表示這是發生例外狀況的處理器。
0: kd> ~1
1: kd> !pcr
PCR Processor 1 @81497000
NtTib.ExceptionList: f0823cc0
NtTib.StackBase: f0823df0
NtTib.StackLimit: f0821000
NtTib.SubSystemTib: 00000000
NtTib.Version: 00000000
NtTib.UserPointer: 00000000
NtTib.SelfTib: 00000000
SelfPcr: 81497000
Prcb: 81497120
Irql: 00000000
IRR: 00000000
IDR: ffffffff
InterruptMode: 00000000
IDT: 8149b0e8
GDT: 8149b908
TSS: 81498000
CurrentThread: 81496d28
NextThread: 00000000
IdleThread: 81496d28
DpcQueue:
當您處於正確的處理器內容時, !process 擴充功能會顯示目前執行中的進程。
進程傾印最有趣的部分如下:
時間(高值表示進程可能是罪魁禍首)。
句柄計數 (這是第一個專案中 ObjectTable 後面括弧中的數位)。
線程狀態 (許多進程有多個線程)。 如果目前的進程是 閑置,可能是計算機真的閑置,或因為發生一些不尋常的問題而停止回應。
雖然使用 !process 0 7 延伸模組是找出懸空系統上問題的最佳方式,但有時候篩選的資訊太多。 請改用 !process 0 0 ,然後在 CSRSS 的處理程式句柄和任何其他可疑進程上使用 !process 。
使用 !process 0 7 時,許多線程可能會標示為「核心堆疊未常駐」,因為這些堆棧已分頁。如果這些頁面仍在轉換中的快取中,您可以在 !process 0 7 之前使用 .cache 譯碼區取得詳細資訊:
kd> .cache decodeptes
kd> !process 0 7
如果您可以識別失敗的進程,請使用 !process <process> 7 來顯示進程中每個線程的核心堆疊。 此輸出可以識別核心模式中的問題,並顯示可疑進程正在呼叫的內容。
除了 !process 之外,下列延伸模組可協助判斷沒有響應的計算機原因:
副檔名 | 效果 |
---|---|
識別已準備好執行的線程,依優先順序排序。 |
|
識別任何保留的資源鎖定,以防零售逾時發生死結。 |
|
檢查虛擬記憶體使用量。 |
|
判斷某個類型的集區配置是否不成比例大(需要集區標記)。 |
|
檢查實體記憶體狀態。 |
|
檢查堆積的有效性。 |
|
搜尋非分頁集區中是否有作用中的 IRP。 |
如果提供的資訊未指出不尋常的狀況,請嘗試在 ntoskrnl 設定 斷點!KiSwapThread 可判斷處理器是否卡在一個進程中,或是否仍在排程其他進程。 如果未停滯,請在 NtReadFile 等常見函式中設定斷點,以判斷電腦是否停滯在特定程式碼路徑中。