你直接看setjmp.h不就完了么
相关的定义如下:
代码: 全选
# if __WORDSIZE == 64
typedef long int __jmp_buf[8];
# elif defined __x86_64__
__extension__ typedef long long int __jmp_buf[8];
# else
typedef int __jmp_buf[6];
# endif
/* Calling environment, plus possibly a saved signal mask. */
struct __jmp_buf_tag
{
/* NOTE: The machine-dependent definitions of `__sigsetjmp'
assume that a `jmp_buf' begins with a `__jmp_buf' and that
`__mask_was_saved' follows it. Do not move these members
or add others before it. */
__jmp_buf __jmpbuf; /* Calling environment. */
int __mask_was_saved; /* Saved the signal mask? */
__sigset_t __saved_mask; /* Saved signal mask. */
};
typedef struct __jmp_buf_tag jmp_buf[1];
你要理解它是在干什么,就需要一点汇编语言和操作系统相关的知识。上面代码中提到的Calling environment,实际上就是指的是CPU的寄存器的值,你看这个函数的名称gc_mark_register,就是在标记寄存器。
一个最简化的程序
代码: 全选
#include <setjmp.h>
int main(int argc,char **argv) {
jmp_buf env;
setjmp(env);
return 0;
}
用gdb调试的结果,你可以自己看看env中包含的值与cpu寄存器的关系
代码: 全选
(gdb) break main
Breakpoint 1 at 0x738: file a.c, line 2.
(gdb) r
Starting program: /tmp/a.out
Breakpoint 1, main (argc=1, argv=0x7fffffffdf78) at a.c:2
2 int main(int argc,char **argv) {
(gdb) s
4 setjmp(env);
(gdb) s
5 return 0;
(gdb) print env
$1 = {{__jmpbuf = {0, 5569584266273830259, 4294968816, 140737488346992, 0, 0, 5569584266370299251, -5569021317323737741},
__mask_was_saved = 0, __saved_mask = {__val = {0, 0, 0, 0, 5658608, 194, 140737488346735, 140737488346734, 140737348619248, 1,
4294969293, 0, 0, 4294969216, 4294968816, 140737488346992}}}}
(gdb) info registers
rax 0x0 0
rbx 0x0 0
rcx 0x0 0
rdx 0x4d4b23619f9b3573 5569584266370299251
rsi 0x0 0
rdi 0x7fffffffddc0 140737488346560
rbp 0x7fffffffde90 0x7fffffffde90
rsp 0x7fffffffddb0 0x7fffffffddb0
r8 0x1000007f0 4294969328
r9 0x7ffff7de7f90 140737351942032
r10 0x2 2
r11 0x1 1
r12 0x1000005f0 4294968816
r13 0x7fffffffdf70 140737488346992
r14 0x0 0
r15 0x0 0
rip 0x100000756 0x100000756 <main+54>
eflags 0x246 [ PF ZF IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb)