C语言 使用 setjmp 和 longjmp 时,jmp_buf中的实际内容是什么



setjmp() 应该将包括"返回地址"和"堆栈指针"在内的寄存器保存到"jmp_buf"中。当我使用 glibc 编译(gcc 和 clang)并在x86_64下调试以下程序时,我无法理解"jmp_buf"中的内容以及"返回地址"和"堆栈指针"在"jmp_buf"中的位置。

#include <stdio.h>
#include <setjmp.h>
int main()
{
    int i;
    jmp_buf env;
    i = setjmp(env);
    printf("i = %dn", i);
    if (i != 0) return;
    longjmp(env, 2);
    printf("Does this line get printed?n");
}   

当程序在"printf("i = %d", i);"之前的断点处停止时,我尝试了gdb功能:"p/x env";但是我在这个包含__jmpbuf和__saved_mask的结构(env)中找不到"返回RIP"和"以前的RSP"。有谁知道这两个函数究竟是如何工作的,以及它们在使用 glibc x86_64下究竟保存了什么(我使用 ubuntu 14.04)?

信不信由你,jmp_buf的内容是故意没有意义的。如果你看一下x86_64 setjmp()的源代码,你会注意到对PTR_MANGLE的几个引用。这是一个内部 glibc 宏,它对寄存器对线程本地值进行 XOR 运算。这在很大程度上是为了确保开发人员不依赖于jmpbuf的布局——它被认为是一个实现细节,并且可能会在libc的版本之间发生变化。

如果你想要一些可读的东西,请查看ucontext界面。

最新更新