ご存知かもしれませんが、GDBを使用してコードにブレークポイントを設定し、デバッグのために実行を一時停止できます。
私の質問は、GDBはどのようにプロセスを一時停止し、たとえばi r
を使用してレジスターの内容を表示できるようにするかです。それらのレジスタは、他のOSプロセスによって常に使用されていませんか?どのようにして上書きされないのですか?
コンテンツのスナップショットのみでライブデータではありませんか?
アーキテクチャによって多少異なりますが、重要な点はほぼ一般的に当てはまります。
割り込み処理により、ISRを実行する前にCPUの状態(レジスタを含む)がメモリに保存され、ISRの終了時に復元されます。
割り込みサービスルーチンが、これらのレジスタが保存されているメモリ位置のコンテンツをスワップする場合、コンテキストスイッチを実行できます。すべてのスレッドには、スレッドが実行されていないときにレジスタが保存されるメモリ領域があります。
コンテキストの切り替えはスレッドスケジューラによって制御されます。これは、スレッドがI/O、同期、その優先順位、信号の配信などを待機しているかどうかを考慮します。多くの場合、考慮される中断カウントがありますに。
デバッガーは中断カウントをインクリメントできます。これにより、スレッドが実行可能でないことが保証されます。次に、スレッドの保存されたレジスタのコピーを検査(および変更)できます。
@BenVoigtによるすばらしい情報に加えて、いくつか追加をさせてください。
ブレークポイントは、デバッグするプロセスのマシンコード値(命令または命令の一部)を、ブレークする必要のある(ソース)行に対応するコード内の位置にある特定のトラップ命令で置き換えることにより、デバッガーによって設定されます。この特定のトラップ命令は、ブレークポイントとして使用するためのものです。デバッガーはこれを認識し、オペレーティングシステムも認識します。
デバッグ中のプロセス/スレッドがトラップ命令にヒットすると、@ Benが説明するプロセスをトリガーします。これには、現在実行中のスレッド(CPU状態をメモリに保存することを含む)を一時停止するコンテキストスワップの半分が含まれ、後で再開できるようになります。このトラップはブレークポイントトラップであるため、オペレーティングシステムは、@ Benが説明するメカニズムを使用して、デバッグ中のプロセスを中断したままにし、デバッガに通知して、最終的に再開します。
デバッガーはシステムコールを使用して、デバッグ中の中断されたプロセス/スレッドの保存された状態にアクセスします。
ブレークしたコード行を実行(再開)するには(特定のトラップ命令が含まれています)、デバッガーがブレークポイントトラップ命令で上書きした元のマシンコード値を復元し、別の場所に別のトラップを設定します(たとえば、シングルステップの場合、または、ユーザーが新しいブレークポイントを作成し、@ Benが説明するメカニズムを使用して、プロセス/スレッドを実行可能としてマークします。
実際の詳細はさらに複雑になる可能性があります。ヒットした長期のブレークポイントを維持することは、実際のコードのブレークポイントトラップをスワップアウトして、ラインが実行できるようにしてから、ブレークポイントを再度スワップすることを意味します...
それらのレジスタは、他のOSプロセスによって常に使用されていませんか?どのようにして上書きされないのですか?
@Benが説明しているように、既存のスレッドの一時停止/再開機能(コンテキスト切り替え/ マルチタスク のスワッピング)を使用すると、タイムスライスを使用して複数のプロセス/スレッドでプロセッサを共有できます。
コンテンツのスナップショットのみでライブデータではありませんか?
両方です。ブレークポイントにヒットしたスレッドは一時停止されているため、一時停止時のライブデータ(CPUレジスタなど)のスナップショット、およびtheスレッドが再開された場合にプロセッサに復元するCPUレジスタ値の信頼できるマスター。デバッガーのユーザーインターフェイスを使用して(デバッグされているプロセスの)CPUレジスターの読み取りや変更を行うと、システムコールを使用してこのスナップショット/マスターの読み取りや変更が行われます。
厳密に言えば、少なくともほとんどの場合、gdb自体は実行を一時停止しません。むしろ、gdbはOSに問い合わせ、OSは実行を一時停止します。
最初は違いがないように見えるかもしれませんが、正直なところ、実際には違いがあります。違いは次のとおりです。その機能は、通常のOSにすでに組み込まれています。スレッドが実行するようにスケジュールされていない場合(たとえば、いくつかのリソースが必要な場合)、スレッドの実行を一時停止して再開できる必要があるためです。は現在利用できません)、実行のスケジュールを設定できるようになるまで、OSで一時停止する必要があります。
そのために、OSには通常、マシンの現在の状態を保存するために、各スレッド用に確保されたメモリブロックがあります。スレッドを一時停止する必要がある場合、マシンの現在の状態がその領域に保存されます。スレッドを再開する必要がある場合、マシンの状態はその領域から復元されます。
デバッガーがスレッドを一時停止する必要がある場合、OSは他の理由とまったく同じ方法でそのスレッドを一時停止します。次に、一時停止したスレッドの状態を読み取るために、デバッガーはスレッドの保存された状態を調べます。状態を変更した場合、デバッガーは保存された状態に書き込みます。その後、スレッドが再開されたときに有効になります。