Partilhar via


Usar a depuração de kernel para depurar falhas de teste de confiabilidade de conceitos básicos do dispositivo

Isso descreve como usar comandos comuns de depuração de kernel para depurar falhas de teste de confiabilidade de conceitos básicos do dispositivo.

Definir símbolos

Você pode encontrar símbolos de conteúdo do Kit de Laboratório de Hardware do Windows no site do Servidor de Símbolos Públicos da Microsoft. Confira Usar o Servidor de Símbolos da Microsoft para obter arquivos de símbolo de depuração para obter mais informações sobre o Servidor de Símbolos Públicos da Microsoft. Você pode definir símbolos no depurador de kernel executando o comando .sympath (Definir Caminho do Símbolo).

Exemplo:

Neste exemplo, o comando .sympath define o caminho do servidor de símbolos públicos no depurador.

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

!analyze -v

Quando você investiga falhas de teste causadas por verificações de bugs do sistema do depurador de kernel, o primeiro comando que você deve emitir depois de definir símbolos é !analyze. Esse comando identifica o código de marcar de bugs, o motivo do bug marcar e o rastreamento de pilha que mostra o componente com falha. Consulte Usando a extensão !analyze para obter mais informações sobre esse comando.

Inspecionar rastreamentos de pilha do processo de teste

Os testes de confiabilidade de conceitos básicos do dispositivo geralmente são executados como Te.ProcessHost.exe ou Te.exe no computador de teste. É útil examinar rastreamentos de pilha desses processos de teste quando você investiga verificações de bugs do sistema ou travamentos de teste. No caso de verificações de bugs, os rastreamentos de pilha podem ajudar a identificar o caso de teste que estava sendo testado no momento da falha. No caso de travamentos de teste, os rastreamentos de pilha identificam os threads de teste que impedem o progresso do teste.

Você pode usar a extensão !process 0 0 para listar todos os processos em execução no computador de teste para localizar o endereço de bloco EPROCESS do processo de teste.

Em seguida, você pode usar a extensão !process /p /r para obter rastreamentos de pilha completos dos processos de teste.

Para obter mais informações sobre a extensão !process , consulte !process e .process (Definir Contexto do Processo).

Observe que !process output contains tick counts for each thread that is running in the process. Quando você investiga travamentos de teste, os threads que têm uma alta contagem de tiques que contêm componentes WDTF na pilha (ou seja, nomes de módulo que começam com "WDTF" na pilha) devem ser revisados cuidadosamente porque esses threads podem fazer com que os testes fiquem permanentemente travados e, eventualmente, falhem devido a um tempo limite.

Exemplo:

Neste exemplo, as extensões !process 0 0, !process /p /r e !process identificam um thread de teste que tem uma contagem de tiques muito alta, o que impede que o teste progrida:

!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

Alternar o contexto para threads e quadros para exibir locais

Para exibir variáveis locais de um registro de pilha, você deve executar as seguintes ações:

  1. Alterne o contexto para o thread usando o comando .thread (Definir Contexto de Registro).

  2. Despeje a pilha junto com números de quadro usando o comando kn (consulte Registro em log de pilha e despejo.

  3. Alterne para o contexto de quadro usando o comando .frame (Definir Contexto Local).

  4. Exiba locais usando o comando dv (Exibir Variáveis Locais).

Observação

Você deve usar símbolos privados para despejar variáveis locais.

Exemplo:

Este exemplo usa os comandos .thread, kn, .frame e dv para despejar variáveis locais de um quadro de pilha:

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

Ao depurar travamentos no teste de Confiabilidade de Conceitos Básicos do Dispositivo, você pode usar o comando !pnptriage para listar threads PNP ativos. Observe que a saída !pnptriage contém contagens de tiques para cada thread PNP em execução no sistema. Quando você investiga travamentos de teste, os threads que têm altas contagens de escala devem ser cuidadosamente revisados porque esses threads podem fazer com que os testes fiquem permanentemente travados e, eventualmente, falhem devido a um tempo limite.

Extensões de depuração de driver

As extensões do depurador de kernel a seguir podem depurar problemas de driver que podem ocorrer quando você executa testes de Confiabilidade de Conceitos Básicos do Dispositivo: !drvobj, !devnode, !devobj, !devstack e !irp. Para obter mais informações sobre essas extensões, consulte Extensões do modo Kernel.

Extensões do depurador

As Ferramentas de Depuração para Windows são fornecidas com extensões adicionais do depurador que são úteis para solucionar problemas de falhas que podem ocorrer quando você executa testes nos seguintes tipos de drivers: USB, Storage, NDIS, Graphics, KMDF (Kernel-Mode Driver Framework) e UMDF (User-Mode Driver Framework). Para obter mais informações sobre essas extensões, consulte Extensões especializadas. Para obter mais informações sobre ferramentas de depuração para Windows, consulte Baixar e instalar ferramentas de depuração para Windows.

Solução de problemas de testes de confiabilidade de conceitos básicos do dispositivo usando o Windows HLK