Partager via


Débogage des fuites de référence d’alimentation dans WDF

Lorsqu’un pilote WDF (Windows Driver Frameworks) appelle WdfDeviceStopIdle, le framework incrémente le nombre de références d’alimentation de l’appareil. Chaque appel réussi à WdfDeviceStopIdle doit être mis en correspondance par un appel à WdfDeviceResumeIdle pour décrémenter le nombre de références d’alimentation.

À partir de Kernel-Mode Driver Framework (KMDF) 1.15 et User-Mode Driver Framework (UMDF) 2.15, vous pouvez surveiller l’utilisation des références d’alimentation à l’aide des extensions de débogueur !wdfkd.wdfdevice et !wdfkd.wdftagtracker . Cette fonctionnalité étant désactivée par défaut pour des raisons de performances, vous devez l’activer avec l’application WdfVerifier ou en modifiant manuellement la clé de service du pilote.

WdfVerifier

Ouvrez la liste des paramètres de votre pilote et cliquez avec le bouton droit sur le paramètre TrackPower . Choisissez l’option appropriée pour votre scénario.

Pointe Évitez de capturer des traces de pile dans des chemins de code critiques pour les performances.

Capture d’écran de la définition des références d’alimentation du suivi dans WdfVerifier.

Modification du Registre

Vous pouvez également activer la prise en charge du vérificateur et le suivi des références d’alimentation en modifiant la clé de service de votre pilote.

Pour un pilote KMDF :

HKLM\SYSTEM\ControlSet001\Services\<Driver Service Name>\Parameters\Wdf

Pour un pilote 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)

Code du pilote

Les pilotes appellent WdfDeviceStopIdle et WdfDeviceResumeIdle pour gérer l’état de fonctionnement de l’appareil comme suit :

//
// Take power reference
//
status = WdfDeviceStopIdle(device, FALSE);
if (NT_SUCCESS(status)) {
    //
    // Release power reference
    //
    WdfDeviceResumeIdle(device);
}

Débogage avec WdfKd

Pour afficher les références d’alimentation prises sur l’appareil, ainsi qu’un suivi de balise qui montre l’historique des références, utilisez !wdfkd.wdfdevice avec des indicateurs détaillés :

kd> !wdfkd.wdfdevice 0x6d939790 ff
Power references: 0 !wdftagtracker 0x9ea030a8

L’appel de !wdfkd.wdftagtracker affiche l’historique de référence d’alimentation de l’appareil :

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

Spécification d’une balise

Si vous le souhaitez, spécifiez un nom de balise pour faciliter l’identification de références d’alimentation spécifiques. Pour ce faire, utilisez WdfDeviceStopIdleWithTag et WdfDeviceResumeIdleWithTag :

status = WdfDeviceStopIdleWithTag(device, FALSE, (PVOID)'oyeH');
if (NT_SUCCESS(status)) {
    WdfDeviceResumeIdleWithTag(device, (PVOID)'oyeH');
}

Exemple de sortie !wdftagtracker correspondant :

(--) 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