【问题标题】:How two independent jmp_bufs work?两个独立的 jmp_bufs 是如何工作的?
【发布时间】:2014-01-07 18:21:39
【问题描述】:

您好,我想问一下关于 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 将存储环境数据,所以跳转函数将在它的原始调用后返回......我很困惑。谢谢回复:)

【问题讨论】:

    标签: c setjmp


    【解决方案1】:

    整个程序有未定义的行为。

    1. setjmp(b); 存储堆栈状态。
    2. jump() 被调用。
    3. `setjmp(a);'再次存储堆栈状态。
    4. longjmp(b, 1); 将堆栈恢复到调用 jump() 之前的位置。所以a中存储的状态现在是无效的。
    5. if 中的main() 处继续执行。
    6. longjmp(a, 1); 被调用。哎哟。由于上述 4,这会导致未定义的行为。

    您的困惑可能是由于setjmp() 的 Linux 文档中对世界“返回”的稍微不精确使用造成的。

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

    在你的例子中,函数jump()没有以正常方式返回,但效果是一样的:堆栈被第一个longjmp()“砍”到jump()之前的状态,即return 也有什么作用。

    【讨论】:

    • 谢谢。您知道一些有用的页面或文献,我可以在其中找到有关 C 和堆栈的更多信息吗?也许我对它的想象与现实略有不同:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 1970-01-01
    • 1970-01-01
    • 2013-01-05
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多