2015-01-21 94 views
5

setjmp()应该将包括“返回地址”和“堆栈指针”的寄存器保存到“jmp_buf”中。当我用glibc编译(包括gcc和clang)并在x86_64下调试以下程序时,我无法理解“jmp_buf”中的内容以及“返回地址”和“堆栈指针”位于“jmp_buf”中。使用setjmp和longjmp时,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)?

+0

我在stackoverflow.com看到了类似这样的问题,但答案通常是“它取决于架构,操作系统,库和ABI ...”或粘贴标准。他们不是我想知道的。 – WindChaser 2015-01-21 03:20:09

+1

你为什么不看看你的平台上的实现?它是开源的。例如:https://github.com/lattera/glibc/blob/master/sysdeps/sh/____longjmp_chk.S - 这是longjmp在glibc中调用的内容。 – 2015-01-21 03:24:45

回答

7

不管你信不信,jmp_buf的内容都是故意地毫无意义。如果你看看the source to the x86_64 setjmp(),你会注意到PTR_MANGLE的几处引用。这是一个内部glibc宏,它将一个线程本地值与一个寄存器异或。这在很大程度上用于确保开发人员不依赖jmpbuf的布局 - 它被视为实现细节,并可能在libc版本之间进行更改。

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

+2

我相信指针修改是作为一个安全特性引入的,而不是隐藏jmpbuf的布局。 – 2015-01-21 22:28:18

+0

@EmployedRussian你的意思是它可以防止像堆栈溢出一样的攻击? – WindChaser 2015-01-22 04:05:04

+0

@WindChaser这是我能找到的唯一相关链接:http://udrepper.livejournal.com/13393.html – 2015-01-22 04:47:09

相关问题