Mozilla's getting a new look. What do you think? https://mzl.la/brandsurvey

WinDbg でスタックトレースを得るには

導入

クラッシュやハングが起きた際のスタックトレース(コールスタック)を取得したいけれども、それが特別なクラッシュやハングであるために TalkbackBreakpad では上手くいかない場合がしばしばあります。この記事では、そのような場合に WinDbg を使って Windows 上でスタックトレースを取得する方法を説明します。(Tunderbird や他のプロダクトのスタックトレースを得たい場合は、以下の文章における "Firefox" の箇所を適宜読み替えてください。)

必要なもの

スタックトレースを取得するためには、以下のソフトウェアをインストールしておく必要があります。

Debugging Tools for Windows

Microsoft は Debugging Tools for Windows を無償で配布しており、今回必要となる WinDbg がこの中に含まれています。これを WDK と WinDbg のダウンロード からダウンロードします(64 ビット版の Windows をお使いの方でも 32 ビット版が必要になります)。WinDbg を入手する方法には 2 種類あり、「スタンドアロンの Debugging Tools for Windows (WinDbg)」をインストールするものと、Visual Studio 2013 をインストールした状態で「WDK 8.1 Update」 をインストールするものがあります。無事にインストールが終われば、基本的な設定は以上です。

Firefox の Nightly 版とリリース版について

WinDbg を使用する際には、 デバッグする Firefox のバージョンに合ったデバッグシンボルを Mozilla symbol server から入手する必要があります(次の節で説明します)。デバッグする Firefox には 公式の Nightly ビルド やリリース版を利用できます。

デバッグ

デバッグを始めるにあたり、まずは Firefox が起動していないことを確認し、WinDbg をスタートメニューから起動します。

  • スタンドアロン型の場合: スタート => すべてのプログラム => Debugging Tools for Windows (X86) => WinDbg (X86)
  • WDK 8.1 Update の場合: スタート => すべてのプログラム => Windows Kit => Debugging Tools for Windows (X86) => WinDbg (X86)

WinDbg が起動したら File メニューをクリックし、次に Open Executable... をクリックします。ファイルを選択する画面が開くので、デバッグしたい firefox.exe をプログラムフォルダ(C:\Program Files\Mozilla Firefox など)から探して開きます。

ここで "Command" テキストウィンドウが開くはずです。この画面の上側にはデバッグの出力が、下端にはコマンド入力用のテキストボックスが表示されています(境界をドラッグすれば領域を変更できます)。さて、デバッグを始める前に必要なコマンドがいくつかあるため、これらを Command ウィンドウの入力部へ一行ずつ入力する必要があります。コマンドの入力については次の項で説明します。

補足: すべてのコマンドは書かれている通りに一行ずつ入力しなければなりません。

  • 間違いを避けるには、各行ごとにコピー・ペーストするのが最も簡単でしょう。
  • コマンドの中にはピリオド (.) やパイプ (|) で始まるものがありますが、これらも正しく入力しなければなりません。
  • たとえデバッグ中に何も問題が生じなくとも、デバッグログを提供していただけると、開発者の参考になる場合があります。

デバッグを始める

デバッガの中に Firefox を起動することができたので、次は Mozilla symbol server からデバッグシンボルを WinDbg にダウンロードするための設定を行います。シンボルを読み込むには、以下に示す 3 つのコマンドを一行ずつ Enter を押して入力します(詳しくは Using the Mozilla symbol server を参照してください)。

.sympath SRV*c:\symbols*http://symbols.mozilla.org/firefox;SRV*c:\symbols*http://msdl.microsoft.com/download/symbols
.symfix+ c:\symbols
.reload /f

シンボルのダウンロードが終わるまでしばらく待ちます。約 70MB ほどをダウンロードするため、ネットワークへの接続環境によっては時間がかかるかもしれません。WinDbg  における入力部の横に "Busy" と表示されている場合、シンボルのダウンロード中であることを示しています。

ダウンロードが終わった次は、WinDbg が子プロセスを監視したり、Flash Player に固有のイベントを無視したり、読み込んだモジュールのログを記録させたりするための設定を行います。以下に示す 5 つのコマンドを一行ずつ入力してください(.logopen のコマンドを入力して "Log file could not be opened" と表示された場合、その場所にファイルを書き込む権限がない可能性があります。マイドキュメントなど、書き込み権限のあるパスを指定してください)。

.logopen /t c:\temp\firefox-debug.log
.childdbg 1
.tlist
sxn gp
lm

.tlist のコマンドの出力に firefox.exe が 2 つ以上あった場合、これは既に Firefox が起動していたことを表しています。もしデバッガの起動前に Firefox を終了していないと、有益なデバッグ結果は得られません。

それでは、Debug メニューをクリックし、続いて Go をクリックしてください。Firefox の実行中にコマンドをデバッガへ入力することはできません。Firefox を起動できたら、調べたいクラッシュや問題を再現してみてください。

デバッガにテキストが数行ほど表示された後に Firefox の起動が止まってしまった場合、「ブレークポイント」で止まっていることがあります。コマンドが入力できる状態で、かつクラッシュを示すエラーが表示されていない場合、そのままもう一度 Debug => Go の順にクリックしてください。

ブラウザがクラッシュすると、WinDbg の Command ウィンドウにエラー("Access violation" など)が表示されます。 Firefox がハングしていて、かつデバッガにコマンドを入力できない場合、Debug => Break の順にクリックしてください。ブラウザがクラッシュしたり停止したら、次のステップに進んでください。

クラッシュやハングした後

バグレポートのコメント欄やサポートのリクエストに記載できるよう、デバッグ情報を取得する必要があります。以下に示す 3 つのコマンドを一行ずつ Enter で入力し、スタックトレースやクラッシュ・ハングの解析、読み込まれていたモジュールのログを取得します。

~* kp
!analyze -v -f
lm

これらの処理が終わると、.logopen コマンドで指定した場所に firefox-debug_(デバッグ日時).log のファイルが作成されているはずです。デバッグ情報を開発者のコミュニティに伝えるには、サポートのリクエスト にこのファイルを送信したり、Bugzilla にこのファイルを添付するなどの方法があります。

minidump の作成

問題が生じている箇所を特定する開発者にとって、スタックトレースだけでは不十分であることが時々あります。このとき、開発者は "minidump" や "full memory dump" を求めることがあります。これらのファイルには、プロセスの実行時に関するより詳細な情報が含まれており、開発者に渡す minidump は WinDbg で簡単に作成できます

FAQ

Q: Windows 7 (32-bit or 64-bit) で実行しましたが、WinDbg の Command ウィンドウに 'ntdll32!LdrpDoDebuggerBreak+0x2c' や 'ntdll32!LdrpDoDebuggerBreak+0x30' という例外が表示されてしまいました。どうすればよいですか?

A: 例外メッセージの後ろにそれぞれ 'int 3' と表示されている場合、以下のコマンドを WinDbg で実行してください。

bp ntdll!LdrpDoDebuggerBreak+0x30
bp ntdll!LdrpDoDebuggerBreak+0x2c
eb ntdll!LdrpDoDebuggerBreak+0x30 0x90
eb ntdll!LdrpDoDebuggerBreak+0x2c 0x90

コマンドは一行ごとに Enter で入力してください。64 ビット版 Windows を使用している場合は、"ntdll" の部分を "ntdll32" に置き換えて入力してください。

Q: スタックトレース上の最初の 4 フレームが次のようになりました。

0012fe20 7c90e89a ntdll!KiFastSystemCallRet
0012fe24 7c81cd96 ntdll!ZwTerminateProcess+0xc
0012ff20 7c81cdee kernel32!_ExitProcess+0x62

0012ff34 6000179e kernel32!ExitProcess+0x14

何か間違っているのでしょうか?

A: "Debug child processes also" のチェックボックスを選択しないまま Firefox を起動しています。一旦デバッガをデタッチし、チェックを入れた状態で再度 Firefox を起動してください。

Q: WinDbg で firefox.exe のチェックサムを計算できません。これは通常動作ですか?

A: 通常動作なので無視しても大丈夫です。

Q: WinDbg が "Save information for workspace?" と尋ねてきたときは yes と no のどちらをクリックすればよいのでしょうか?

A: yes をクリックすると、次回のデバッグ時に firefox.exe のシンボルが格納されている場所を指定する手間が省けます。この情報を WinDbg に保存させたくない場合は no をクリックしてください。

Q: 各スレッドに "wow64" と表示されていますが大丈夫でしょうか?

A: いいえ、32 ビット版の Mozilla ソフトウェアを 64 ビット版の WinDbg で起動しています。32 ビット版の WinDbg をダウンロードし、再度インストールし直してください。

トラブルシューティング: シンボルをダウンロードできない

どの手段を使ってもシンボルをダウンロードできない場合、Internet Explorer が オフライン作業 モードになっている可能性があります。これに関する警告は WinDbg にも Visual C++ にも Visual Studio にも表示されることはありません。コマンドラインから symchk.exe を使用してシンボルをダウンロードしようとしても失敗します。この原因は、Microsoft がシンボルファイルをダウンロードする際に、Internet Explorer のインターネット設定・プロキシ設定を用いているからです。Internet Explorer の「ファイル」メニューをクリックし、「オフライン作業」のチェックを外してください。

参考情報

  • symbol server を利用すると、メモリアドレスを読みやすい文字列に変換できます
  • source server を利用すると、メモリアドレスをソースコードの行数に変換できます

ドキュメントのタグと貢献者

タグ: 
 このページの貢献者: hashedhyphen
 最終更新者: hashedhyphen,