getcontext(3)
背景: / makecontext(3)
/ setcontext(3)
( ucontext.h
; SUSv2, POSIX.1-2001) ファミリの関数を使用して、独自のマシン コンテキストとスタックを割り当てています。
スレッドが割り当てたこれらのコンテキストのいずれかにあるときに、gdb (バージョン 6.1.1) を使用してスタックを調べると、gdb はスタックの最後 (論理的な底) がどこにあるかを認識していないようです。たとえば、x86 FreeBSD のスタックは次のとおりです。
#0 0x2872d79f in poll () from /lib/libc.so.7
#1 0x28646e23 in poll () from /lib/libthr.so.3
#2 0x2869b267 in fdtask (task=0x28a3dc40, v=0x0) at fd.c:58
#3 0x2869c8dc in taskstart (y=681827392, x=0) at task.c:58
#4 0x00000000 in ?? ()
#5 0x28a3dc40 in ?? ()
#6 0x00000000 in ?? ()
#7 0x00000000 in ?? ()
…
#65 0x00000000 in ?? ()
…
(はい、これはRuss Cox の libtask ライブラリの上に構築されています。)
このコンテキストの実行はtaskstart
関数で始まりますが、そのフレームで NULL の戻りアドレスにヒットしたにもかかわらず、GDB はスタックの読み取りを停止する必要があることを理解できないようです。
私の質問は: GDB がスタックのトップがどこにあるかを理解するのを助けるために (何らかの方法でスタックをフォーマットしたり、レジスタを設定したりすることによって) できることはありますか? ありがとう。
編集:結論: gdb 6.1.1 がスタックの終わりを検出する 1 つの方法は、格納されたフレーム ポインターが NULL であることを確認することです。makecontext(2)
新しいコンテキストを初期化するときに、x86 および amd64 関数を変更して ebp または rbp をゼロにリセットすることで、ユース ケースの問題を修正しました。(この場合、他のアーキテクチャは気にしません。) この問題は gdb 7.1 で解消されました。おそらく gdb 7.1 は、debuginfo などの他の手段でスタックの終わりを検出できます。