查找失败的进程

在查找失败的进程之前,请确保你位于接受处理器的上下文中。 若要确定接受处理器,请在每个处理器上使用 !pcr 扩展,并查找已为其加载异常处理程序的处理器。 接受处理器的异常处理程序具有除 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 扩展是在挂起的系统上查找问题的最佳方式,但有时需要筛选的信息太多。 相反,对于 CSRSS 和其他任何可疑进程,请在进程句柄上使用 !process0 0 和 !process。

使用 !process 0 7 时,许多线程可能标记为“内核堆栈未驻留”,因为这些堆栈已分页。如果这些页面仍在正在转换的缓存中,则可以在 !process 0 7 之前使用 .cache 解码来获取详细信息:

kd> .cache decodeptes 
kd> !process 0 7 

如果可以识别失败的进程,请使用 !process<process>7 显示进程中每个线程的内核堆栈。 此输出可以识别内核模式下的问题,并显示可疑进程正在调用的内容。

除了 !process 之外,以下扩展还有助于确定计算机无响应的原因:

分机 效果

!准备

按优先级顺序标识已准备好运行的线程。

!kdext*.locks

标识任何保留的资源锁,以防出现零售超时死锁。

!Vm

检查虚拟内存使用情况。

!poolused

确定一种类型的池分配是否不成比例地大, (池标记所需的) 。

!memusage

检查物理内存状态。

!堆

检查堆的有效性。

!irpfind

在非分页池中搜索活动 IRP。

如果提供的信息未指示异常情况,请尝试在 ntoskrnl 设置断点!KiSwapThread 用于确定处理器是否卡在一个进程中,或者它是否仍在计划其他进程。 如果未停滞,请在常用函数(如 NtReadFile)中设置断点,以确定计算机是否停滞在特定代码路径中。