Jmp_buf 结构中的每个条目保存什么?
我运行的是 Ubuntu 9.10 (Karmic Koala),我查看了 jmp_buf 结构,它只是一个 12 个整数的数组。当我使用 setjmp
并传入 jmp_buf
结构时,12 个条目中有 4 个被保存。这 4 个条目是堆栈指针、帧指针、程序计数器和返回地址。另外8个条目是做什么用的?它们依赖于机器吗?另一个条目是段表基址寄存器吗?正确恢复线程/进程的环境还需要什么?我查看了手册页和其他来源,但找不到 setjmp
的汇编代码。
I am running Ubuntu 9.10 (Karmic Koala), and I took a look at the jmp_buf
structure which is simply an array of 12 ints. When I use setjmp
, and pass in a jmp_buf
structure—4 out of 12 entries are saved off. These 4 entries are the stack pointer, frame pointer, program counter and return address. What are the other 8 entries for? Are they machine-dependent? Is another entry the segment table base register? What else is needed to properly restore a thread/process's environment? I looked through the man page, other sources, but I couldn't find the assembly code for setjmp
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 MacOS X 10.6.2 上,标头
最终使用
,其中显示:您可能会在 Linux 上找到类似的要求 -
jmp_buf
包含足够的信息来存储必要的状态。而且,要使用它,您实际上不需要知道它包含什么;您只需知道它包含什么即可。您需要做的就是相信实施者的做法是正确的。当然,如果您想更改实现,那么您确实需要了解它。请注意,setjmp 和 longjmp 是非常特定于机器的。阅读 Plauger 的“标准 C 库”,了解其中涉及的一些问题的讨论在实施它们时。更现代的芯片使得真正更好地实施变得更加困难。
On MacOS X 10.6.2, the header
<setjmp.h>
ends up using<i386/setjmp.h>
, and in there it says:You would probably find similar requirements on Linux - the
jmp_buf
contains enough information to store the necessary state. And, to use it, you really don't need to know what it contains; all you need to do is trust that the implementers got it correct. If you want to alter the implementation, then you do need to understand it, of course.Note that setjmp and longjmp are very machine specific. Read Plauger's "The Standard C Library" for a discussion of some of the issues involved in implementing them. More modern chips make it harder to implement really well.
setjmp
/longjmp
/sigsetjmp
高度依赖于CPU架构、操作系统和线程模型。前两个函数著名地(或臭名昭著地——取决于你的观点)出现在原始 Unix 内核中,作为一种“结构化”方式来摆脱失败的系统调用,例如 I/O 错误或其他令人讨厌的情况。/usr/include/setjmp.h (Linux Fedora) 中的结构注释表示调用环境,以及可能保存的信号掩码。它包括 /usr/include/bits/setjmp.h 来将 jmp_buf 声明为有一个由 6 个 32 位整数组成的数组,显然是 x86 系列特有的。
虽然我找不到除了 PPC 实现,那里的注释合理地暗示应该保存 FPU 设置。这是有道理的,因为无法恢复舍入模式、默认操作数大小、异常处理等会令人惊讶。
系统工程师通常会在这种结构中保留比实际需要多一点的空间。一些额外的字节几乎没什么值得担心的——特别是考虑到
setjmp
/longjmp
的实际使用很少。空间太小肯定是一个危险。我能想到的最重要的原因是拥有额外的空间(而不是恰到好处),如果运行时库版本更改为在 jmp_buf 中需要更多空间,则通过已保留额外的空间,无需重新编译引用的程序它。setjmp
/longjmp
/sigsetjmp
are highly dependent on the CPU architecture, operating system, and threading model. The first two functions famously (or infamously—depending on your POV) appeared in the original Unix kernel as a "structured" way to unwind out of a failed system call, as from an i/o error or other nasty situations.The structure's comments in /usr/include/setjmp.h (Linux Fedora) say Calling environment, plus possibly a saved signal mask. It includes /usr/include/bits/setjmp.h to declare jmp_buf to have an array of six 32-bit ints, apparently specific to the x86 family.
While I couldn't find source other than a PPC implementation, the comments there reasonably hint that FPU settings should be saved. That makes sense since failing to restore the rounding mode, default operand size, exception handling, etc. would be surprising.
It's typical of system engineers to reserve a little more space than actually needed in such a structure. A few extra bytes are hardly anything to sweat—especially considering the rarity of actual uses of
setjmp
/longjmp
. Having too little space definitely is a hazard. The most salient reason I can think of is having extra—as opposed to being spot on—is that if the runtime library version is changed to need more space in jmp_buf, by having extra room already reserved, there's no need to recompile programs referring to it.