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

标签 c debugging gdb setjmp

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 functionality: "p/x env";但是我在这个包含 __jmpbuf 和 __saved_mask 的结构 (env) 中找不到“return RIP”和“previous RSP”。任何人都知道这两个函数究竟是如何工作的,以及它们在 x86_64 下使用 glibc(我使用的是 ubuntu 14.04)到底保存了什么?

最佳答案

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

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

关于c - 使用 setjmp 和 longjmp 时,jmp_buf 中的实际内容是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28059021/

相关文章:

visual-studio - 找出我的应用程序当前在 Visual Studio 的 Debug模式下运行的代码行

rust - 使用 OpenOCD 和 arm-none-eabi-gdb 将二进制文件加载到 stm32f103c8t6

无法在 ubuntu : Could not find platform independent libraries 上运行 gdb

C: 为什么 &(void *) 和 void** 不兼容?

c - 在 malloc 中使用 sizeof(void)

c# - System.Diagnostics.StackTrace 紧凑框架

.net - 如何在 Visual Studio 中的引用代码中设置断点?

返回字符串数组时类型冲突

c++ - 如何编写可以控制设备驱动程序的程序?

c - 将 gdb 与 alsa-lib-1.1.3 一起使用