Debug Diagnostic Tool を利用したクラッシュ時のデバッグ方法

デバッグには大きく分けて二つあります。

ひとつは、ライブデバッグで、もうひとつはポストモーテムデバッグといいます。

ライブデバッグというのは、要は生きているプロセス (プログラム) にデバッガをアタッチして、実行中のプログラムを診断するものです。Visual Studio などで開発しているとき、ちょっと動かして止めて、直して、なんてやることがあると思いますが、あれがライブデバッグです。

ライブデバッグも、Visual Studio のような統合開発環境の中で実施するものと、本番環境で稼働中のプログラムに対して行うものまで、形態はさまざまです。

ポストモーテムデバッグというのは、ポストモーテム (=死後の) という言葉の通り、プログラムが ”死んだ” ときの様子から、その原因を突き止めるものです。代表的な方法は、メモリダンプの採取です。プロセス終了時のダンプを採取して、持ち帰り、それを解析して原因を究明する方法です。

本番環境で稼働中のサーバーで時々発生する問題を解析する場合、よっぽど事情がない限り、ダウンタイムを減らすために、まずはポストモーテムデバッグを選びます。つまり、ダンプを採取して持ち帰り、それを解析するという方向性からはじめます。

非常にクリティカルな問題でも、ダンプをひと目見るだけで問題解決への手がかりをつかめることは、実は少なくありません。これはサーバーに限った話ではなく、例えば、「最近 IE が良く落ちるなぁ」 とか 「あれれ、メールの受信が途中で止まってしまう・・・。どうしてだろう?」 というような身近な例でも良くあることです。IE の例では、落ちるときのダンプを見れば、どのプラグインが悪さをしていたか突き止められる場合が多いでしょうし、ネットワーク系の問題っぽくても、ダンプを見たらアンチウィルスソフトが処理を止めていた、なんて良くあることです。

前フリが、異常に長くなってしまいましたが・・・(汗)

Debug Diagnostic Tool はユーザダンプの取得と解析を自動化するツールです。クラッシュだけでなく、ハングアップ時、とかリソースのリークなどの状況にも対応できる、非常に強力なツールです。

IIS のクラッシュ

IIS が応答を返さない、とか、急に停止してしまう場合、イベントログに次のようなログが残っている場合があります。

詳細を良く見ると次のように書いてあります。

Faulting application w3wp.exe, version 7.0.6001.18000, time stamp 0x47919413, 
faulting module ghttpmod.dll, version 0.0.0.0, time stamp 0x491b2973, 
exception code 0xc0000005, fault offset 0x00001505, process id 0x184c, 
application start time 0x01c94648e52fe240.

このログから w3wp.exe (つまり、IIS のワーカープロセス) がクラッシュして停止したことがわかります。 この時の例外は 0xc0000005 (つまりアクセス違反) であり、問題を起こしたコードは ghttpmod.dll のオフセット 0x00001505。 これだけわかれば、どの関数で問題が発生したのか特定できることはできますが、さすがにパッと見てわかる人はいないでしょう。

ちなみに、0xC0000005 がアクセス違反 (Access Violation, AV) だ、ということは覚えてない方は、 覚えておいてくださいね。これは winnt.h で定義されています。

Debug Diagnostic Tool を利用すると、メモリダンプの取得に加え、その解析もある程度自動化できます。 ここでは、上記のログが記録されているような状況、すなわち、ワーカープロセスがクラッシュするとき (いわゆる「落ちる」ってとき) の状況で、Debug Diagnostic Tool が どのように役に立つのか試してみます。

Debug Diagnostic Tool v1.1 のインストール

当サイト内 Debug Diagnostics Tool 1.1 を参考にインストールを行ってください。

Debug Diagnostic Tool をクラッシュ診断用に設定する

インストールすると、スタートメニューに Debug Diagnostics Tool 1.1 というプログラムグループが作成されます。 その中の、DebugDiag 1.1 を開始します。

すると、以下の画面になりますが、ここではワーカープロセスが落ちる (クラッシュする) という状況がわかっているので、 Crash を選択して次へ行きます。

IIS 関連の調査なら All IIS/COM+ related processes を選んでおきましょう。

オプションは通常特に変更する必要はありません。

上で作ったルールを、アクティブにしましょう。

こんな画面が出てきます。これで、Debug Diagnostic Tool が IIS を監視している状態に入っています。

このように Debug Diagnostic Tool が IIS を監視している状態で、IIS にリクエストを送信して、 問題となっている現象を発生させます。

Debug Diagnostic Tool を用いたユーザーダンプの自動解析

Debug Diagnostic Tool で IIS を監視している最中に、IIS がクラッシュすると、障害発生プロセスの ユーザーダンプが採取されます。下の画面で Userdump Count が 2 になっていますよね? これはユーザーダンプが二つ採取できました、ということです。

念のため補足しますと、ユーザーダンプ というのはメモリダンプのうち、 ユーザーモードのプロセスのダンプを言います。カーネルの情報は含まれていません。

画面のフォルダアイコンをクリックすると、ログディレクトリがエクスプローラで開きます。 確かに2個、ユーザーダンプが採取できています。

このユーザーダンプを、このツールで解析しましょう。Advanced Analysis タブをクリックします。

Add Data Files をクリックして、ユーザーダンプファイルを選択します。

下側のリストに選択したファイルが表示されました。Start Analysis をクリックして、 解析を開始します。

自動的に解析が進み...

下図のようなレポートが表示されます。(画像をクリックすると拡大します)

着目するところは上側の Analysis Summary です。

ここには以下のように書いています。

the assembly instruction at ghttpmod!MyGlobalModule::OnGlobalTraceEvent+75 in C:\aikane\trunk\test\iis\iis05\ghttpmod\chk\ghttpmod.dll has caused an access violation exception (0xC0000005) when trying to read from memory location 0x01b50004 on thread 6.
スレッド 6 上にて、 C:\aikane\trunk\test\iis\iis05\ghttpmod\chk\ghttpmod.dll 内の ghttpmod!MyGlobalModule::OnGlobalTraceEvent+75 にあるアセンブリ命令にて、 メモリ 0x01b50004 番地を読み出そうとしたときに アクセス違反例外が発生しました。

冒頭のイベントログの表示と比べると、ghttpmod.dll のオフセット 0x00001505 という ところが、ghttpmod!MyGlobalModule::OnGlobalTraceEvent+75 となっておりわかりやすくなっています。 (シンボルファイルがない場合は必ずしもこうはなりませんが) また、アクセス違反の理由はイベントログには全くありませんでしたが、Debug Diagnostic Tool の 診断には記載があります。

これはかなり使えると思います。しかも、起動直後の問題でも対応できてますね。ライブデバッグの必要がないなら、 これだけで良さそうです。


関連書籍

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Web/DB プログラミング徹底解説