커널 디버깅을 사용하여 디바이스 기본 사항 안정성 테스트 실패 디버그

일반적인 커널 디버깅 명령을 사용하여 디바이스 기본 사항 안정성 테스트 실패를 디버그하는 방법을 설명합니다.

기호 설정

Microsoft 공용 기호 서버 사이트에서 Windows Hardware Lab Kit 콘텐츠 기호를 찾을 수 있습니다. Microsoft 공용 기호 서버에 대한 자세한 내용은 Microsoft 기호 서버를 사용하여 디버그 기호 파일 얻기를 참조하세요. .sympath(기호 경로 설정) 명령을 실행하여 커널 디버거에서 기호를 설정할 수 있습니다.

예:

이 예제에서 .sympath 명령은 디버거에서 공용 기호 서버 경로를 설정합니다.

.sympath SRV*c:\localsymbols*https://msdl.microsoft.com/download/symbols

!analyze -v

커널 디버거에서 시스템 버그 검사로 인해 발생하는 테스트 실패를 조사할 때 기호를 설정한 후 실행해야 하는 첫 번째 명령은 !analyze입니다. 이 명령은 버그 검사 코드, 버그 검사 이유 및 오류 구성 요소를 보여주는 스택 추적을 식별합니다. 이 명령에 대한 자세한 내용은 !analyze 사용을 참조하세요.

테스트 프로세스의 스택 추적 검사

디바이스 기본 사항 안정성 테스트는 테스트 컴퓨터에서 Te.ProcessHost.exe 또는 Te.exe로 실행되는 경우가 많습니다. 시스템 버그 검사 또는 테스트 중단을 조사할 때 이러한 테스트 프로세스에서 스택 추적을 검토하는 것이 유용합니다. 버그 검사의 경우 스택 추적은 충돌 시 테스트 중인 테스트 사례를 식별하는 데 도움이 될 수 있습니다. 테스트 중단의 경우 스택 추적은 테스트가 진행되지 않도록 하는 모든 테스트 스레드를 식별합니다.

!process 0 0 확장을 사용하여 테스트 컴퓨터에서 실행 중인 모든 프로세스를 나열하여 테스트 프로세스 EPROCESS 블록 주소를 찾을 수 있습니다.

그런 다음, !process /p /r 확장을 사용하여 테스트 프로세스에서 전체 스택 추적을 가져올 수 있습니다.

!process 확장에 대한 자세한 내용은 !process.process(프로세스 컨텍스트 설정)를 참조하세요.

!process 출력에는 프로세스에서 실행 중인 각 스레드에 대한 틱 수가 포함됩니다. 테스트 중단을 조사할 때 스택에 WDTF 구성 요소가 포함된 틱 수가 높은 스레드(즉, 스택에서 "WDTF"로 시작하는 모듈 이름)를 신중하게 검토해야 합니다. 이러한 스레드로 인해 테스트가 영구적으로 중단되고 시간이 초과되어 결국 실패할 수 있기 때문입니다.

예:

이 예제에서 !process 0 0, !process /p /r!process 확장은 테스트 진행을 방해하는 틱 수가 매우 높은 테스트 스레드를 식별합니다.

!process 0 0 Te.ProcessHost.exe 
    PROCESS fffffa80093c6340
    SessionId: 1 Cid: 1320 Peb: 7f6595b3000 ParentCid: 12a0
    DirBase: 21eee000 ObjectTable: fffff8a0035b0a00 HandleCount: 327. 
    Image: TE. ProcessHost.exe
.process /p /r fffffa80093c6340
!process fffffa80093c6340 


        THREAD fffffa800b2be8c0  Cid 0964.0eac  Teb: 000007f601ba6000 Win32Thread: 0000000000000000 WAIT: (UserRequest) UserMode Non-Alertable
            fffffa800b2a11d0  SynchronizationEvent
            fffffa800b300640  SynchronizationEvent
        Not impersonating
        DeviceMap                 fffff8a0014b9c80
        Owning Process            fffffa800b302940       Image:         TE.exe
        Attached Process          N/A            Image:         N/A
        Wait Start TickCount      210995         Ticks: 405945 (0:01:45:32.782)
        Context Switch Count      51             IdealProcessor: 2             
        UserTime                  00:00:00.015
        KernelTime                00:00:00.015
        Win32 Start Address WDTFInterfaces!TsSingleWorkerThread (0x000007fe3a567f28)
        Stack Init fffff8800eb5edd0 Current fffff8800eb5dee0
        Base fffff8800eb5f000 Limit fffff8800eb59000 Call 0
        Priority 9 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
        Kernel stack not resident.
        Child-SP          RetAddr           Call Site
        fffff880`0eb5df20 fffff803`78b27f7c nt!KiSwapContext+0x76
        (Inline Function) --------`-------- nt!KiSwapThread+0xf4 (Inline Function @ fffff803`78b27f7c)
        fffff880`0eb5e060 fffff803`78aaf4ab nt!KiCommitThreadWait+0x23c
        fffff880`0eb5e120 fffff803`78b257a0 nt!KiWaitForAllObjects+0x3bb
        fffff880`0eb5e3c0 fffff803`78ecb3dc nt!KeWaitForMultipleObjects+0x4ae
        fffff880`0eb5e470 fffff803`78ecb853 nt!ObWaitForMultipleObjects+0x29c
        fffff880`0eb5e980 fffff803`78aff053 nt!NtWaitForMultipleObjects+0xe3
        fffff880`0eb5ebd0 000007fe`45d2315b nt!KiSystemServiceCopyEnd+0x13 (TrapFrame @ fffff880`0eb5ec40)
        00000083`7cdef148 000007fe`430912c6 ntdll!ZwWaitForMultipleObjects+0xa
        00000083`7cdef150 000007fe`368641b5 KERNELBASE!WaitForMultipleObjectsEx+0xe5
        00000083`7cdef430 000007fe`3a566793 WDTFAudioSimpleIoAction!CAudioImpl::RunIO+0x3d1
        00000083`7cdef520 000007fe`3a566ea0 WDTFInterfaces!CSimpleIOEx::PerformIO+0x10f
        00000083`7cdef5b0 000007fe`3a56706b WDTFInterfaces!CSimpleIOExWrap::PerformIO+0x28
        00000083`7cdef5e0 000007fe`3a553fe5 WDTFInterfaces!CMTest_Receiver::Run+0x77
        00000083`7cdefe20 000007fe`3a5578ac WDTFInterfaces!CSimpleIO_MTestEx::ActionThread+0x105
        00000083`7cdefeb0 000007fe`3a567f3e WDTFInterfaces!CMTEXThread::ThreadWorker+0xc
        00000083`7cdefee0 000007fe`4319167e WDTFInterfaces!TsSingleWorkerThread+0x16
        00000083`7cdeff20 000007fe`45d3c3f1 KERNEL32!BaseThreadInitThunk+0x1a
        00000083`7cdeff50 00000000`00000000 ntdll!RtlUserThreadStart+0x1d

컨텍스트를 스레드 및 프레임으로 전환하여 로컬 보기

스택 프레임에서 로컬 변수를 보려면 다음 작업을 수행해야 합니다.

  1. .thread(레지스터 컨텍스트 설정) 명령을 사용하여 컨텍스트를 스레드로 전환합니다.

  2. kn 명령을 사용하여 프레임 번호와 함께 스택을 덤프합니다(스택 및 덤프 로깅 참조).

  3. .frame(로컬 컨텍스트 설정) 명령을 사용하여 프레임 컨텍스트로 전환합니다.

  4. dv(로컬 변수 표시) 명령을 사용하여 로컬을 봅니다.

참고

프라이빗 기호를 사용하여 로컬 변수를 덤프해야 합니다.

예:

이 예제에서는 .thread, kn, .framedv 명령을 사용하여 스택 프레임에서 로컬 변수를 덤프합니다.

3: kd> .thread fffffa8009da7b00
Implicit thread is now fffffa80`09da7b00

3: kd> kn
  *** Stack trace for last set context - .thread/.cxr resets it
# Child-SP          RetAddr           Call Site
00 fffff880`054a03a0 fffff801`05caaf7c nt!KiSwapContext+0x76
01 fffff880`054a04e0 fffff801`05ca8d9f nt!KiCommitThreadWait+0x23c
02 fffff880`054a05a0 fffff801`05f98841 nt!KeWaitForSingleObject+0x1cf
03 fffff880`054a0630 fffff801`061f253d nt!IopCancelAlertedRequest+0x71
04 fffff880`054a0670 fffff801`0604fc5d nt! ?? ::NNGAKEGL::`string'+0x1caaf
05 fffff880`054a0860 fffff801`060552b8 nt!ObpLookupObjectName+0x7a1
06 fffff880`054a0990 fffff801`06066ebe nt!ObOpenObjectByName+0x258
07 fffff880`054a0a60 fffff801`06067609 nt!IopCreateFile+0x37c
08 fffff880`054a0b00 fffff801`05c82053 nt!NtCreateFile+0x79
09 fffff880`054a0b90 000007fa`1a4930fa nt!KiSystemServiceCopyEnd+0x13
0a 00000038`d21bb478 000007fa`0677feef ntdll!NtCreateFile+0xa
0b 00000038`d21bb480 000007fa`0678e9a2 WDTFFuzzTestAction!DPETryOpenDevice+0x2b3
0c 00000038`d21bcde0 000007fa`0678e892 WDTFFuzzTestAction!CWDTFFuzz_MTestImpl::AttemptToOpenSurface+0x66
0d 00000038`d21bce50 000007fa`0678b84c WDTFFuzzTestAction!CWDTFFuzz_MTestImpl::FindAttackSurfaces+0x16e
0e 00000038`d21bf6c0 000007fa`0678a4d9 WDTFFuzzTestAction!CWDTFFuzz_MTestImpl::ActionThread+0x200
0f 00000038`d21bf760 000007fa`1a17167e WDTFFuzzTestAction!ActionThreadStart+0x9
10 00000038`d21bf790 000007fa`1a4ac3f1 KERNEL32!BaseThreadInitThunk+0x1a
11 00000038`d21bf7c0 00000000`00000000 ntdll!RtlUserThreadStart+0x1d

3: kd> .frame b
0b 00000038`d21bb480 000007fa`0678e9a2 WDTFFuzzTestAction!DPETryOpenDevice+0x2b3

3: kd> dv
szName = 0x00000038`d21bce90
bSync = 0n0
ppdevice = 0x00000038`d21bce10
messageBuffer = wchar_t [2048] "Attempting to open device : \DosDevices\root#multiportserial#0000#{05caff94-7b1e-420c-8c70-d8361bc4ee0a}"
oa = struct _OBJECT_ATTRIBUTES

!pnptriage

디바이스 기본 사항 안정성 테스트 중단을 디버그하는 경우 !pnptriage 명령을 사용하여 활성 PNP 스레드를 나열할 수 있습니다. !process 출력에는 시스템에서 실행 중인 각 PNP 스레드에 대한 틱 수가 포함되어 있습니다. 테스트 중단을 조사할 때 틱 수가 많은 스레드는 테스트가 영구적으로 중단되고 시간 초과로 인해 결국 실패할 수 있으므로 신중하게 검토해야 합니다.

드라이버 디버깅 확장명

!drvobj, !devnode, !devobj, !devstack!irp 커널 디버거 확장은 디바이스 기본 사항 안정성 테스트를 실행할 때 발생할 수 있는 드라이버 문제를 디버그할 수 있습니다. 이러한 확장에 대한 자세한 내용은 커널 모드 확장을 참조하세요.

디버거 확장

Windows용 디버깅 도구는 USB, Storage, NDIS, 그래픽, KMDF(Kernel-Mode Driver Framework) 및 UMDF(User-Mode Driver Framework)와 같은 드라이버 유형에 대해 테스트를 실행할 때 발생할 수 있는 오류를 해결하는 데 유용한 추가 디버거 확장과 함께 제공됩니다. 이러한 확장에 대한 자세한 내용은 특수화된 확장을 참조하세요. Windows용 디버깅 도구에 대한 자세한 내용은 Windows용 디버깅 도구 다운로드 및 설치를 참조하세요.

Windows HLK를 사용하여 디바이스 기본 사항 안정성 테스트 문제 해결