다음을 통해 공유


실패한 프로세스 찾기

실패한 프로세스를 찾기 전에 수락 프로세서의 컨텍스트에 있는지 확인합니다. 허용되는 프로세서를 확인하려면 각 프로세서에서 !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 의 값은 0xFFFFFFFF 아니라 f0823cc0이며 이는 예외가 발생한 프로세서임을 나타냅니다.

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 decodeptes를 사용하여 더 많은 정보를 얻을 수 있습니다.

kd> .cache decodeptes 
kd> !process 0 7 

실패한 프로세스를 식별할 수 있는 경우 !process<process>7 을 사용하여 프로세스의 각 스레드에 대한 커널 스택을 표시합니다. 이 출력은 커널 모드에서 문제를 식별하고 의심 프로세스가 호출하는 내용을 표시할 수 있습니다.

!process 외에도 다음 확장은 응답하지 않는 컴퓨터의 원인을 확인하는 데 도움이 될 수 있습니다.

확장 영향

!준비된

우선 순위에 따라 실행할 준비가 된 스레드를 식별합니다.

!kdext*.locks

소매 시간 초과로 교착 상태가 발생하는 경우 보류된 리소스 잠금을 식별합니다.

!vm

가상 메모리 사용량을 확인합니다.

!poolused

풀 할당의 한 유형이 불균형적으로 큰지 여부를 확인합니다(풀 태그 지정 필요).

!memusage

실제 메모리 상태를 확인합니다.

!heap

힙의 유효성을 확인합니다.

!irpfind

비페이지 풀에서 활성 IRP를 검색합니다.

제공된 정보가 비정상적인 상태를 나타내지 않는 경우 ntoskrnl에서 중단점을 설정해 보세요. KiSwapThread 를 사용하여 프로세서가 한 프로세스에서 중단되었는지 아니면 다른 프로세스를 예약하고 있는지 확인합니다. 중단이 없으면 NtReadFile과 같은 일반적인 함수에서 중단점을 설정하여 컴퓨터가 특정 코드 경로에 갇혀 있는지 확인합니다.