デバッガーはどのように機能しますか?


170

デバッガーはどのように機能するのでしょうか。特に、すでに実行中の実行可能ファイルに「接続」できるもの。コンパイラーがコードを機械語に変換することを理解していますが、デバッガーはそれが接続されているものをどのように「知る」のですか?



@Oktalistこの記事は興味深いですが、LinuxでのデバッグのためのAPIレベルの抽象化についてのみ述べています。OPは内面についてもっと知りたいと思います。
smwikipedia 2017

回答:


96

デバッガーの動作の詳細は、デバッグ対象とOSによって異なります。Windowsでのネイティブデバッグについては、MSDN:Win32 Debugging APIで詳細を確認できます

ユーザーは、名前またはプロセスIDのいずれかで、アタッチするプロセスをデバッガーに指示します。名前の場合、デバッガーはプロセスIDを検索し、システムコールを介してデバッグセッションを開始します。Windowsでは、これはDebugActiveProcessになります。

接続すると、デバッガーは他のUIと同じようにイベントループに入りますが、ウィンドウシステムからのイベントではなく、OSはデバッグ中のプロセスで発生したことに基づいてイベントを生成します(例外の発生など)。WaitForDebugEventを参照してください。

デバッガーは、ターゲットプロセスの仮想メモリを読み書きでき、OSが提供するAPIを介してそのレジスター値を調整することもできます。Windows のデバッグ関数のリストを参照してください。

デバッガーは、シンボルファイルからの情報を使用して、アドレスから変数名およびソースコード内の場所に変換できます。シンボルファイル情報は、別個のAPIセットであり、OS自体のコア部分ではありません。Windowsでは、これはDebug Interface Access SDKを介して行われます

管理対象環境(.NET、Javaなど)をデバッグしている場合、プロセスは通常似ていますが、仮想マシン環境が基盤となるOSではなくデバッグAPIを提供するため、詳細は異なります。


5
この質問は愚かに聞こえるかもしれませんが、プログラム内の特定のアドレスに到達した場合、OSはどのように追跡しますか。たとえば、アドレス0x7710cafeにブレークポイントが設定されています。命令ポインタが変更されると、OS(またはCPU)が命令ポインタをすべてのブレークポイントアドレスと比較する必要がありますか、それとも間違っていますか?これはどのように作動しますか ..?
displayname

3
@StefanFalk (x86で)下位レベルの詳細のいくつかに対処する回答を書きまし
Jonathon Reinhart 2014

変数名がアドレスに正確にどのようにマッピングされるか説明できますか?アプリケーションは、実行されるたびに変数に同じメモリアドレスを使用しますか?私は常に、利用可能なメモリからマッピングされただけだと思っていましたが、バイトがアプリのメモリ空間の同じ場所に直接マッピングされるかどうかについてはまったく考えていませんでした。それは主要なセキュリティ問題になるようです。
James Joshua Street

@JamesJoshuaStreet私はそれがデバッガーに固有の詳細であると想像します。
moonman239

この答えは何かを明らかにします。しかし、私はopはいくつかのAPI抽象化よりもいくつかの低レベルの詳細に関心があると思います。
smwikipedia

63

私が理解しているように:

x86のソフトウェアブレークポイントの場合、デバッガーは命令の最初のバイトをCCint3)に置き換えます。これはWriteProcessMemoryWindowsで行われます。CPUがその命令に到達してを実行するint3と、CPUはデバッグ例外を生成します。OSはこの割り込みを受け取り、プロセスがデバッグ中であることを認識し、ブレークポイントに達したことをデバッガプロセスに通知します。

ブレークポイントにヒットしてプロセスが停止した後、デバッガーはブレークポイントのリストを調べ、をCC元々あったバイトに置き換えます。デバッガーはTF、トラップフラグEFLAGS(を変更してCONTEXT)設定し、プロセスを続行します。トラップフラグにより​​、CPU INT 1は次の命令でシングルステップ例外()を自動的に生成します。

デバッグ中のプロセスが次回停止すると、デバッガーはブレークポイント命令の最初のバイトを再びに置き換えCC、プロセスは続行されます。

これがすべてのデバッガーでどのように実装されているのか正確にはわかりませんが、このメカニズムを使用して自分自身をデバッグするWin32プログラムを作成しました。まったく役に立たないが、教育的。


25

Linuxでは、プロセスのデバッグはptrace(2)システムコールで始まります。 この記事には、ptraceいくつかの簡単なデバッグ構造を実装するためのの使用方法に関する優れたチュートリアルがあります。


1
(2)「ptraceはシステムコールです」以上のことを教えてくれますか?
Lazer、

5
@eSKay、そうでもない。(2)マニュアルセクション番号です。マニュアルセクションの説明については、en.wikipedia.org / wiki / Man_page#Manual_sectionsをご覧ください。
Adam Rosenfield、

2
@AdamRosenfieldセクション2が特に「システムコール」であるという事実を除きます。つまり、間接的に、それはptraceシステムコールであることがわかります。
Jonathon Reinhart 2014

1
より実際的には、(2)man 2 ptrace正しいマンページを入力して取得できることを示しています- ptrace明確にするものは他にないため、ここでは重要ではありませんが、Linux と比較man printfするためman 3 printfです。
スリム

9

Windows OSを使用している場合、このための優れたリソースは、John Robbinsによる「Microsoft .NETおよびMicrosoft Windowsのアプリケーションのデバッグ」です。

(または以前のエディション:「アプリケーションのデバッグ」

この本には、いくつかの単純な(しかし機能している)デバッガーのコードを含む、デバッガーの動作に関する章があります。

私はUnix / Linuxデバッグの詳細に精通していないので、これは他のOSにはまったく当てはまらないかもしれません。しかし、非常に複雑なテーマの紹介として、詳細やAPIでなくても、ほとんどのOSにコンセプトを「移植」する必要があると思います。


3

デバッグを理解するためのもう1つの貴重な情報源は、インテルCPUマニュアル(インテル®64およびIA-32アーキテクチャーソフトウェア開発者向けマニュアル)です。ボリューム3Aの第16章では、特別な例外やハードウェアデバッグレジスタなど、デバッグのハードウェアサポートを紹介しました。以下はその章からのものです:

T(トラップ)フラグ、TSS — TSSにTフラグが設定されているタスクに切り替えようとしたときに、デバッグ例外(#DB)を生成します。

WindowとLinuxのどちらがこのフラグを使用しているかはわかりませんが、その章を読むのはとても興味深いです。

これが誰かを助けることを願っています。


2

ここで答えるべき主な質問が2つあると思います。

1.デバッガーは例外が発生したことをどのようにして知るのですか?

デバッグ中のプロセスで例外が発生すると、ターゲットプロセスで定義されたユーザー例外ハンドラーが例外に応答する機会が与えられる前に、デバッガーはOSから通知を受けます。デバッガーがこの(初回)例外通知を処理しないことを選択した場合、例外ディスパッチシーケンスはさらに進み、ターゲットスレッドは、処理する必要がある場合に例外を処理する機会が与えられます。SEH例外がターゲットプロセスで処理されない場合、デバッガーには、セカンドチャンス通知と呼ばれる別のデバッグイベントが送信され、未処理の例外がターゲットプロセスで発生したことを通知します。ソース

ここに画像の説明を入力してください


2.デバッガーはどのようにしてブレークポイントで停止するかを知っていますか?

簡単な答えは次のとおりです。プログラムにブレークポイントを設定すると、デバッガーはその時点でコードをソフトウェア割り込みであるint3命令に置き換えます。結果として、プログラムが中断され、デバッガーが呼び出されます。


1

私の理解では、アプリケーションまたはDLLファイルをコンパイルすると、コンパイルされるものにはすべて、関数と変数を表すシンボルが含まれます。

デバッグビルドがある場合、これらのシンボルはリリースビルドの場合よりもはるかに詳細であるため、デバッガーはより多くの情報を提供できます。デバッガーをプロセスにアタッチすると、現在アクセスされている関数が確認され、ここから使用可能なすべてのデバッグシンボルが解決されます(コンパイルされたファイルの内部がどのようになっているのかを知っているため、メモリ内の内容を確認できます) 、int、float、stringなどのコンテンツを含む)。最初のポスターが言ったように、この情報とこれらの記号がどのように機能するかは、環境と言語に大きく依存します。


2
これはシンボルについてです。シンボルよりもはるかに多くのデバッグがあります。
Jonathon Reinhart、2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.