Depurando vazamentos de referência de energia no WDF
Quando um driver WDF (Estruturas de Driver do Windows) chama WdfDeviceStopIdle, a estrutura incrementa a contagem de referência de energia do dispositivo. Cada chamada bem-sucedida para WdfDeviceStopIdle deve ser correspondida por uma chamada para WdfDeviceResumeIdle para diminuir a contagem de referência de energia.
Começando no KMDF (Kernel-Mode Driver Framework) 1.15 e User-Mode Driver Framework (UMDF) 2.15, você pode monitorar o uso da referência de energia usando as extensões de depurador !wdfkd.wdfdevice e !wdfkd.wdftagtracker . Essa funcionalidade é desabilitada por padrão por motivos de desempenho, portanto, você precisa ativá-la com o aplicativo WdfVerifier ou editando manualmente a chave de serviço do driver.
WdfVerifier
Abra a lista de configurações do driver e clique com o botão direito do mouse na configuração TrackPower . Escolha a opção apropriada para seu cenário.
Ponta Evite capturar rastreamentos de pilha em caminhos de código críticos ao desempenho.
Editando o Registro
Você também pode ativar o suporte do Verificador e o acompanhamento de referência de energia editando a chave de serviço do driver.
Para um driver KMDF:
HKLM\SYSTEM\ControlSet001\Services\<Driver Service Name>\Parameters\Wdf
Para um driver UMDF:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WUDF\Services\<Driver Service Name>\Parameters\Wdf
(REG_DWORD) VerifierOn = 0x1
(REG_DWORD) TrackPower = 0x0 (disabled)
= 0x1 (capture tick count, file name, line number)
= 0x2 (capture tick count, file name, line number, and stack traces)
Código do driver
Os drivers chamam WdfDeviceStopIdle e WdfDeviceResumeIdle para gerenciar o estado de energia de trabalho do dispositivo da seguinte maneira:
//
// Take power reference
//
status = WdfDeviceStopIdle(device, FALSE);
if (NT_SUCCESS(status)) {
//
// Release power reference
//
WdfDeviceResumeIdle(device);
}
Depuração com WdfKd
Para exibir as referências de energia feitas no dispositivo, bem como um rastreador de marcas que mostra o histórico de referência, use !wdfkd.wdfdevice com sinalizadores detalhados:
kd> !wdfkd.wdfdevice 0x6d939790 ff
Power references: 0 !wdftagtracker 0x9ea030a8
Chamar o !wdfkd.wdftagtracker mostra o histórico de referência de energia do dispositivo:
kd> !wdftagtracker 0x9ea030a8
Reference and Release History:
# (showing most recent first; refcount is approximate in multi-threaded scenarios)
## 3 entries, history depth is 25
(--) 0 ref: Tag '....' at Time 0x1331e ticks
## path\to\your\driver\code.c @ 374
(++) 1 refs: Tag '....' at Time 0x1331e ticks
## path\to\your\driver\code.c @ 372
(++) Initial Tag '....' at Time 0x12c9a ticks
Especificando uma marca
Opcionalmente, especifique um nome de marca para facilitar a identificação de referências de energia específicas. Para fazer isso, use WdfDeviceStopIdleWithTag e WdfDeviceResumeIdleWithTag:
status = WdfDeviceStopIdleWithTag(device, FALSE, (PVOID)'oyeH');
if (NT_SUCCESS(status)) {
WdfDeviceResumeIdleWithTag(device, (PVOID)'oyeH');
}
Saída de exemplo do !wdftagtracker correspondente:
(--) 0 ref: Tag 'Heyo' at Time 0x24e40 ticks
## path\to\your\driver\code.c @ 374
(++) 1 refs: Tag 'Heyo' at Time 0x24e40 ticks
## path\to\your\driver\code.c @ 372
(++) Initial Tag '....' at Time 0x12c9a ticks