两个独立的jmp_buf如何工作?

时间:2014-01-07 18:21:40

标签: c longjmp setjmp

您好我想问一下setjmp / longjmp。我试图搜索,但我没有用...

#include <stdio.h>
#include <setjmp.h>

jmp_buf a, b;

void jump() {
    int aa = setjmp(a);

    if (aa)
    {
        printf("Jump!\n");
    }
    else
    {
        longjmp(b, 1); 
        printf("Should not happened...\n");
    }

    printf("End of function!\n");
}


int main(int argc, char** argv) {
    int bb = setjmp(b);

    if (bb)
    {
        longjmp(a, 1);
        printf("Should not happened...\n");
    }
    else
    {
        jump();
        printf("What here?\n");
    }

    printf("Exit\n");
    return 0;
}

问题是,在jump()中的最后一个printf之后会发生什么...我尝试了这个代码,它变成了无限循环。为什么?我虽然setjmp会存储环境数据,所以跳转函数应该在它原始调用之后返回...我很安静。谢谢你的回复:)

1 个答案:

答案 0 :(得分:2)

整个程序有不确定的行为。

  1. setjmp(b);存储堆栈状态。
  2. jump()被召唤。
  3. `setjmp的(一);”再次存储堆栈状态。
  4. longjmp(b, 1);将堆栈恢复到调用jump()之前的点。因此,a中存储的状态现在无效。
  5. if中的main()继续执行。
  6. longjmp(a, 1);被调用。哎哟。由于上面的4,这导致了未定义的行为。
  7. 您的混淆可能是因为setjmp()的Linux文档中使用世界“返回”的略微不精确。

      

    如果调用setjmp()的函数返回,则堆栈上下文将无效。

    在您的示例中,函数jump()没有以正常方式返回,但效果是相同的:堆栈被第一个longjmp()“切断”到{{之前的状态1}},这也是回报的作用。