会話中の電話がクラッシュする問題

翻訳元: The Case of the Crashed Phone Call (英語)

拙著『Windows Internals』の共著者である David Solomon外部サイトへが Skype の VoIP を使って重要な会話をしていると、その最中に突然音声が乱れました。しばらくすると、システムがブルー スクリーンになってしまいました。30 分後、今度は相手が話している途中で再びシステムがクラッシュしました。会話は実際に収束しており、最初のクラッシュで伝えることができなかった部分は既に説明済みだったので、Dave はその後電話をかけ直して、改めて会話を終わらせることはしませんでしたが、クラッシュの原因は調査することにしました。彼は Debugging Tools for Windows パッケージにある Windbg を起動して、[File (ファイル)] メニューの [Open Crash Dump (クラッシュ ダンプを開く)] をクリックし、[%Systemroot%\Memory.dmp] を選択しました。

あらかじめ Windbg のシンボル設定ダイアログで "srv*c:\symbols*http://msdl.microsoft.com/download/symbols" と入力して、Windbg が Microsoft のパブリック シンボル サーバーを使用するように設定しておいたため、Windbg でクラッシュ ダンプファイルを解析することができました。Windbg はクラッシュ ダンプ ファイルを読み込むと、自動的にヒューリスティック ベースの解析エンジンを実行し、クラッシュを引き起こした原因として最も疑わしいドライバーまたはシステム コンポーネントを特定します。解析結果を見ると、NETw4v64.sys デバイス ドライバーが原因のようです。

図 1

図 1

解析結果の "!analyze -v" というハイパーリンクをクリックすると、Winddbg が解析で使用したデータの一部が出力されます。解析ヒューリスティックは完璧ではないため、Dave は常にこのリンクをクリックして、詳細データを参照しています。特にクラッシュ時のスタック トレースや、クラッシュに関係していそうなメモリ位置などのデータをチェックします。スタック トレースには、KeBugCheckEx というカーネルのクラッシュ関数を呼び出すプロセッサの関数呼び出しのネストが記録されています。このケースでは、スタックの内容は次のようになっています。

図 2

下から上へ、関数呼び出しの発生順に読みます。トレースを見ると、NETw4v64 内のあるコードがカーネル (nt) の KeAcquireSpinLockRaiseToDpc 関数を呼び出したことがわかります。NETw4v64 のスタック フレームは、Windows の一部ではないドライバーが期待するようなテキストの関数名を持っていないため、Microsoft シンボル サーバーにシンボルがありません。そのさらに上のスタック フレームを見ると、KeAcquireSpinLockRaiseToDpc が、KiPageFault をおそらく間接的に呼び出していますが、これは物理メモリ上に存在しない仮想メモリ アドレスを参照したためです。KiPageFault はその後、KeBugCheckEx を呼び出して停止コード A を渡します。解析結果の詳細を見ると、この停止コード IRQL_NOT_LESS_OR_EQUAL であることがわかります。

図 3

図 3

Dave は、「NETw4v64 ドライバーがカーネルを呼び出す際に、無効なメモリ参照をトリガする不正なポインターを渡した」という仮説を立てました。今回のクラッシュの原因は、たとえば他のドライバーによって、無差別的にデータの破損が発生しているためかもしれないと考え、彼は、%Systemroot%\Minidump ディレクトリにある最初のクラッシュのダンプ ファイルを確認してみました。彼が使用している OS の Windows Vista では、システムは常にカーネル メモリ ダンプを古いダンプに上書きして %Systemroot%\Memory.dmp に保存し、minidump という簡易メモリ ダンプを %Systemroot%\Minidump をアーカイブします。2 つ目のメモリ ダンプについても同じ手順を行って、解析エンジンのレポートを確認すると、クラッシュの原因がまったく同一で、不正なメモリ ポインターの値まで同じであることがわかりました。

ヒューリスティックが指摘しているドライバーが誤動作の原因であるという確証を得るには、ダンプを綿密に手作業で解析する必要がありますが、クラッシュを軽減するためにまずやっておくべきことは、疑わしいドライバーをすべて最新バージョンに更新することです。Windows Update では、自動適用されないオプションの更新プログラムがあるので、Dave は %Systemroot%\System32\drivers ディレクトリに移動して、NETw4v64.sys ファイルがどのデバイス用のものであるか調べました。ファイルのプロパティ ダイアログ ボックスを開くと、"Intel Wireless WiFi Link Driver" の Version 11.5 であることがわかりました。

図 4

図 4

Dave はデバイス マネージャーを開き、ネットワーク アダプターのノードを展開して、この Intel ワイヤレス ネットワーク ドライバーと類似した名前のデバイスを見つけました。

図 5

図 5

次に、右クリックしてコンテキスト メニューの [ドライバーの更新] を選択し、ハードウェアの更新ウィザードを起動して、Windows Update で最新のバージョンのチェックを実行しました。残念ながら、最新バージョンがインストールされていました。

図 6

図 6

OEM は、Windows Update ではまだ提供されていないドライバーを自社の Web サイトで公開していることがあるので、Dave は自分が使っているラップトップのブランドである Dell の Web サイトにアクセスして、ドライバーのバージョンをチェックしました。ここでも、見つかったバージョンも、彼が使用しているバージョンと同じものでした。

図 7

図 7

OEM は通常、特定のコスト、電力、サイズ要件に対応したカスタム ハードウェアの製造をハードウェア製造元に依頼します。このため、ハードウェア製造元は、OEM 専用デバイス用のドライバーは提供しておらず、OEM 固有の機能を利用できない汎用ドライバーを提供している可能性があります。それでも、調べる価値はあるため、Dave は Intel の Web サイトにアクセスしました。驚いたことに、期待通りインストールして使用できるドライバーの最新バージョンがあっただけでなく、バージョンは 12.1 で、Dell が使用しているものより新しいメジャー リリース版でした。

図 8

図 8

また Intel では都合よく "ドライバーのみ" のダウンロードを提供していました。サイズは 7 MB で、高付加価値管理ソフトウェアを同梱した Dell サイトのパッケージの 10 分の 1 程度です。

Dave には Intel ドライバーがこのクラッシュの原因であるという確証がないため、この件が解決したと思えませんでしたが、その後クラッシュは再発していません。たとえ Intel ドライバーがクラッシュの根本原因でなかったとしても、Dave は、パフォーマンスや信頼性が改善され、高度な電源管理機能を備えている最新バージョンのドライバーを入手できたことに満足していました。シンプルなダンプ解析の良い一例としてご紹介した今回のケースでは、Windows Update や OEM のサイトでも最新のドライバーが見つからない場合があるという教訓が得ることができました。これで、Dell も Windows Update からユーザーに最新ドライバーを提供してくれるようになれば良いのですが。

公開: 2008 年 12 月 30 日火曜日 10:42 PM 投稿者 markrussinovich (英語)

ページのトップへ

共有

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