查找失败的进程
在查找失败的进程之前,请确保处于接受处理器的上下文中。 若要确定接受处理器,请使用 每个处理器上的 !rf 扩展,并查找已加载异常处理程序的处理器。 接受处理器的异常处理程序具有除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:
当处于正确的处理器上下文中时, !进程 扩展将显示当前正在运行的进程。
进程转储最有趣的部分包括:
时间(高值表示进程可能是罪魁祸首)。
句柄计数(这是第一个条目中 ObjectTable 后面的括号中的数字)。
线程状态(许多进程具有多个线程)。 如果当前进程为 “空闲”,则可能是因为计算机确实处于空闲状态,或者由于一些异常问题而挂起。
尽管使用 !process 0 7 扩展是查找挂起系统上问题的最佳方法,但有时信息过多,无法筛选。 请改用 !process 0 0 ,然后在 CSRSS 和其他任何可疑进程的进程句柄上使用一个 !进程 。
使用 !process 0 7 时,许多线程可能会标记为“内核堆栈不驻留”,因为这些堆栈已分页。如果这些页面仍在正在转换的缓存中,则可以在 !process 0 7 之前使用 .cache 解码器获取详细信息:
kd> .cache decodeptes
kd> !process 0 7
如果可以识别失败的进程,请使用 !process <进程> 7 显示进程中每个线程的内核堆栈。 此输出可以识别内核模式下的问题,并显示可疑进程正在调用的内容。
除了 !process,以下扩展还有助于确定无响应计算机的原因:
扩展 | 效果 |
---|---|
按优先级顺序标识已准备好运行的线程。 |
|
标识任何保留的资源锁,以防存在零售超时的死锁。 |
|
检查虚拟内存使用情况。 |
|
确定一种类型的池分配是否不成比例(需要池标记)。 |
|
检查物理内存状态。 |
|
检查堆的有效性。 |
|
在非分页池中搜索活动 IRP。 |
如果提供的信息未指示异常情况,请尝试在 ntoskrnl 处 设置断点!KiSwapThread 用于确定处理器是否停滞在一个进程中,还是仍在计划其他进程。 如果它未卡住,请设置常见函数(如 NtReadFile)中的断点,以确定计算机是否停滞在特定代码路径中。