コンテキストの変更
カーネル モード デバッグでは、多くのプロセス、スレッド、および同時に実行されるユーザー セッションがあります。 therfore、"仮想アドレス0x80002000" や " eax レジスタ" などの語句はあいまいです。 そのような語句を理解できる コンテキスト を指定する必要があります。
デバッガーには、デバッグ中に設定できる 5 つの異なるコンテキストがあります。
セッション コンテキストは、既定のユーザー セッションを示します。
プロセス コンテキストは、デバッガーが仮想アドレスを解釈する方法を決定します。
ユーザー モードのアドレス コンテキストは、ほとんど直接設定されません。 このコンテキストは、プロセス コンテキストを変更すると自動的に設定されます。
レジスタ コンテキストは、デバッガーがレジスタを解釈する方法を決定し、スタック トレースの結果も制御します。 このコンテキストは スレッド コンテキストとも呼ばれますが、その用語は完全には正確ではありません。 明示的なコンテキストは、レジスタ コンテキストの一種でもあります。 明示的なコンテキストを指定した場合、そのコンテキストは現在のレジスタ コンテキストの代わりに使用されます。
ローカル コンテキストは、デバッガーがローカル変数を解釈する方法を決定します。 このコンテキストは 、スコープとも呼ばれます。
セッション コンテキスト
複数のログオン セッションを同時に実行できます。 各ログオン セッションには、独自のプロセスがあります。
!session 拡張機能は、すべてのログオン セッションを表示するか、現在のセッション コンテキストを変更します。
セッションのコンテキストは、セッション番号が "-2" と入力されたときに !sprocess および !spoolused 拡張機能によって使用されます。
セッション コンテキストが変更されると、そのセッションのアクティブ なプロセスにプロセス コンテキストが自動的に変更されます。
プロセス コンテキスト
各プロセスには、仮想アドレスが物理アドレスにマップされる方法を記録する独自のページ ディレクトリがあります。 プロセス内のスレッドが実行中の場合、Windows オペレーティング システムはこのページ ディレクトリを使用して仮想アドレスを解釈します。
ユーザー モードのデバッグ中に、現在のプロセスによってプロセス コンテキストが決定されます。 デバッガー コマンド、拡張機能、デバッグ情報ウィンドウで使用される仮想アドレスは、現在のプロセスのページ ディレクトリを使用して解釈されます。
カーネル モード デバッグ中に、.process (プロセス コンテキストの設定) コマンドを使用して プロセス コンテキストを設定 できます。 このコマンドを使用して、仮想アドレスの解釈に使用するプロセスのページ ディレクトリを選択します。 プロセス コンテキストを設定した後は、アドレスを受け取る任意のコマンドでこのコンテキストを使用できます。 このアドレスにブレークポイントを設定することもできます。 .process コマンドに /i オプションを含めて侵入型デバッグを指定することで、カーネル デバッガーを使用してユーザー空間にブレークポイントを設定することもできます。
カーネル 領域関数でプロセス固有のブレークポイントを使用して、カーネル デバッガーからユーザー モード ブレークポイントを設定することもできます。 戦略的ブレークポイントを設定し、適切なコンテキストが表示されるまで待ちます。
ユーザー モード アドレス コンテキストは、プロセス コンテキストの一部です。 通常、ユーザー モード のアドレス コンテキストを直接設定する必要はありません。 プロセス コンテキストを設定すると、ユーザー モード のアドレス コンテキストは、プロセスの関連ページ テーブルのディレクトリ ベースに自動的に変更されます。
カーネル モード デバッグ中にプロセス コンテキストを設定すると、そのプロセス コンテキストは、別の .process コマンドによってコンテキストが変更されるまで保持されます。 ユーザー モードのアドレス コンテキストは、 .process または .context コマンドによって変更されるまで保持されます。 これらのコンテキストは、ターゲット コンピューターの実行時に変更されず、レジスタ コンテキストまたはローカル コンテキストの変更の影響を受けません。
コンテキストの登録
各スレッドには、独自のレジスタ値があります。 これらの値は、スレッドの実行時に CPU レジスタに格納され、別のスレッドの実行時にメモリに格納されます。
ユーザー モードのデバッグ中、現在のスレッドは通常、レジスタ コンテキストを決定します。 デバッガー コマンド、拡張機能、デバッグ情報ウィンドウ内のレジスタへの参照は、現在のスレッドのレジスタに従って解釈されます。
次のいずれかのコマンドを使用して、ユーザー モード デバッグの実行中に、レジスタ コンテキストを現在のスレッド以外の値に変更できます。
カーネル モード デバッグ中は、次のコマンドを含むさまざまなデバッガー コマンドを使用してレジスタ コンテキストを制御できます。
これらのコマンドは、CPU レジスタの値を変更しません。 代わりに、デバッガーはメモリ内の場所から指定されたレジスタ コンテキストを取得します。 実際には、デバッガーは 保存された レジスタ値のみを取得できます。 (その他の値は動的に設定され、保存されません。 保存された値は、スタック トレースを再作成するのに十分です。
レジスタ コンテキストが設定されると、 k (Display Stack Backtrace) や r (Registers) など、レジスタ値を使用するすべてのコマンドに新しいレジスタ コンテキストが使用されます。
ただし、マルチプロセッサ コンピューターをデバッグする場合は、一部のコマンドを使用してプロセッサを指定できます。 (このようなコマンドの詳細については、「 マルチプロセッサ構文」を参照してください)。コマンドにプロセッサを指定した場合、指定されたプロセッサが現在アクティブなプロセッサであっても、コマンドは現在のレジスタ コンテキストではなく、指定されたプロセッサ上のアクティブ スレッドのレジスタ コンテキストを使用します。
また、レジスタ コンテキストが現在のプロセッサ モード設定と一致しない場合、これらのコマンドは正しくない出力または意味のない出力を生成します。 出力エラーを回避するために、レジスタの状態に依存するコマンドは、レジスタ コンテキストに一致するようにプロセッサ モードを変更するまで失敗します。 プロセッサ モードを変更するには、 .effmach (有効なマシン) コマンドを使用します。
登録コンテキストを変更すると、ローカル コンテキストを変更することもできます。 この方法では、レジスタ コンテキストがローカル変数の表示に影響を与える可能性があります。
アプリケーションの実行、ステップ実行、またはトレースが発生した場合、レジスタ コンテキストはプログラム カウンターの位置に一致するように直ちにリセットされます。 ユーザー モードでは、現在のプロセスまたはスレッドが変更された場合、レジスタ コンテキストもリセットされます。
スタック トレースはスタック ポインター レジスタ (x86 ベースのプロセッサ上の esp ) が指す場所から開始するため、レジスタ コンテキストはスタック トレースに影響します。 レジスタ コンテキストが無効またはアクセスできない値に設定されている場合、スタック トレースを取得できません。
プロセッサ ブレークポイント (データ ブレークポイント) を特定のレジスタ コンテキストに適用するには、 .apply_dbp (データ ブレークポイントをコンテキストに適用) コマンドを 使用します。
ローカル コンテキスト
プログラムが実行されている場合、ローカル変数の意味はプログラム カウンターの場所によって異なります。これは、そのような変数のスコープが定義されている関数のみに拡張されるためです。
ユーザー モードまたはカーネル モードのデバッグを実行する場合、デバッガーはローカル コンテキストとして現在の関数 (スタック上の現在のフレーム) のスコープを使用します。 このコンテキストを変更するには、 .frame (ローカル コンテキストの設定) コマンドを使用するか、[ 呼び出し] ウィンドウで目的のフレームをダブルクリックします。
ユーザー モード デバッグでは、ローカル コンテキストは常に、現在のスレッドのスタック トレース内のフレームです。 カーネル モード デバッグでは、ローカル コンテキストは常に、現在のレジスタ コンテキストのスレッドのスタック トレース内のフレームです。
ローカル コンテキストには、一度に 1 つのスタック フレームのみを使用できます。 他のフレーム内のローカル変数にはアクセスできません。
次のいずれかのイベントが発生した場合、ローカル コンテキストはリセットされます。
プログラムの実行、ステップ実行、トレース
任意のコマンドでスレッド区切り記号 (~) を使用する場合
レジスタ コンテキストに対する変更
!for_each_frame 拡張機能を使用すると、スタック内のフレームごとに 1 回、1 つのコマンドを繰り返し実行できます。 このコマンドは、各フレームのローカル コンテキストを変更し、指定したコマンドを実行し、ローカル コンテキストを元の値に返します。