Depuración de fugas de referencia de energía en WDF
Cuando un controlador de Windows Driver Frameworks (WDF) llama a WdfDeviceStopIdle, el marco incrementa el recuento de referencias de energía del dispositivo. Cada llamada correcta a WdfDeviceStopIdle debe coincidir con una llamada a WdfDeviceResumeIdle para reducir el recuento de referencias de energía.
A partir de Kernel-Mode Driver Framework (KMDF) 1.15 y User-Mode Driver Framework (UMDF) 2.15, puede supervisar el uso de referencia de energía mediante las extensiones del depurador !wdfkd.wdfdevice y !wdfkd.wdftagtracker . Esta funcionalidad está deshabilitada de forma predeterminada por motivos de rendimiento, por lo que debe activarla con la aplicación WdfVerifier o editando manualmente la clave de servicio del controlador.
WdfVerifier
Abra la lista de configuración del controlador y haga clic con el botón derecho en la configuración TrackPower . Elija la opción adecuada para su escenario.
Propina Evite capturar seguimientos de pila en rutas de código críticas para el rendimiento.
Edición del Registro
También puede activar la compatibilidad del comprobador y el seguimiento de referencia de energía editando la clave de servicio del controlador.
Para un controlador KMDF:
HKLM\SYSTEM\ControlSet001\Services\<Driver Service Name>\Parameters\Wdf
Para un controlador 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 de controlador
Los controladores llaman a WdfDeviceStopIdle y WdfDeviceResumeIdle para administrar el estado de energía de trabajo del dispositivo de la siguiente manera:
//
// Take power reference
//
status = WdfDeviceStopIdle(device, FALSE);
if (NT_SUCCESS(status)) {
//
// Release power reference
//
WdfDeviceResumeIdle(device);
}
Depuración con WdfKd
Para mostrar las referencias de energía tomadas en el dispositivo, así como un rastreador de etiquetas que muestra el historial de referencia, use !wdfkd.wdfdevice con marcas detalladas:
kd> !wdfkd.wdfdevice 0x6d939790 ff
Power references: 0 !wdftagtracker 0x9ea030a8
Al llamar a !wdfkd.wdftagtracker se muestra el historial de referencia de energía del 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
Especificar una etiqueta
Opcionalmente, especifique un nombre de etiqueta para facilitar la identificación de referencias de energía específicas. Para ello, use WdfDeviceStopIdleWithTag y WdfDeviceResumeIdleWithTag:
status = WdfDeviceStopIdleWithTag(device, FALSE, (PVOID)'oyeH');
if (NT_SUCCESS(status)) {
WdfDeviceResumeIdleWithTag(device, (PVOID)'oyeH');
}
Salida de ejemplo !wdftagtracker correspondiente:
(--) 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