WDF での電源参照リークのデバッグ
Windows Driver Frameworks (WDF) ドライバーが WdfDeviceStopIdle を呼び出すと、フレームワークはデバイスの電源参照数をインクリメントします。 WdfDeviceStopIdle への正常な呼び出しはすべて、電源参照数を減らすため、WdfDeviceResumeIdle の呼び出しと一致している必要があります。
カーネルモード ドライバー フレームワーク (KMDF) 1.15 およびユーザーモード ドライバー フレームワーク (UMDF) 2.15 以降では、!wdfkd.wdfdevice および !wdfkd.wdftagtracker デバッガー拡張機能を使用して電源参照の使用状況を監視できます。 この機能は、パフォーマンス上の理由から既定で無効になっているため、WdfVerifier アプリケーションで、またはドライバーのサービス キーを手動で編集して有効にする必要があります。
WdfVerifier
ドライバーの設定一覧を開き、[TrackPower] 設定を右クリックします。 シナリオに適したオプションを選択します。
ヒント: パフォーマンスが重要ななコード パスでスタック トレースをキャプチャしないようにします。
レジストリ編集
ドライバーのサービス キーを編集して、検証ツールのサポートと電源参照の追跡を有効にすることもできます。
KMDF ドライバーの場合:
HKLM\SYSTEM\ControlSet001\Services\<Driver Service Name>\Parameters\Wdf
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)
ドライバー コード
ドライバーは、WdfDeviceStopIdle と WdfDeviceResumeIdle を呼び出して、デバイスの動作電源状態を次のように管理します。
//
// Take power reference
//
status = WdfDeviceStopIdle(device, FALSE);
if (NT_SUCCESS(status)) {
//
// Release power reference
//
WdfDeviceResumeIdle(device);
}
WdfKd を使用したデバッグ
デバイスで取得された電源参照と、参照履歴を示すタグ トラッカーを表示するには、詳細フラグを指定して !wdfkd.wdfdevice を使用します。
kd> !wdfkd.wdfdevice 0x6d939790 ff
Power references: 0 !wdftagtracker 0x9ea030a8
!wdfkd.wdftagtracker を呼び出すと、デバイスの電源参照履歴が表示されます。
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
タグの指定
必要に応じて、特定の電源参照の識別を容易にするタグ名を指定します。 これを行うには、WdfDeviceStopIdleWithTag と WdfDeviceResumeIdleWithTag を使用します。
status = WdfDeviceStopIdleWithTag(device, FALSE, (PVOID)'oyeH');
if (NT_SUCCESS(status)) {
WdfDeviceResumeIdleWithTag(device, (PVOID)'oyeH');
}
対応する !wdftagtracker サンプル出力:
(--) 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