7

setjmp() は、「リターンアドレス」と「スタックポインタ」を含むレジスタを「jmp_buf」に保存することになっています。glibc を使用して x86_64 で次のプログラムをコンパイル (gcc と clang の両方) してデバッグすると、「jmp_buf」の内容と「リターン アドレス」と「スタック ポインター」が「jmp_buf」のどこにあるのかがわかりません。

#include <stdio.h>
#include <setjmp.h>

int main()
{
    int i;

    jmp_buf env;

    i = setjmp(env);

    printf("i = %d\n", i);

    if (i != 0) return;

    longjmp(env, 2);
    printf("Does this line get printed?\n");
}   

プログラムが "printf("i = %d\n", i);" の前のブレークポイントで停止した場合、gdb 機能を試しました: "p/x env"; ただし、__jmpbuf と __saved_mask を含むこの構造体 (env) に「リターン RIP」と「前の RSP」が見つかりません。これら2つの関数がどのように機能し、glibcを使用してx86_64で正確に何を保存するかを知っている人はいますか(私はubuntu 14.04を使用しています)?

4

1 に答える 1

8

信じられないかもしれませんが、 の内容jmp_buf意図的に無意味です。x86_64 のソースをsetjmp()見ると、 への参照がいくつかあることに気付くでしょうPTR_MANGLE。これは、レジスタに対してスレッドローカル値を XOR する内部 glibc マクロです。これは主に、開発者がレイアウトに依存しないようにするために使用されますjmpbuf— これは実装の詳細と見なされ、libc のバージョン間で変更される可能性があります。

読みやすいものが必要な場合は、 ucontext インターフェイスを確認してください。

于 2015-01-21T03:32:43.700 に答える