1

gdbがbacktraceコマンドを実行するときに行うように、コールスタックを構築する方法を理解したいと思います。これはインタビューで尋ねられ、私はコールスタックとスタックフレームの知識に基づいて答えました。これは、スタックポインター、呼び出し元のリターンアドレス/命令を使用し、実行可能ファイル/アセンブリ命令にマッピングすることで行われると思います。私はそれが実際にどのように行われるか、またはこのスタックウォークの良い説明を探していました。グーグルで見つけたすべての情報は、プログラムでこのウォークへのMicrosoft APIに関連しており、コールスタックの構築にアプローチする方法の一般的な説明を探しています。

4

2 に答える 2

1

グーグル検索は私をここに導きました。

フレームポインタを使用した非常に単純なix86呼び出し規約について考えてみます。ルーチンを呼び出すたびに、次の命令のアドレスがスタックにプッシュされます。エントリ直後に呼び出されたルーチンは、push %ebp; mov %esp,%ebp命令を実行します。そうすると、上のページのレイアウトが正確に表示されます。

から呼び出された、から呼び出された、から呼び出された、から呼び出されたルーチンfooで停止したとします。barbazmain

で指す2つの単語を調べます%ebp。最初のワードはの前の値です%ebp(これを呼びましょうprev_ebp。2番目のワードはリターンアドレスです-内のどこかにある命令ポインタbar

ここで、が指す2つの単語を調べますprev_ebp。最初のものはになりprev_prev_ebp、2番目はリターンアドレスになります-内のどこかにある命令ポインタbaz

mainに到達し、GDBが使用する手順を大まかに実行するまで繰り返します。

フレームポインタを使用しないフレームなど、多くの実用的な複雑さがありますが、それを理解することは期待されていません:-)

于 2012-10-27T16:29:26.687 に答える
0

gdbでどのように実行されるかはわかりませんが、ここにアイデアがあります。すべてのjmp/call命令とそのターゲットアドレスをスタックに保持できれば、いつでも完全な呼び出しトレースが得られます。

于 2012-10-27T14:37:39.440 に答える