シンボルの検証

シンボルの問題は、さまざまな方法で表示できます。 スタックトレースによって、正しくない情報が表示されるか、スタック内の関数の名前が識別されない可能性があります。 または、デバッガーコマンドでモジュール、関数、変数、構造体、またはデータ型の名前を理解できなかった可能性があります。

デバッガーがシンボルを正しく読み込まないと思われる場合は、この問題を調査するために実行できる手順がいくつかあります。

最初に、 lm (List Loaded modules) コマンドを使用して、読み込まれたモジュールの一覧をシンボル情報と共に表示します。 このコマンドの最も便利な形式は次のとおりです。

0:000> lml 

WinDbg を使用している場合は、 Debug |[モジュール ] メニューコマンドを使用すると、この情報も表示されます。

これらの表示に表示されるメモや省略形に特に注意してください。 これらの解釈については、「 シンボルの状態の省略形」を参照してください。

適切なシンボルファイルが表示されない場合は、まず、シンボルパスをチェックします。

0:000> .sympath
Current Symbol Path is: d:\MyInstallation\i386\symbols\retail

シンボルパスが間違っている場合は修正します。 カーネルデバッガーを使用している場合は、ローカルの% WINDIR% がシンボルパスにないことを確認してください。

次に、 . reload (モジュールの再読み込み) コマンドを使用してシンボルを再読み込みします。

0:000> .reload ModuleName 

シンボルパスが正しい場合は、適切な モード を有効にする必要があります。これにより、 dbghelp.dll がどのシンボルファイルを読み込んでいるかを確認できます。 次に、モジュールを再読み込みします。 ノイズモードを有効にする方法については、「 シンボルオプションの設定 」を参照してください。

次に示すのは、Microsoft Windows シンボルの "雑音" の再読み込みの例です。

kd> !sym noisy
kd> .reload nt
 1: Kernel Version 2081 MP Checked
 2: Kernel base = 0x80400000 PsLoadedModuleList = 0x80506fa0
 3: DBGHELP: FindExecutableImageEx-> Looking for D:\MyInstallation\i386\ntkrnlmp.exe...mismatched timestamp
 4: DBGHELP: No image file available for ntkrnlmp.exe
 5: DBGHELP: FindDebugInfoFileEx-> Looking for
 6: d:\MyInstallation\i386\symbols\retail\symbols\exe\ntkrnlmp.dbg... no file
 7: DBGHELP: FindDebugInfoFileEx-> Looking for
 8: d:\MyInstallation\i386\symbols\retail\symbols\exe\ntkrnlmp.pdb... no file
 9: DBGHELP: FindDebugInfoFileEx-> Looking for d:\MyInstallation\i386\symbols\retail\exe\ntkrnlmp.dbg... OK
10: DBGHELP: LocatePDB-> Looking for d:\MyInstallation\i386\symbols\retail\exe\ntkrnlmp.pdb... OK
11: *** WARNING: symbols checksum and timestamp is wrong 0x0036a4ea 0x00361a83 for ntkrnlmp.exe

シンボルハンドラーは、まず、読み込もうとしているモジュール (3 行目と4行目) に一致するイメージを検索します。 イメージ自体は必ずしも必要ではありませんが、正しくないものが存在する場合は、シンボルハンドラーが失敗することがよくあります。 これらの行は、デバッガーが D:\MyInstallation\i386\ntkrnlmp.exeでイメージを検出したが、タイムスタンプが一致しなかったことを示しています。 日付と時刻のタイムスタンプが一致しなかったため、検索は続行されます。 次に、デバッガーは、読み込まれたイメージと一致する、dbg ファイルと .pdb ファイルを検索します。 これらは 6 ~ 10 行です。 11行目は、シンボルが読み込まれたにもかかわらず、画像のタイムスタンプが一致していないことを示しています (つまり、シンボルが間違っています)。

シンボル検索で致命的なエラーが発生した場合は、次の形式のメッセージが表示されます。

ImgHlpFindDebugInfo(00000000, module.dll, c:\MyDir;c:\SomeDir, 0823345, 0) failed

これは、ファイルシステムのエラー、ネットワークエラー、dbg ファイルの破損などの項目が原因で発生する可能性があります。

シンボルの読み込みエラーの診断

ノイズモードの場合、シンボルファイルを読み込むことができないときに、デバッガーがエラーコードを出力することがあります。 Dbg ファイルのエラーコードは、winerror.h に記載されています。 .Pdb エラーコードは別のソースから取得され、最も一般的なエラーはプレーンテキストで印刷されます。

Winerror.h からの dbg ファイルの一般的なエラーコードを次に示します。

0xB
ERROR_BAD_FORMAT

0x3
ERROR_PATH_NOT_FOUND

0x35
ERROR_BAD_NETPATH

ネットワークエラーのため、シンボルファイルを読み込めない可能性があります。 ERROR_BAD_FORMAT または ERROR_BAD_NETPATH が表示され、ネットワーク上の別のコンピューターからシンボルを読み込んでいる場合は、そのシンボルファイルをホストコンピューターにコピーし、そのパスをシンボルパスに配置してみてください。 その後、シンボルの再読み込みを試みます。

検索パスとシンボルを確認する

"C:\MyDir; c:\SomeDir" を使用して、シンボルパスを表します。 デバッグ情報を検索する場所を指定してください。

Windows の無料ビルドなどのデバッグ情報がバイナリによって削除されている場合は、最初に次の場所にある dbg ファイルを探します。

c:\MyDir\symbols\exe\ntoskrnl.dbg
c:\SomeDir\symbols\exe\ntoskrnl.dbg
c:\MyDir\exe\ntoskrnl.dbg
c:\SomeDir\exe\ntoskrnl.dbg
c:\MyDir\ntoskrnl.dbg
c:\SomeDir\ntoskrnl.dbg
current-working-directory\ntoskrnl.dbg

次に、次の場所にある .pdb ファイルを探します。

c:\MyDir\symbols\exe\ntoskrnl.pdb
c:\MyDir\exe\ntoskrnl.pdb
c:\MyDir\ntoskrnl.pdb
c:\SomeDir\symbols\exe\ntoskrnl.pdb
c:\SomeDir\exe\ntoskrnl.pdb
c:\SomeDir\ntoskrnl.pdb
current-working-directory\ntoskrnl.pdb

Dbg ファイルの検索では、デバッガーは MyDir および SomeDir ディレクトリを検索しますが、.pdb 検索では実行されないことに注意してください。

Windows XP 以降のバージョンの Windows では、任意の dbg シンボルファイルは使用しません。 詳細については 、「シンボルとシンボルファイル 」を参照してください。

一致しないビルド

頻繁に更新されるコンピューターでのデバッグエラーの最も一般的な問題の1つは、異なるビルドのシンボルが一致していないことです。 この問題が発生する3つの一般的な原因として、誤ったビルドのシンボルをポイントし、対応するシンボルなしでプライベートに作成されたバイナリを使用して、マルチプロセッサコンピューターでユニプロセッサハードウェアアブストラクションレベル (HAL) とカーネルシンボルを使用します。 最初の2つは、バイナリとシンボルを一致させるだけです。3番目のは、hal* と ntkrnlmp の名前を hal.dll とに変更することで修正できます。

ターゲットコンピューターにインストールされている Windows のビルドを確認するには、 vertarget (ターゲットコンピューターのバージョンを表示)コマンドを使用します。

kd> vertarget 
Windows XP Kernel Version 2505 UP Free x86 compatible
Built by: 2505.main.010626-1514
Kernel base = 0x804d0000 PsLoadedModuleList = 0x80548748
Debug session time: Mon Jul 02 14:41:11 2001
System Uptime: 0 days 0:04:53 

シンボルのテスト

シンボルのテストはより困難です。 これには、デバッガーでスタックトレースを確認し、デバッグ出力が正しいかどうかを確認する必要があります。 試してみる1つの例を次に示します。

kd> u videoprt!videoportfindadapter2
Loading symbols for 0xf2860000     videoprt.sys ->   videoprt.sys

VIDEOPRT!VideoPortFindAdapter2:
f2856f42 55               push    ebp
f2856f43 8bec             mov     ebp,esp
f2856f45 81ecb8010000     sub     esp,0x1b8
f2856f4b 8b4518           mov     eax,[ebp+0x18]
f2856f4e 53               push    ebx
f2856f4f 8365f400         and     dword ptr [ebp-0xc],0x
f2856f53 8065ff00         and     byte ptr [ebp-0x1],0x0
f2856f57 56               push    esi

Uコマンドは、videoprt.sys で videoportfindadapter 文字列をアセンブル解除します。 プッシュmovなどの一般的なスタックコマンドはスタックに表示されるため、シンボルはデバッガーで適切です。 ほとんどの関数は、基本ポインター (ebp) またはスタックポインター (esp) を使用して、add、sub、または push 操作を開始します。

通常、シンボルが正しく動作していない場合は明らかです。 関数が Glintmpの横に一覧表示されないため、この例では Glintmp.sys にシンボルがありません。

kd> kb
Loading symbols for 0xf28d0000     videoprt.sys ->   videoprt.sys
Loading symbols for 0xf9cdd000      glintmp.sys ->   glintmp.sys
*** ERROR: Symbols could not be loaded for glintmp.sys
ChildEBP RetAddr  Args to Child
f29bf1b0 8045b5fa 00000001 0000a100 00000030 ntoskrnl!RtlpBreakWithStatusInstruction
f29bf1b0 8044904e 00000001 0000a100 00000030 ntoskrnl!KeUpdateSystemTime+0x13e
f29bf234 f28d1955 f9b7d000 ffafb2dc f9b7d000 ntoskrnl!READ_REGISTER_ULONG+0x6
f29bf248 f9cde411 f9b7d000 f29bf2b0 f9ba0060 VIDEOPRT!VideoPortReadRegisterUlong+0x27
00000002 00000000 00000000 00000000 00000000 glintMP+0x1411 [No function listed.] 

このスタックトレースに間違ったビルドシンボルが読み込まれました。 最初の2つの呼び出しに対して関数が一覧表示されていないことに注意してください。 このスタックトレースは、四角形の描画 win32k.sys の問題のように見えます。

1: kd> 
1: kd> kb                      [Local        9:50 AM]
Loading symbols for 0xf22b0000       agpcpq.sys ->   agpcpq.sys
*** WARNING: symbols checksum is wrong 0x0000735a 0x00000000 for agpcpq.sys
*** ERROR: Symbols could not be loaded for agpcpq.sys
Loading symbols for 0xa0000000       win32k.sys ->   win32k.sys
*** WARNING: symbols checksum is wrong 0x00191a41 0x001995a9 for win32k.sys
ChildEBP RetAddr  Args to Child
be682b18 f22b372b 82707128 f21c1ffc 826a70f8 agpCPQ+0x125b [No function listed.]
be682b4c a0140dd4 826a72f0 e11410a8 a0139605 agpCPQ+0x372b [No function listed.]
be682b80 a00f5646 e1145100 e1cee560 e1cee560 win32k!vPatCpyRect1_6x6+0x20b
00000001 00000000 00000000 00000000 00000000 win32k!RemoteRedrawRectangle+0x32 

正しいスタックトレースを次に示します。 AGP440.sys には問題があります。 スタックトレースに最初に表示される項目は、通常、エラーになります。 四角形の win32k.sys エラーが消えていることに注意してください。

1: kd> kb                      [Local        9:49 AM]
ChildEBP RetAddr  Args to Child
be682b18 f22b372b 82707128 f21c1ffc 826a70f8 agpCPQ!AgpReleaseMemory+0x88
be682b30 f20a385c 82703638 e183ec68 00000000 agpCPQ!AgpInterfaceReleaseMemory+0x8b
be682b4c a0140dd4 826a72f0 e11410a8 a0139605 VIDEOPRT!AgpReleasePhysical+0x44
be682b58 a0139605 e1cee560 e11410a8 a00e5f0a win32k!OsAGPFree+0x14
be682b64 a00e5f0a e1cee560 e11410a8 e1cee560 win32k!AGPFree+0xd
be682b80 a00f5646 e1145100 e1cee560 e1cee560 win32k!HeapVidMemFini+0x49
be682b9c a00f5c20 e1cee008 e1cee008 be682c0c win32k!vDdDisableDriver+0x3a
be682bac a00da510 e1cee008 00000000 be682c0c win32k!vDdDisableDirectDraw+0x2d
be682bc4 a00da787 00000000 e1843df8 e1843de8 win32k!PDEVOBJ__vDisableSurface+0x27
be682bec a00d59fb 00000000 e1843de8 00000000 win32k!PDEVOBJ__vUnreferencePdev+0x204
be682c04 a00d7421 e1cee008 82566a98 00000001 win32k!DrvDestroyMDEV+0x30
be682ce0 a00a9e7f e1843e10 e184a008 00000000 win32k!DrvChangeDisplaySettings+0x8b3
be682d20 a008b543 00000000 00000000 00000000 win32k!xxxUserChangeDisplaySettings+0x106
be682d48 8045d119 00000000 00000000 00000000 win32k!NtUserChangeDisplaySettings+0x48
be682d48 77e63660 00000000 00000000 00000000 ntkrnlmp!KiSystemService+0xc9 

便利なコマンドと拡張機能

次のコマンドと拡張機能は、シンボルの問題を追跡する場合に役立ちます。

lm (読み込まれたモジュールの一覧)
すべてのモジュールを一覧表示し、これらのモジュールのすべてのシンボルの読み込み状態を示します。

! dh イメージヘッダー-base
イメージヘッダーベースで始まる読み込み済みイメージのヘッダー情報を表示します。

. 再読み込み/n
すべてのカーネルシンボルを再読み込みします。

。再読み込み [イメージ名]
(CDB または WinDbg のみ)イメージ イメージ名のシンボルを再読み込みします。 イメージ名が指定されていない場合は、すべてのイメージのシンボルを再読み込みします。 (シンボルパスが変更された後にシンボルを再読み込みする必要があります)。

! 記号のノイズ
シンボルの読み込みの詳細モードをオンにします。 これは、モジュールの読み込みに関する情報を取得するために使用できます。 詳細については、「 シンボルオプションの設定 」を参照してください。

. sympath [新しいシンボルパス]
新しいシンボルパスを設定するか、現在のシンボルパスを表示します。 詳細については、「 シンボルパス 」を参照してください。

カーネルシンボルが正しい場合でも、完全なスタックが得られない場合は、次のコマンドも役に立つことがあります。

X *!
これにより、シンボルが現在読み込まれているモジュールが一覧表示されます。 これは、カーネルシンボルが正しい場合に便利です。

。再読み込み/user
これにより、すべてのユーザーモードシンボルの再読み込みが試行されます。 これは、1つのプロセスの実行中にシンボルが読み込まれ、後で別のプロセスで中断が発生した場合に、カーネルデバッグを実行するために必要です。 この場合、このコマンドを実行しない限り、新しいプロセスのユーザーモードシンボルは読み込まれません。

X wdmaud!*start\*
これにより、名前に "start" 文字列が含まれる wdmaud モジュール内のシンボルだけが一覧表示されます。 これは、 wdmaud 内のすべてのシンボルを強制的に再読み込みするが、それらの中に "start" が含まれるシンボルのみを表示するという利点があります。 (つまり、一覧が短くなりますが、"start" が含まれるシンボルが常にいくつかあるので、負荷が行なっているという検証が行えます)。

シンボルを検証するもう 1 つの便利な手法は、コードの組み立て解除です。 ほとんどの関数は、基本ポインター (ebp) またはスタック ポインター (esp または sp) を使用して、add、sub、または push 操作からまります。 シンボルを確認するには、スタック上の一部の関数 (オフセット 0 から) をアンアセンブリング (U 関数) してみてください。

ネットワークとポートの問題

シンボル ファイルとデバッガーへの接続中に問題が発生します。 問題が発生した場合に注意する必要があるいくつかのことを次に示します。

  • デバッグ ケーブルがテスト システム上で接続されている COM ポートを確認します。

  • テスト システムboot.ini設定を確認します。 /debug スイッチを探し、ボー レートと COM ポートの設定を確認します。

  • シンボル ファイルにネットワーク経由でアクセスすると、ネットワークの問題がデバッグに干渉する可能性があります。

  • .dllファイルと .sys ファイル (例: - mga64.sys と mga64.dll) は、シンボル ツリーの適切なディレクトリに分離されていない場合、デバッガーを混乱します。

  • カーネル デバッガーは、ビルド シンボル ファイルをプライベート シンボル ファイルに置き換えるのが常に好きとは限らない。 シンボル パスを再確認し、動作の誤ったシンボル に対して .reloadFileName を実行します。 !dlls コマンドが役に立つ場合があります。

質問と誤解

Q: シンボルが正常に読み込まれたが、スタックが間違っているようです。 デバッガーが壊れていますか?

A: 必ずしも。 問題の最も可能性の高い原因は、シンボルが正しくなされていないことです。 このセクションで説明する手順を実行して、有効なシンボルを読み込んだかどうかを判断します。 これは、一部の機能が有効なシンボルを持つため、想定しません。 たとえば、dd nt!ntbuildnumber または u nt! を実行できる場合 があります。シンボルが正しくない KeInitializeProcess 。 上記の手順を使用して、正しい内容を確認します。

Q: デバッガーは引き続き正しくないシンボルで動作しますか?

A: さあ何とも言えません。 多くの場合、厳密に一致しないシンボルから離れる可能性があります。 たとえば、以前の Windows ビルドのシンボルは、多くの場合、特定のケースで機能しますが、これがいつ機能し、いつ動作しないかについてはルールはありません。

Q: カーネル デバッガーで停止し、ユーザー モード プロセスのシンボルを表示する必要があります。 実行できますか?

A: 主。 カーネル デバッガーでは、プロセスごとにモジュールの読み込みを追跡するのに十分な情報が保持されませんが、妥当な回避策があるため、このシナリオのサポートは不十分です。 ユーザー モード モジュールのシンボルを読み込むには、 .reload -user コマンドを実行 します。 これにより、現在のコンテキストのユーザー モード モジュールが読み込まれます。

Q: 次のメッセージは何を意味しますか?

*** WARNING: symbols checksum and timestamp is wrong 0x0036d6bf 0x0036ab55 for ntkrnlmp.exe

A: これは、 のシンボルが間違ntkrnlmp.exeを意味します。