IE が不規則にクラッシュする問題

翻訳元: The Case of the Random IE Crash (英語)

私はバグのあるソフトウェアの影響を受けなくて済む日が来るのを待ち焦がれてはいますが、自分の身に起こったトラブルシューティングが必要な問題を解決すると、良いこともあります。トラブルシューティングの過程では、私の "技法コレクション" に追加して "Case of the Unexplained..." (原因不明の...の問題) というプレゼンテーションやブログ記事で皆さんにご紹介できる新しい手法が見つかることがよくあります。先日も、非常に興味深い事例を無事に解決することができました。この事例は、私が Web ページを読んでいるときに Internet Explorer (IE) がクラッシュしたことから始まります。次に示すのは、その際に表示されたダイアログ ボックスです。

図 1

図 1

私は、システムでもアプリケーションでも、クラッシュが発生したときは必ず調べてみます。保証はできませんが、数分も調べると、クラッシュの原因であるアドオンを示し、最終的には修正方法や解決策も示す手掛かりを発見できることがよくあります。クラッシュしたのがアプリケーションである場合の多くは、問題のあるプロセスがはっきりしているので、Windbg (Windows SDK および Windows DDK に付属する無償の Debugging Tools for Windows パッケージに含まれています) を起動し、プロセスにアタッチして、調査を開始するだけです。

ですが、前述の IE クラッシュのダイアログ ボックスが表示されたときのように、問題のあるプロセスがわかりにくいこともあります。これは、私が実行していたのが IE 8 であり、IE 8 では、各タブがそれぞれ別のプロセスでホストされるマルチプロセス モデルが採用されているためです (下図参照)。

図 2

図 2

私はいつもどおり複数のタブを開いていたので、(親であるブローカー インスタンスに加えて) 実行されていた 4 つの IE プロセスのうち、クラッシュしたのはどれであるかを特定する必要がありました。各プロセスに順にアタッチして問題のあるスレッドを探すという力ずくの方法を使用することもできましたが、さいわい、より簡単かつ直接的に目的のプロセスを特定する方法があります。

プロセスがクラッシュすると、Windows エラー報告 (WER) サービスにより、クラッシュしたプロセスのセッション内で WerFault という固有のプロセスが起動されて、セッションを実行しているユーザーにエラー ダイアログ ボックスが表示され、クラッシュ ダンプ ファイルが生成されます。WER サービスは、WerFault がクラッシュしたプロセスを認識できるように、WerFault のコマンド ラインで、目的のプロセスのプロセス ID (PID) を渡します。Process Explorer を使用すると、コマンド ラインを簡単に表示することができます。私は常に、アイコンをタスク バーの通知領域に表示した状態で Process Explorer を実行しているので、アイコンをクリックして Process Explorer を起動し、次のようにプロセス ツリー内に WER プロセスを見つけました。

図 3

図 3

これをダブルクリックしてプロセスのプロパティ ダイアログ ボックスを開き、コマンド ラインを確認すると、問題のある IE プロセスのプロセス ID がわかりました (下図参照)。

図 4

図 4

これで、探していたプロセスはプロセス 4440 であることがわかったので、Windbg を起動し、F6 キーを押してプロセス選択ダイアログ ボックスを開き、プロセス ID が 4440 の iexplore.exe をダブルクリックしました。Windbg がアタッチされたので、次は、問題のあるスレッドのスタックを調査してバグのあるアドオンの兆しがないかどうか確認できるように、問題のあるスレッドを特定する必要がありました。Windbg には、!analyze コマンドでトリガーできるクラッシュ分析ヒューリスティックが組み込まれており、このヒューリスティックで問題のあるスレッドを特定できる場合もありますが、今回はそうではありませんでした。とはいえ、問題のあるスレッドを見つけるのは、かなり簡単です。

まず、Windbg の [View] メニューから [Process and Threads] ダイアログ ボックスと [Call Stack] ダイアログ ボックスを開き、この 2 つを並べて表示します。目標は、fault、exception、または unhandled という単語が名前に含まれる関数を持つスレッドを見つけることです。これは、[Process and Threads] ウィンドウで各スレッドを選択して Enter キーを押してから、[Call Stack] ウィンドウに表示されるスタックを調べることで、簡単に行うことができます。最初のいくつかのスレッドでこれを行うと、探しているスレッドが見つかりました。これは、問題が発生していることを示す文字列が名前に含まれる関数がこのスレッドのスタックのいたるところにあることからわかります (下図参照)。

図 5

図 5

コール スタックに表示されている DLL はすべてマイクロソフトのものだったので、残念ながら、問題のあるアドオンの特定に関しては、作業は行き詰まったように思われました。ただし、ビューに表示されていないアドオンが存在する可能性があることを示すものが 1 つありました。これは、Windbg は少なくともいくつかのスタック フレームのシンボルを見つけることができなかったので、スタックのレイアウトについて推測しなければならなかったため、どの DLL 内にも存在しないアドレスが表示されているという旨のテキストです (下図参照)。

図 6

図 6

このような事態は、DLL で "フレーム ポインターの省略" (FPO) 呼び出し規則が使用されている場合に起こります。この呼び出し規則を使用すると、DLL のシンボル情報がない場合に、デバッガーが単にフレーム ポインターのチェーンをたどってスタック フレームを見つけることが阻止されます。スレッドが呼び出した関数に返されるアドレスは、(クラッシュを発生させたバグによって上書きされていない限り) スタック上に存在するはずですが、Windbg のヒューリスティックでは、このようなアドレスを見つけることができませんでした。

このような場合は、単語やシンボルの表示用の Windbg コマンドを使用して、見つからないフレーム関数アドレスを探すことができます。32 ビット プロセスのデバッグを行っている場合は dds バージョンのコマンドを使用し、64 ビット プロセスの場合は dqs を使用します。dps ("ポインター シンボルの表示" を表す "Display Pointer Symbols" の略) を使用することもできます。これを使用すると、関数アドレスは 32 ビット プロセスまたは 64 ビット プロセスに合ったサイズとして解釈されます。開始位置としてコマンドに渡す必要があるアドレスは、Windbg がアドレスを見つけられなかった箇所の真上にあるスタック フレームのアドレスです。アドレスを確認するには、コール スタック ダイアログ ボックスの [Addrs] ボタンをクリックします (下図参照)。

図 7

図 7

問題のフレームのアドレスは、2cbc5c8 でした (下図参照)。

図 8

図 8

私はこれを次のように引数として dds に渡し、Enter キーを押しました。

図 9

図 9

結果の 1 ページ目には、予期していた KiUserException 以外には関数は表示されませんでした。私は、別のコマンドを入力せずに Enter キーをもう一度押しました。dds のようなアドレス ベースのコマンドの場合、この操作を行うと、最後に実行したコマンドを続きのアドレスで再実行するよう Windbg に指定したことになるからです。結果の 2 ページ目には、より興味深いものが表示されました。私にとってなじみがない DLL の名前です (下図参照)。

図 10

図 10

Windbg を離れることなくモジュールのバージョン情報を確認する簡単な方法は、lm ("モジュールの一覧表示" を表す "List Modules" の略) コマンドを使用することです。このコマンドの出力により、Yt.dll (DLL の名前は、"!" の左側にあるテキストです) は、Yahoo ツール バーの一部であることがわかりました (下図参照)。

図 11

図 11

クラッシュが発生したのは、数週間前に家庭でのゲーム用のシステムとして買ったばかりのコンピューターだったので、これには驚きました。私が通常、ゲーム用システムにインストールするソフトウェアは、Microsoft Office とゲームだけです。ブラウザーのツール バーは使用せず、もし使用するとしても、当然 Yahoo ではなく Bing のものを使用します。さらに、DLL の日付は、この DLL が 2 年ほど前のものであることを示していました。私は、ソフトウェア インストーラーを使用する際はオプトアウト チェック ボックスを入念に探すようにしているので、おそらくこれが原因ではありません。システムのオーバークロック中に使用した、ビデオ カードのストレス テストや温度プロファイリングを行ういくつかのツールのいずれかをインストールした際に、ツール バーがツールと共にインストールされたのではないかと思われます。私は、ユーザーが拒否の意思表示をしなくてはならないオプトアウト方式のやり方を腹立たしく思っていますが、ユーザーに選択肢すら与えないというやり方についてはなおさら腹立たしく思います。そのため、ここで私はかなり腹が立ちました。コントロール パネルを操作したところ、数分後には、不要な古いツール バーをシステムから削除することができました。

いくつかの便利なトラブルシューティング手法を使用して、5 分もかからずに、発生したクラッシュの原因と思われるものを特定し、システムの信頼性を向上させ、おそらくパフォーマンスも向上させました。こうして、問題は解決されました。

ページのトップへ

共有

ブログにコピー: ([Ctrl] + [C] でコピーしてください)