カーネル デバッガーを使用したカーネル モード メモリ リークの検出
カーネル デバッガーは、カーネル モード メモリ リークの正確な場所を特定します。
プールのタグ付けを有効にする
先に GFlags を使用して、プールのタグ付けを有効にする必要があります。 GFlags は Windows 用デバッグ ツールに含まれています。 GFlags を起動し、[システム レジストリ] タブを選択し、[プールのタグ付けを有効にする] チェック ボックスをオンにして、[適用] を選択します。 この設定を有効にするには、Windows を再起動する必要があります。
Windows Server 2003 以降のバージョンの Windows では、プールのタグ付けは常に有効になっています。
リークのプール タグの特定
どのプール タグがリークに関連しているかを特定するには、通常、このステップで PoolMon ツールを使用するのが最も簡単です。 詳細については、「PoolMon を使用したカーネル モード メモリ リークの検出」を参照してください。
または、カーネルデバッガーを使用して、大量のプール割り当てに関連するタグを検索することもできます。 そのためには、以下の手順に従います。
.reload (モジュールの再読み込み) コマンドを使用して、すべてのモジュールを再読み込みします。
!poolused 拡張機能を使用します。 ページ メモリ使用量に基づいて出力を並べ替えるには、フラグ「4」を含めます。
kd> !poolused 4 Sorting by Paged Pool Consumed Pool Used: NonPaged Paged Tag Allocs Used Allocs Used Abc 0 0 36405 33930272 Tron 0 0 552 7863232 IoN7 0 0 10939 998432 Gla5 1 128 2222 924352 Ggb 0 0 22 828384
どのプール タグがメモリの最大使用量に関連しているかを特定します。 この例では、タグ「Abc」を使用するドライバーが最も多くのメモリ (約 34 MB) を使用しています。 したがって、メモリ リークはこのドライバーにある可能性が最も高そうです。
リークの検出
リークに関連するプール タグを特定したら、以下の手順に従ってリーク自体を特定します。
ed (値の入力) コマンドを使用して、グローバル システム変数 PoolHitTag の値を変更します。 このグローバル変数は、その値に一致するプール タグが使用されるたびにデバッガーが中断する原因となります。
PoolHitTag を、メモリ リークの原因と疑われるタグに設定します。 シンボル解決を速めるために、モジュール名「nt」を指定する必要があります。 タグ値はリトルエンディアン形式 (つまり、逆方向) で入力する必要があります。 プールタグは常に 4 文字であるため、このタグは実際には A-b-c-space であり、単に A-b-c ではありません。 そのため、次のコマンドを使用します。
kd> ed nt!poolhittag ' cbA'
PoolHitTag の現在の値を確認するには、db (メモリの表示) コマンドを使用します。
kd> db nt!poolhittag L4 820f2ba4 41 62 63 20 Abc
プールが Abc タグで割り当てられるか解放されるたびに、デバッガーは中断します。 これらの割り当てまたは解放操作のいずれかでデバッガーが中断するたびに、kb (スタック バックトレースの表示) デバッガー コマンドを使用してスタック トレースを表示します。
この手順を使用して、メモリ内のどのコードが Abc タグでプールを過剰に割り当てているかを特定できます。
ブレークポイントをクリアするには、PoolHitTag をゼロに設定します。
kd> ed nt!poolhittag 0
このタグの付いたメモリが割り当てられている場所が複数あり、それらが自分で作成したアプリケーションまたはドライバー内にある場合は、これらの割り当てのそれぞれに固有のタグを使用するように、ソース コードを変更できます。
プログラムを再コンパイルできないが、コード内の考えられる複数の場所のどれがリークの原因となっているかを特定する場合は、各場所でコードをアンアセンブルし、デバッガーを使用してメモリに常駐するこのコードを編集して、各インスタンスが異なる (以前に使用されていない) プール タグを使用するようにします。 その後、システムを数分間、実行状態にします。 しばらく時間が経過したら、再びデバッガーで中断し、!poolfind 拡張機能を使用して、新しいタグのそれぞれに関連付けられたすべてのプール割り当てを見つけます。