【问题标题】:What does each entry in the Jmp_buf structure hold?Jmp_buf 结构中的每个条目包含什么?
【发布时间】:2010-12-21 21:07:56
【问题描述】:

我正在运行 Ubuntu 9.10 (Karmic Koala),我查看了 jmp_buf 结构,它只是一个 12 个整数的数组。当我使用setjmp 并传入jmp_buf 结构时,12 个条目中有4 个被保存。这 4 个条目是堆栈指针、帧指针、程序计数器和返回地址。其他 8 个条目是做什么用的?它们依赖于机器吗?另一个条目是段表基址寄存器吗?正确恢复线程/进程的环境还需要什么?我查看了手册页和其他来源,但找不到 setjmp 的汇编代码。

【问题讨论】:

    标签: c callstack setjmp


    【解决方案1】:

    在 MacOS X 10.6.2 上,标题 <setjmp.h> 最终使用 <i386/setjmp.h>,并在其中显示:

    #if defined(__x86_64__)
    /*
     * _JBLEN is number of ints required to save the following:
     * rflags, rip, rbp, rsp, rbx, r12, r13, r14, r15... these are 8 bytes each
     * mxcsr, fp control word, sigmask... these are 4 bytes each
     * add 16 ints for future expansion needs...
     */
    #define _JBLEN ((9 * 2) + 3 + 16)
    typedef int jmp_buf[_JBLEN];
    typedef int sigjmp_buf[_JBLEN + 1];
    
    #else
    
    /*
     * _JBLEN is number of ints required to save the following:
     * eax, ebx, ecx, edx, edi, esi, ebp, esp, ss, eflags, eip,
     * cs, de, es, fs, gs == 16 ints
     * onstack, mask = 2 ints
     */
    
    #define _JBLEN (18)
    typedef int jmp_buf[_JBLEN];
    typedef int sigjmp_buf[_JBLEN + 1];
    
    #endif
    

    您可能会在 Linux 上找到类似的要求 - jmp_buf 包含足够的信息来存储必要的状态。而且,要使用它,你真的不需要知道它包含什么;您需要做的就是相信实施者做对了。如果您想更改实现,那么您当然需要了解它。

    请注意,setjmp 和 longjmp 是非常特定于机器的。阅读 Plauger 的“The Standard C Library”,了解实施它们所涉及的一些问题。更现代的芯片很难真正很好地实现。

    【讨论】:

      【解决方案2】:

      setjmp/longjmp/sigsetjmp 高度依赖于 CPU 架构、操作系统和线程模型。前两个函数著名(或臭名昭著——取决于你的 POV)出现在原始 Unix 内核中,作为一种“结构化”的方式来解除失败的系统调用,例如从 i/o 错误或其他讨厌的情况。

      /usr/include/setjmp.h (Linux Fedora) 中的结构的 cmets 表示 调用环境,可能还有保存的信号掩码。 它包括 /usr/include/bits/setjmp.h 到将 jmp_buf 声明为具有六个 32 位整数的数组,显然是特定于 x86 系列的。

      虽然除了PPC implementation 之外我找不到其他来源,但那里的 cmets 合理地暗示应该保存 FPU 设置。这是有道理的,因为无法恢复舍入模式、默认操作数大小、异常处理等会令人惊讶。

      系统工程师通常会在这种结构中预留比实际需要多一点的空间。一些额外的字节几乎没有什么可汗的——尤其是考虑到setjmp/longjmp 的实际使用很少。空间太小肯定是危险的。我能想到的最显着的原因是有额外的——而不是被发现的——如果运行时库版本被更改为在 jmp_buf 中需要更多空间,通过已经预留了额外的空间,就不需要重新编译引用的程序它。

      【讨论】:

        猜你喜欢
        • 2019-12-18
        • 2016-05-08
        • 2014-04-02
        • 2021-01-16
        • 1970-01-01
        • 2017-11-01
        • 1970-01-01
        • 2014-07-24
        • 1970-01-01
        相关资源
        最近更新 更多