.NETアプリのダンプ調査方法について、以下の流れでまとめました。
1. .NETアプリのダンプ取得方法
2. WinDbg.exe(=ダンプ調査に使用するデバッガー)のインストール
3. WinDbgを使った.NETアプリのダンプ調査方法
以下詳細を見てみます。
1. .NETアプリのダンプ取得方法
.NETアプリのダンプを取得する方法は種々あり、以下が有名なツールです。
・タスクマネージャー
・DebugDiag
・procdump
・adplus
ダンプ取得時の注意点は.NETアプリのダンプは、32bitプロセスは32bitダンプを、64bitプロセスは64bitダンプを作成しなくてはいけない点です。(32bitプロセスを64bitダンプで作成した場合にどうなるかは後述します。)
具体的なダンプの取得方法は以前のブログをご参照ください。
・.NETの64bit OS上の32bitプロセスのダンプの取得方法
・DebugDiag v1.2を利用した64bit OS上の32bitダンプの取得方法
2. WinDbg.exe(=ダンプ調査に使用するデバッガー)のインストール
ダンプ調査で使用するWinDbg.exeのインストール方法を記載します。
WinDbgはMicrosoftよりフリーで公開されているデバッガーでDebugging Tools for Windowsというパッケージの一部として公開されております。
以下、Debugging Tools for Windowsをインストールする方法を記述します。
*ここではDebugging Tools for Windowsを単体でインストールする方法を記述しますが、Debugging Tools for WindowsはWDKやSDKのインストール時に一緒にインストールすることもできます。詳細はDownload and Install Debugging Tools for Windowsをご参照ください。
2.1. Microsoftのサイトに行き、"ダウンロード"をクリックし、sdksetup.exeを実行します。
2.2. ウィザードに従ってインストールします。
2.2.1. 以下のスプラッシュウィンドウが表示されます。
2.2.2. インストール先を指定します。
2.2.3. CEIP(匿名のデータをマイクロソフトに送り製品の向上に役立てるプログラム)に参加するかを選択します。
2.2.4. .NET Framework 4.5がインストールされていない際は.NET Framework 4.5をインストールしていないと.NET Framework 4.5のSDKの機能はインストールできない、と注意されます。WinDbgのインストールの際には問題ありません。
2.2.5. 使用許諾を確認します。
2.2.6. Debugging Tools for Windowsを選択します。
2.2.7. 進捗が表示されます。
2.2.8. 終了時の画面です。
2.3. スタートメニューにx86とx64のWinDbgを確認できます。
(本環境はWindows 7 x64です)
3. WinDbgでの.NETアプリのダンプ調査方法
.NETアプリのダンプをWinDbgで調査する方法を記述します。
詳細は後述しますが、流れとしては次のようになります。
ダンプファイルをWinDbgで開く
→.loadby sos clr/mscorwks
→ .symfix c:\sym
→.reload
→コマンドを用いてダンプ調査
以下詳細を見ていきます。
3.1. WinDbgを開きFile -> Open Crash Dumpをクリックします。
.NETダンプ調査時の注意点は32bitダンプは32bitのWinDbgを、64bitダンプは64bitのWinDbgを使用する必要がある点です。
(これを守らなかったらどうなるかは後述します)
以下のような画面になります。(文字列は環境により異なります。)
3.2. .NETダンプを調査するために使用するDLL(sos.dll)をデバッガーにロードします。
.NETダンプを調査するときに使用するsos.dllをデバッガーにロードします。sos.dllをロードするには.loadbyコマンドが便利です。.loadbyコマンドをWinDbgの一番下の空白の部分に入力しEnterを押します。
具体的な使用方法は以下です。.NETのバージョンにより異なります。
.NET 4.0以降:.loadby sos clr
.NET 4.0より前:.loadby sos mscorwks
無事sos.dllがロードできたかは!chainコマンドで確認することができます。
出力にsos.dllがあればOKです。
*.loadbyコマンドの意味は、clr.dll(.NET 4以降)/mscorwks.dll(.NET 4より前)と同じフォルダにあるsos.dllをロードする、という意味です。sos.dllは.NETのバージョンごとに用意されており、たとえばx64の.NET 4のsos.dllは以下にあります。
C:\Windows\Microsoft.NET\Framework64\v4.0.30319
ダンプ調査時に使用するsos.dllはclr.dll/mscorwks.dllと同じバージョンのものを使う必要があり、このようなコマンドを実行する必要があります。
すなわち、ダンプファイル中のclr.dllのバージョンがv4.0.30319だったら.loadby sos clrと実行することで、デバッガーにC:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dllを読み込みます。
*.loadコマンドを使用することもできます。
この際は、引数としてsos.dllのパスを指定します。
例:.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dll
3. シンボルの設定をします。
ダンプの調査時には、シンボルの設定を行うとより詳細にダンプ調査が行えます。
(シンボルの設定をしない場合の挙動については後述します。)
シンボルの設定は.symfixが便利です。具体的な使用方法は以下です。
.symfix <シンボルを保存するパス>
*コマンドの意味は、Microsoftが公開しているシンボルサーバーからシンボルを<シンボルを保存するパス>にダウンロードし、使用する、という意味です。
無事設定できたかどうかは.sympathコマンドを実行すると確認できます。
以下のようにSRV*<フォルダへのパス>*http://msdl.microsoft.com/download/symbolsとなっていればOKです。
自分が作成したアプリのシンボルといったMicrosoftのシンボルサーバーに公開していないシンボルを読み込むには.sympath+が便利です。(この最後の’+’は既存のシンボルの設定に加えて追加でシンボルの設定をする、という意味です。)
シンボルの設定をした後に.reloadコマンドを実行すると、シンボルをデバッガーに読み込みむことができます。
4. その後種々のコマンドを使用して調査していきます。
sos.dllのコマンド一覧は、MSDNで確認できます。本ブログでも随時取り上げていきます。
補足
[32bitプロセスを64bitダンプとして作成した場合にどうなるか?]
32bitプロセスを64bitダンプとして作成すると、ダンプ調査に支障が出ることがあります。
具体例を挙げます。以下は、32bitプロセスのダンプを64bitダンプとして作成したものを32bitのWinDbgで開いたところです。
sos.dllのコマンド!peを実行すると、以下のエラーが出ていることがわかります。
Failed to load data access DLL, 0x80004005
Verify that 1) you have a recent build of the debugger (6.2.14 or newer)
2) the file mscordacwks.dll that matches your version of mscorwks.dll is
in the version directory
3) or, if you are debugging a dump file, verify that the file
mscordacwks_<arch>_<arch>_<version>.dll is on your symbol path.
4) you are debugging on the same architecture as the dump file.
For example, an IA64 dump file must be debugged on an IA64
machine.
You can also run the debugger command .cordll to control the debugger's
load of mscordacwks.dll. .cordll -ve -u -l will do a verbose reload.
If that succeeds, the SOS command should work on retry.
If you are debugging a minidump, you need to make sure that your executable
path is pointing to mscorwks.dll as well.
64bitのWinDbgでダンプを開きsos.dllのコマンド!peを実行しても上記と同じエラーが出ます。
*32bitのWinDbgで開き、wow64extsエクステンションを利用すると一部コマンドが実行できるようになりますが、すべてのコマンドが実行できるようになるわけではありません。
以下はwow64extsを読み込んで!swを実行した後に!peを行った画面です。!peは無事実行できていることがわかります。
`
しかし依然として!clrstackは正常な結果は返しませんでした。
[32bitの.NETダンプを64bitのWinDbgで開いたら/64bitの.NETダンプを32bitで開いたらどうなるか?]
.loadbyコマンドが正常に動きません。32bitのWinDbgが64bitのsos.dllを/64bitのWinDbgが32bitのsos.dllを読みに行こうとするからです。
0:000> .loadby sos clr
The call to LoadLibrary(C:\Windows\Microsoft.NET\Framework\v4.0.30319\sos) failed, Win32 error 0n193
"%1 は有効な Win32 アプリケーションではありません。"
Please check your debugger configuration and/or network access.
.loadで同じバージョン・同じアーキテクチャのsos.dllを読みに行ってコマンドを実行すると、エラーが表示されコマンドの実行ができません。
[シンボルの設定をしなかったらどうなるか?]
3点具体例を挙げてます。
1. "Failed to load data access DLL, 0x80004005"が発生することがある。
sos.dllのコマンドが正常に動作するにはclr.dll/mscorwks.dllのバージョンにマッチしたmscordacwks.dllが必要です。これは通常Microsoftのシンボルサーバーからダウンロードできます。
したがってシンボルの設定をしていないとmscordacwks.dllがダウンロードできず、上記のエラー場発生し、sos.dllのコマンドが実行できないことがあります。
詳細は、“Failed to load data access DLL, 0x80004005” – OR – What is mscordacwks.dll?をご確認ください。
2. !clrstackの結果にソースコードのパス・行が表示されない。
.NET 4のダンプ調査時に自分が作成したアプリのシンボルがあると、!clrstack時にソースコードのパス・行がわかります。
以下がシンボルがある場合です。ソースコードのパス・行が表示されていることがわかります。
以下シンボルがない場合です。ソースコードのパス・行はわかりません。
3. ネイティブコード(アンマネージコード)のデバッグ時に情報が欠如する。
たとえばコールスタックを表示するkコマンドはシンボルがあるときは関数名が表示されますが、シンボルがないとアドレスのみが表示されます。
以下シンボルがない場合です。一番右の行に数字のみ記載されている部分があります。
以下シンボルがある場合です。数字ではなく関数名が表示されていることがわかります。
リンク
・SOS.dll (SOS Debugging Extension)
http://msdn.microsoft.com/en-us/library/bb190764.aspx
・Capturing memory dumps for 32-bit processes on an x64 machine
http://blogs.msdn.com/b/tess/archive/2010/09/29/capturing-memory-dumps-for-32-bit-processes-on-an-x64-machine.aspx
・Tips for successful .NET Debugging With WinDBG
http://blogs.msdn.com/b/dougste/archive/2011/10/31/tips-for-successful-net-debugging-with-windbg.aspx