Share via


不要なシンボルのデバッガー検索の回避

最終更新:

  • 2007 年 5 月 27 日

あなたがドライバーのデバッグ中にブレークポイントに到達するのは、自身が所有しておらず、手元のデバッグ タスクには何の関係もないドライバーのシンボルの読み込みを試みている間に、デバッガーが非常に長い間一時停止するだけのときです。 何が起きているのでしょうか。

既定では、シンボルは必要に応じてデバッガーによって読み込まれます。 (これは、シンボルの遅延読み込みまたはシンボルの遅延の読み込みと呼ばれます)。デバッガーは、シンボルの表示を呼び出すコマンドを実行するたびに、シンボルを検索します。 これは、現在のスタック フレームに存在しない関数パラメーターやローカル変数など、現在のコンテキストで有効でないウォッチ変数を設定した場合に、ブレークポイントで発生する可能性がありますが、これはコンテキストが変更されると無効になるためです。 また、シンボル名を誤って入力したり、無効なデバッガー コマンドを実行したりするだけでも、発生する可能性があります。このような状況でも、デバッガーは一致するシンボルの検索を開始します。

なぜそれほど時間がかかるのでしょうか。 これは、シンボル名が修飾されているか非修飾であるかによって異なります。 修飾されたシンボル名の前に、シンボル (myModule!myVar など) を含むモジュールの名前が付けられます。 非修飾のシンボル名では、モジュール名 (myOtherVar など) は指定されません。

修飾名の場合、デバッガーは指定されたモジュール内のシンボルを検索し、モジュールがまだ読み込まれていない場合は、モジュールを読み込みます (モジュールが存在し、シンボルが含まれている場合)。 これはかなりすぐに起こります。

非修飾名の場合、デバッガーはどのモジュールにシンボルが含まれているかを「認識」しないため、すべてのモジュール内を調べなければなりません。 まず、デバッガーはすべての読み込まれたモジュール内にシンボルがないかをチェックし、読み込まれたモジュール内のシンボルと一致しない場合は、読み込んでいないモジュールをすべて読み込んだ後に検索を続行します。その際、ダウンストリーム ストアから開始し、シンボル サーバーで終了します (シンボル サーバーを使用している場合)。 明らかに、これにはかなり時間がかかる場合があります。

非修飾シンボルの自動読み込みを防ぐ方法

SYMOPT_NO_UNQUALIFIED_LOADS オプションで、非修飾シンボルの検索時のデバッガーによるモジュールの自動読み込みの有効/無効を切り替えることができます。 SYMOPT_NO_UNQUALIFIED_LOADS が有効に設定され、デバッガーが非修飾シンボルとの一致を試みると、デバッガーは既に読み込まれているモジュールのみを検索し、目的のシンボルと一致しない場合は検索を停止します。読み込んでいないモジュールを読み込んで検索を続行することはしません。 このオプションは、修飾名の検索には影響しません。

SYMOPT_NO_UNQUALIFIED_LOADS は既定でオフになっています。 このオプションを有効にするには、-snul コマンド ライン オプションを使用するか、デバッガーの実行中に .symopt+0x100 または .symopt-0x100 を使用してオプションをそれぞれオンまたはオフにします。

SYMOPT_NO_UNQUALIFIED_LOADS の効果を確認するには、次の実験を試してください。

  1. -n コマンド ライン オプションを使用してノイズの多いシンボルの読み込み (SYMOPT_DEBUG) を有効にするか、デバッガーが既に実行されている場合は、.symopt+0x80000000 または !sym noisy デバッガー拡張コマンドを使用します。 SYMOPT_DEBUG は、デバッガーにシンボルの検索に関する情報 (読み込まれる各モジュールの名前やデバッガーがファイルを見つけられない場合はエラー メッセージなど) を表示するように指示します。
  2. デバッガーに存在しないシンボルを評価するように指示します (?asdasdasd 型など)。 存在しないシンボルを検索するときに、デバッガーは多数のエラーを報告してくるはずです。
  3. .symopt+ 0x100 を使用して、SYMOPT_NO_UNQUALIFIED_LOADS を有効にします。
  4. ステップ 2 を繰り返します。 デバッガーは、存在しないシンボルがないか、読み込み済みモジュールのみを検索するはずなので、タスクははるかに迅速に完了するはずです。
  5. SYMOPT_DEBUG を無効にするには、.symopt-0x80000000 または !sym quiet デバッガー拡張コマンドを使用します。

デバッガーがシンボルを読み込んで使用する方法を制御するには、いくつかのオプションを使用できます。 シンボル オプションをすべて記載した一覧とその使用方法については、Windows 用デバッグ ツールに付属するオンライン ドキュメントの「シンボル オプションの設定」を参照してください。 Windows 用デバッグ ツール パッケージの最新リリースは、Web から無料でダウンロードできます。または、パッケージを Windows DDK、プラットフォーム SDK、またはカスタマー サポート診断 CD からインストールすることもできます。

どうすればよいでしょうか。

  • シンボル検索を高速化するには、可能な限りブレークポイントとデバッガー コマンドで修飾名を使用します。 既知のモジュールのシンボルを表示するには、モジュール名で修飾します。シンボルの場所がわからない場合は、非修飾名を使用します。 ローカル変数と関数引数の場合は、モジュール名として $ を使用します ($!MyVar など)。
  • シンボルの読み込みが遅い原因を診断するには、-n コマンド ライン オプションを使用してノイズの多いシンボルの読み込み (SYMOPT_DEBUG) を有効にするか、デバッガーが既に実行されている場合は、.symopt+0x80000000 または !sym noisy デバッガー拡張コマンドを使用します。
  • デバッガーが読み込んでいないモジュール内のシンボルを検索できないようにするには、SYMOPT_NO_UNQUALIFIED_LOADS を有効にします。そのためには、-snul コマンド ライン オプションを使用するか、デバッガーが既に実行されている場合は .symopt+0x100 を使用します。
  • デバッグ セッションに必要なモジュールを明示的に読み込むには、.reloadld などのデバッガー コマンドを使用します。

関連項目

WDK のダウンロード

Windows 用デバッグ ツール

Windows のデバッグの概要