7

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 = %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”。任何人都知道这两个函数究竟是如何工作的,以及它们在 x86_64 下使用 glibc(我使用 ubuntu 14.04)究竟保存了什么?

4

1 回答 1

8

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

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

于 2015-01-21T03:32:43.700 回答