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

Win*_*ser 5 c debugging gdb longjmp setjmp

setjmp()应该将包含"返回地址"和"堆栈指针"的寄存器保存到"jmp_buf"中.当我编译(gcc和clang)并使用glibc在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");
}   
Run Code Online (Sandbox Code Playgroud)

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

dus*_*uff 8

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

如果您想要可读的内容,请查看ucontext界面.

  • 我认为指针修改是作为安全功能引入的,而不是隐藏jmpbuf的布局. (2认同)