Suchen des fehlgeschlagenen Prozesses
Bevor Sie den fehlgeschlagenen Prozess finden, stellen Sie sicher, dass Sie sich im Kontext des akzeptierten Prozessors befinden. Um den akzeptierten Prozessor zu ermitteln, verwenden Sie die !pcr-Erweiterung auf jedem Prozessor, und suchen Sie nach dem Prozessor, für den ein Ausnahmehandler geladen wurde. Der Ausnahmehandler des akzeptierten Prozessors hat eine andere Adresse als 0xFFFFFFFF.
Da beispielsweise die Adresse von NtTib.ExceptionList auf diesem Prozessor 0xFFFFFFFF ist, ist dies nicht der Prozessor mit dem fehlgeschlagenen Prozess:
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:
Die Ergebnisse für Prozessor 1 unterscheiden sich jedoch ziemlich. In diesem Fall ist der Wert von NtTib.ExceptionList f0823cc0, nicht 0xFFFFFFFF, was angibt, dass dies der Prozessor ist, für den die Ausnahme aufgetreten ist.
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:
Wenn Sie sich im richtigen Prozessorkontext befinden, zeigt die !process-Erweiterung den derzeit ausgeführten Prozess an.
Die interessantesten Teile des Prozessabbilds sind:
Die Zeiten (ein hoher Wert gibt an, dass der Prozess der Täter sein kann).
Die Handleanzahl (dies ist die Zahl in Klammern nach ObjectTable im ersten Eintrag).
Der Threadstatus (viele Prozesse haben mehrere Threads). Wenn der aktuelle Prozess im Leerlauf ist, ist es wahrscheinlich, dass die Maschine wirklich im Leerlauf ist oder aufgrund eines ungewöhnlichen Problems hängen bleibt.
Obwohl die Verwendung der Erweiterung !process 0 7 die beste Möglichkeit ist, das Problem auf einem hängenden System zu finden, ist es manchmal zu viele Informationen zum Filtern. Verwenden Sie stattdessen einen !Prozess 0 0 und dann einen !-Prozess auf dem Prozesshandle für CSRSS und andere verdächtige Prozesse.
Bei Verwendung eines !-Prozesses 0 7 sind viele der Threads möglicherweise als "Kernelstapel nicht resident" gekennzeichnet, da diese Stapel ausgelagert werden. Wenn sich diese Seiten noch im Cache befinden, der sich im Übergang befindet, können Sie weitere Informationen mithilfe einer CACHE-Decodierung vor !process 0 7 abrufen:
kd> .cache decodeptes
kd> !process 0 7
Wenn Sie den fehlerhaften Prozess identifizieren können, verwenden Sie !Process <Process> 7, um die Kernelstapel für jeden Thread im Prozess anzuzeigen. Diese Ausgabe kann das Problem im Kernelmodus identifizieren und erkennen, was der verdächtige Prozess aufruft.
Zusätzlich zu !process können die folgenden Erweiterungen helfen, die Ursache eines nicht reagierenden Computers zu bestimmen:
Erweiterung | Effekt |
---|---|
Identifiziert die Threads, die zur Ausführung bereit sind, in der Reihenfolge der Priorität. |
|
Identifiziert alle gehaltenen Ressourcensperren, falls es einen Deadlock mit Einzelhandelstimeouts gibt. |
|
Überprüft die Auslastung des virtuellen Speichers. |
|
Bestimmt, ob eine Art von Poolzuordnung unverhältnismäßig groß ist (Pooltagging erforderlich). |
|
Überprüft den Status des physischen Speichers. |
|
Überprüft die Gültigkeit des Heaps. |
|
Durchsucht nicht seitenseitigen Pool für aktive IRPs. |
Wenn die bereitgestellten Informationen keine ungewöhnliche Bedingung angeben, versuchen Sie, einen Haltepunkt bei ntoskrnl festzulegen! KiSwapThread , um festzustellen, ob der Prozessor in einem Prozess hängen bleibt oder ob er noch andere Prozesse plant. Wenn sie nicht hängen bleibt, legen Sie Haltepunkte in allgemeinen Funktionen wie NtReadFile fest, um zu bestimmen, ob der Computer in einem bestimmten Codepfad hängen bleibt.