スレッドとプロセスの制御

デバッガー エンジンのスレッドとプロセスの概要については、「 スレッドとプロセス」を参照してください。

イベントが発生すると、イベント スレッドとイベント プロセスは、イベントが発生したスレッドとプロセス (オペレーティング システムまたは仮想) に設定されます。 これらは、 それぞれ GetEventThreadGetEventProcess を使用して見つけることができます。

暗黙的なスレッドとプロセス

カーネル モード デバッグでは、デバッガー エンジンは 暗黙的なプロセス を使用して、仮想から物理アドレスへの変換を実行するときに使用する仮想アドレス空間を決定します 。たとえば、 VirtualToPhysical メソッドと ReadVirtual メソッドなどです。 イベントが発生すると、暗黙的なプロセスは現在のプロセスに設定されます。

暗黙的なプロセスは 、SetImplicitProcessDataOffset を使用して変更できます。 暗黙的なプロセスを決定するには、 GetImplicitProcessDataOffset を使用します

メモ ライブ カーネル デバッグ セッション中に ブレークポイント を設定すると、デバッガー エンジンによってブレークポイントの仮想アドレスがターゲットに渡され、ターゲットによってブレークポイントが設定されます。 この場合、ブレークポイントを処理するときにターゲットのプロセス コンテキストのみが使用されます。暗黙的なプロセスの値は関係ありません。

カーネル モード デバッグでは、デバッガー エンジンは 暗黙的なスレッド を使用して、ターゲットのレジスタの一部を決定 します。 これには、プロセッサ スタック ( GetStackOffset を参照)、フレーム オフセット ( GetFrameOffset を参照)、命令オフセット ( GetInstructionOffset を参照) が含まれます。 イベントが発生すると、暗黙的なスレッドは現在のスレッドに設定されます。

暗黙的なスレッドは 、SetImplicitThreadDataOffset を使用して変更できます。 暗黙的なスレッドを特定するには、 GetImplicitThreadDataOffset を使用します

すべてのレジスタが暗黙的なスレッドによって決定されるわけではありません。 暗黙的なスレッドが変更された場合、一部のレジスタは変わりません。

警告 暗黙的なプロセスと暗黙的なスレッドは独立しています。 暗黙的なスレッドが暗黙的なプロセスに属していない場合、暗黙的なスレッドのユーザーとセッションの状態が間違った仮想アドレス空間に存在し、この情報へのアクセスを試みると、エラーが発生したり、正しくない結果が得られます。 カーネル メモリ アドレスはすべての仮想アドレス空間で一定であるため、カーネル メモリにアクセスするときにこの問題は発生しません。 したがって、カーネル メモリ内にある暗黙的なスレッドの情報には、暗黙的なプロセスとは無関係にアクセスできます。

スレッド

エンジン スレッド ID は、デバッガー エンジンによって、各オペレーティング システム スレッドとターゲットの各仮想スレッドを識別するために使用されます。

ターゲットが停止している間、各スレッドには、そのスレッドが属するプロセスに対する相対インデックスもあります。 どのプロセスでも、プロセス内の最初のスレッドのインデックスは 0 で、最後のスレッドのインデックスは、プロセス内のスレッドの数から 1 を引いた数です。 現在のプロセス内のスレッドの数は、 GetNumberThreads を使用して確認できます。 現在のターゲット内のすべてのプロセスのスレッドの合計数は、 GetTotalNumberThreads を使用して確認できます。

現在のプロセス内の 1 つ以上のスレッドのエンジン スレッド ID とシステム スレッド ID は、 GetThreadIdsByIndex を使用してインデックスから見つけることができます。

エンジンは、各スレッドに関するいくつかの情報を保持します。 この情報は、現在のスレッドに対してクエリを実行でき、スレッドのエンジン スレッド ID を検索するために使用できます。

システム スレッド ID (ユーザー モード デバッグのみ)
現在のスレッドのシステム スレッド ID は 、GetCurrentThreadSystemId を使用して確認できます。 特定のシステム スレッド ID に対して、対応するエンジン スレッド ID が GetThreadIdBySystemId を使用して見つかる場合があります。

スレッド環境ブロック (TEB)
現在のスレッドの TEB のアドレスは、 GetCurrentThreadTeb を使用して確認できます。 特定の TEB アドレスに対して、対応するエンジン スレッド ID が GetThreadIdByTeb を使用して見つかる場合があります。 カーネル モード デバッグでは、(仮想) スレッドの TEB は、最後のイベントが発生したときに対応するプロセッサで実行されていたシステム スレッドの TEB です。

データ オフセット
ユーザー モード デバッグでは、(システム) スレッドのデータ オフセットは、そのスレッドの TEB の場所です。 カーネル モード デバッグでは、(仮想) スレッドのデータ オフセットは、最後のイベントが発生したときに対応するプロセッサで実行されていたシステム スレッドの KTHREAD 構造体です。 現在のスレッドのデータ オフセットは、 GetCurrentThreadDataOffset を使用して確認できます。 特定のデータ オフセットに対して、対応するエンジン スレッド ID が GetThreadIdByDataOffset を使用して見つかる場合があります。

システム ハンドル
現在のスレッドのシステム ハンドルは、 GetCurrentThreadHandle を使用して見つけることができます。 特定のシステム ハンドルの場合、対応するエンジン スレッド ID は 、GetThreadIdByHandle を使用して見つけることができます。 カーネル モード デバッグでは、(仮想) プロセスごとに人工ハンドルが作成されます。 このハンドルは、デバッガー エンジン API クエリでのみ使用できます。

プロセス

エンジン プロセス ID は、デバッガー エンジンによって、各オペレーティング システム プロセスとターゲットの各仮想プロセスを識別するために使用されます。

ターゲットが停止している間、各プロセスにはターゲットに対する相対インデックスがあります。 ターゲット内の最初のプロセスのインデックスは 0 で、最後のプロセスのインデックスはターゲット内のプロセスの数から 1 を引いた値です。 現在のターゲット内のプロセスの数は、 GetNumberProcesses を使用して確認できます。

現在のターゲット内の 1 つ以上のスレッドのエンジン プロセス ID とシステム プロセス ID は、 GetProcessIdsByIndex を使用してインデックスから見つけることができます。

エンジンは、各プロセスに関するいくつかの情報を保持します。 この情報は、現在のプロセスに対して照会され、プロセスのエンジン プロセス ID を検索するために使用される場合があります。

システム プロセス ID (ユーザー モード デバッグのみ)
現在のプロセスのシステム プロセス ID は、 GetCurrentProcessSystemId を使用して確認できます。 特定のシステム プロセス ID に対して、対応するエンジン プロセス ID が GetProcessIdBySystemId を使用して見つかる場合があります。

プロセス環境ブロック (PEB)
現在のプロセスの PEB のアドレスは、 GetCurrentProcessPeb を使用して確認できます。 特定の PEB アドレスに対して、対応するエンジン プロセス ID が GetProcessIdByPeb を使用して見つかる場合があります。 カーネル モード デバッグでは、(仮想) プロセスの PEB は、最後のイベントが発生したときに実行されていたシステム プロセスの PEB です。

データ オフセット
ユーザー モード デバッグでは、(システム) プロセスのデータ オフセットは、そのプロセスの PEB の場所です。 カーネル モード デバッグでは、(仮想) プロセスのデータ オフセットは、最後のイベントが発生したときに実行されていたシステム プロセスの KPROCESS 構造体です。 現在のプロセスのデータ オフセットは、 GetCurrentProcessDataOffset を使用して確認できます。 特定のデータ オフセットに対して、対応するエンジン プロセス ID が GetProcessIdByDataOffset を使用して見つかる場合があります。

システム ハンドル
現在のプロセスのシステム ハンドルは、 GetCurrentProcessHandle を使用して確認できます。 特定のシステム ハンドルに対して、対応するエンジン プロセス ID が GetProcessIdByHandle を使用して見つかる場合があります。 カーネル モード デバッグでは、 (仮想) プロセス用に人工ハンドルが作成されます。 このハンドルは、デバッガー エンジン クエリでのみ使用できます。

イベント

ライブ ユーザー モード デバッグでは、スレッドが作成されるか、ターゲットで終了するたびに、作成スレッドと終了スレッドのデバッグ イベントが生成されます。 これらのイベントにより、 IDebugEventCallbacks::CreateThread コールバック メソッドと IDebugEventCallbacks::ExitThread コールバック メソッドが呼び出されます。

ライブ ユーザー モード デバッグでは、プロセスが作成されるか、ターゲットで終了するたびに、作成プロセスと終了プロセスのデバッグ イベントが生成されます。 これらのイベントにより、 IDebugEventCallbacks::CreateProcess コールバック メソッドと IDebugEventCallbacks::ExitProcess コールバック メソッドが呼び出されます。

イベントの詳細については、「イベントの 監視」を参照してください。

追加情報

TEB、KTHREAD、PEB、KPROCESS 構造体など、スレッドとプロセスの詳細については、「 Microsoft Windows Internals by David Solomon and Mark Russinovich」を参照してください。