Compartilhar via


Localizando o processo com falha

Antes de localizar o processo com falha, verifique se você está no contexto do processador que aceita. Para determinar o processador de aceitação, use a extensão !pcr em cada processador e procure o processador para o qual um manipulador de exceção foi carregado. O manipulador de exceção do processador de aceitação tem um endereço diferente de 0xFFFFFFFF.

Por exemplo, como o endereço de NtTib.ExceptionList neste processador é 0xFFFFFFFF, este não é o processador com o processo com falha:

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: 

No entanto, os resultados para o Processador 1 são bem diferentes. Nesse caso, o valor de NtTib.ExceptionList é f0823cc0, não 0xFFFFFFFF, indicando que esse é o processador no qual a exceção ocorreu.

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: 

Quando você está no contexto correto do processador, a extensão !process exibe o processo em execução no momento.

As partes mais interessantes do despejo de processo são:

  • Os tempos (um valor alto indica que o processo pode ser o culpado).

  • A contagem de identificadores (este é o número entre parênteses após ObjectTable na primeira entrada).

  • O status do thread (muitos processos têm vários threads). Se o processo atual estiver ocioso, é provável que a máquina esteja realmente ociosa ou travada devido a algum problema incomum.

Embora usar a extensão !process 0 7 seja a melhor maneira de encontrar o problema em um sistema travado, às vezes é muita informação para filtrar. Em vez disso, use um !process 0 0 e, em seguida, um !process no identificador do processo para CSRSS e quaisquer outros processos suspeitos.

Ao usar um !process 0 7, muitos dos threads podem ser marcados como "pilha de kernel não residente" porque essas pilhas são paginadas. Se essas páginas ainda estiverem no cache que está em transição, você poderá obter mais informações usando um .cache decodeptes antes de !process 0 7:

kd> .cache decodeptes 
kd> !process 0 7 

Se você puder identificar o processo com falha, use !process <process> 7 para mostrar as pilhas de kernel para cada thread no processo. Essa saída pode identificar o problema no modo kernel e revelar o que o processo suspeito está chamando.

Além de !process, as seguintes extensões podem ajudar a determinar a causa de um computador que não responde:

Extensão Efeito

!pronto

Identifica os threads que estão prontos para serem executados, em ordem de prioridade.

!kdext*.locks

Identifica todos os bloqueios de recursos retidos, caso haja um deadlock com tempos limite de varejo.

!Vm

Verifica o uso da memória virtual.

!poolused

Determina se um tipo de alocação de pool é desproporcionalmente grande (marcação de pool necessária).

!memusage

Verifica o status da memória física.

!heap

Verifica a validade do heap.

!irpfind

Pesquisa o pool não paginado em busca de IRPs ativos.

Se as informações fornecidas não indicarem uma condição incomum, tente definir um ponto de interrupção em ntoskrnl! KiSwapThread para determinar se o processador está preso em um processo ou se ainda está agendando outros processos. Se ele não estiver travado, defina pontos de interrupção em funções comuns, como NtReadFile, para determinar se o computador está preso em um caminho de código específico.