Windows ミニダンプのスタックの解釈
-
09-06-2019 - |
質問
コンピューター デバッグの複雑さを学び始めたばかりの私としては、Windbg でダンプのスタック テキストを読む方法が一生わかりません。それらをどのように解釈するか、どのように対処するかについてどこから始めればよいかわかりません。誰かこの哀れな魂に指示を与えることができるでしょうか?
ie (実際に私が手元に持っている唯一のダンプ)
>b69dd8f0 bfa1e255 016d2fc0 89efc000 00000040 nv4_disp+0x48b94 b69dd8f4 016d2fc0 89efc000 00000040 00000006 nv4_disp+0x49255 b69dd8f8 89efc000 00000040 00000006 bfa1dcc0 0x16d2fc0 b69dd8fc 00000000 00000006 bfa1dcc0 e1e71018 0x89efc000
問題が Nvidia ディスプレイ ドライバーに関係していることはわかっていますが、私が知りたいのは実際にスタックを読み取る方法です (たとえば、b69dd8f4 とは何ですか?) :-[
解決
まず、適切なシンボルを設定する必要があります。シンボルを使用すると、メモリ アドレスと関数名を一致させることができます。これを行うには、シンボルのローカル キャッシュを保存するローカル フォルダーをマシンに作成する必要があります (例:C:\シンボル)。次に、シンボルサーバーのパスを指定する必要があります。これを行うには、次の場所に移動するだけです。[ファイル] > [シンボル ファイル パス] に移動し、次のように入力します。
SRV*c:\symbols*http://msdl.microsoft.com/download/symbols
シンボルを正しく設定する方法について詳しくは、こちらをご覧ください。 ここ.
シンボル サーバーを適切に構成したら、次の場所からミニダンプを開くことができます。[ファイル] > [クラッシュ ダンプ] を開きます。
ミニダンプを開くと、ダンプの生成時に実行されていたスレッドがコマンド ラインの左側に表示されます。このスレッドが何を実行していたのかを確認したい場合は、次のように入力します。
kpn 200
初めて実行する場合は、必要なパブリック Microsoft 関連のシンボルをダウンロードする必要があるため、時間がかかる場合があります。すべてのシンボルがダウンロードされると、次のようなものが得られます。
01 MODULE!CLASS.FUNCTIONNAME1(...)
02 MODULE!CLASS.FUNCTIONNAME2(...)
03 MODULE!CLASS.FUNCTIONNAME3(...)
04 MODULE!CLASS.FUNCTIONNAME4(...)
どこ:
- 最初の数字:フレーム番号を示します
- モジュール:コードを含む DLL
- クラス:(C++ コードのみ) コードを含むクラスが表示されます。
- 機能名:呼び出されたメソッド。正しいシンボルを持っている場合は、パラメーターも表示されます。
次のようなものも表示されるかもしれません
01 MODULE!+989823
これは、この DLL に適切なシンボルがないため、メソッド オフセットのみを確認できることを示します。
では、コールスタックとは何でしょうか?
次のコードがあると想像してください。
void main()
{
method1();
}
void method1()
{
method2();
}
int method2()
{
return 20/0;
}
このコードでは、method2 は基本的に 0 で除算しようとしているため例外をスローし、これによりプロセスがクラッシュします。これが発生したときにミニダンプを取得すると、次のコールスタックが表示されます。
01 MYDLL!method2()
02 MYDLL!method1()
03 MYDLL!main()
このコールスタックから、「main」が「method1」を呼び出し、その後「method2」を呼び出して失敗したことがわかります。
あなたの場合、このコールスタックがあります(これは「kb」コマンドを実行した結果だと思います)
b69dd8f0 bfa1e255 016d2fc0 89efc000 00000040 nv4_disp+0x48b94
b69dd8f4 016d2fc0 89efc000 00000040 00000006 nv4_disp+0x49255
b69dd8f8 89efc000 00000040 00000006 bfa1dcc0 0x16d2fc0
b69dd8fc 00000000 00000006 bfa1dcc0 e1e71018 0x89efc000
最初の列は子フレーム ポインターを示し、2 番目の列は実行中のメソッドのリターン アドレスを示し、次の 3 つの列はメソッドに渡された最初の 3 つのパラメーターを示し、最後の部分は DLL 名 (nv4_disp) です。および実行されているメソッドのオフセット (+0x48b94)。シンボルがないため、メソッド名を確認できません。NVIDIA がシンボルへのパブリック アクセスを提供しているとは思えないので、ここからは多くの情報は得られないと思います。
「kpn 200」を実行することをお勧めします。これにより、完全なコールスタックが表示され、このクラッシュの原因となったメソッドの起源を確認できる可能性があります (Microsoft DLL の場合は、ここで説明した手順に適切なシンボルが含まれているはずです)。
少なくとも、これが NVIDIA のバグに関連していることはわかっています ;-) このドライバーの DLL を最新バージョンにアップグレードしてみてください。
WinDBG のデバッグについてさらに詳しく知りたい場合は、次のリンクをお勧めします。
他のヒント
スタック トレースの解釈に関する非常に優れたチュートリアルがここから入手できます。
http://www.codeproject.com/KB/debug/cdbntsd2.aspx
ただし、そのようなチュートリアルであっても、適切なシンボルが利用可能またはロードされていない状態でスタック ダンプを解釈することは非常に困難 (またはほぼ不可能) になる可能性があります。
読み取ろうとしているスタックの例を含めると役立つ場合があります。良いヒントは、スタックに表示されているすべてのモジュールに対して正しいデバッグ シンボルがあることを確認することです。これには OS 内のモジュールのシンボルが含まれており、Microsoft はシンボル サーバーを公開しています。