- 1. 概要
- 2. アタッチ
- 3. トレース
- 4. 解析
1. 概要
以前、「Windows Server 2008R2」「Visual Studio 2010」で、「VC++」で書き込みできないメモリ領域に書き込んで、壊していたときの、解析を行いました。
その時のメモは、「Visual Studio 2010 - Debugging Tools for Windows」に記載していますので、そちらをご参照ください。
今回、実は、同じ組み合わせで、「C#」で書いたプログラムが、ハンドルリークを起こしている風に見えるので、それを解析してみました。
本ページは、下記のサイトを参考にさせていただきました。
「WinDbg を使ってプロセスのハンドルリークを調査する方法」
「!htrace コマンドを利用したハンドルリークのデバッグ方法」
2. アタッチ
「WinDbg」を起動して。
「File」→「Attach to a Process...」もしくは F6
現在実行中のプロセスが一覧表示されます。
解析したいプロセスを選択して「OK」
これが、プロセスにアタッチしている状態です。
3. トレース
トレースを開始します。
以下のコマンドを発行。
「!htrace -enable」と入力して Enter
「!htrace -snapshot」と入力して Enter
g Enter もしくは F5 で、実行を継続します。
4. 解析
リークが、発生するまで待ちます。
発生したと判断したら
「Debug」→「break」
(Ctrl+Break では、わたしの環境では止まりませんでした)
「!htrace -diff」と入力して Enter

これで、上のリストボックスのウィンドウに、前回スナップショットをとった時点のハンドルと、現在のハンドルの違いが表示されます。
テキストを選択して、コピー、テキストファイルにペーストすれば、内容をじっくり解析できます。
わたしが実際に、解析した環境では。
--------------------------------------
Handle = 0x0000000000000760 - OPEN
Thread ID = 0x0000000000000f4c, Process ID = 0x0000000000000d34
0x00000000776f9d0a: ntdll!ZwCreateEvent+0x000000000000000a
0x000007fefd452d15: KERNELBASE!CreateEventExW+0x0000000000000065
0x000007fef3a517c7: clr+0x00000000000017c7
0x000007fef2772dcd: mscorlib_ni+0x0000000000422dcd
0x000007fef27284ea: mscorlib_ni+0x00000000003d84ea
0x000007fef0f085b2: System_Core_ni+0x00000000005485b2
0x000007ff00178d7b: +0x000007ff00178d7b
--------------------------------------
Handle = 0x00000000000006ec - OPEN
Thread ID = 0x0000000000000f4c, Process ID = 0x0000000000000d34
0x00000000776f9d0a: ntdll!ZwCreateEvent+0x000000000000000a
0x000007fefd452d15: KERNELBASE!CreateEventExW+0x0000000000000065
0x000007fef3a517c7: clr+0x00000000000017c7
0x000007fef2772dcd: mscorlib_ni+0x0000000000422dcd
0x000007fef27284ea: mscorlib_ni+0x00000000003d84ea
0x000007fef0f085b2: System_Core_ni+0x00000000005485b2
0x000007ff00178d7b: +0x000007ff00178d7b
--------------------------------------
てなハンドルが、山ほど出力されておりまして。
「ZwCreateEvent」「リーク」をキーワードに検索すると。
「.NET Framework 4 アプリ リーク イベント ハンドル - .NET Frameworkn」ってとこにたどり着きまして。
そこによれば。
原因
この問題は、.NET Frameworkがこれらのハンドルに関連付けられているメモリをすぐに解放しないために発生します。 ハンドルは、ガベージ コレクションの実行時にのみ解放されます。 アプリケーションによっては、アプリケーションがマネージド オブジェクトを割り当てることがほとんどないため、ガベージ コレクションはほとんど発生しません。
解決方法
この問題を解決するには、.NET Framework 4 から最新バージョンの .NET Framework 4.5 にアップグレードします。
ですって。
事情があって、この環境では、「.NET Framework」のバージョンをあげられないので、解決できないのであった。
|