c - 使用 getcontext/setcontext 向上/向下切换堆栈

标签 c ucontext

我试图了解 getcontext/setcontext 在特定情况下是否能正常工作。

我可以看到如何使用 setcontext() 将堆栈展开回历史记录中的某个位置。

#include <stdio.h>
#include <ucontext.h>

int  rollback = 0;
ucontext_t context;

void func(void)
{
    setcontext(cp);
}

int main(void)
{
    getcontext(&context);
    if (rollback == 0)
    {
        printf("getcontext has been called\n");
        rollback++;
        func();
    }
    else
    {
        printf("setcontext has been called\n");
    }
}

但我想知道放松后是否可以重新回到 future 的地方?我想这取决于 getcontext() 调用捕获堆栈的副本,​​我无法在文档中找到确切的详细信息。

#include <stdio.h>
#include <ucontext.h>

int  rollback     = 0;
int  backToFuture = 0;
ucontext_t context;
ucontext_t futureContext;

void func(void)
{
    // Some complex calc
    if (some-condition)
    {
        getcontext(&futureContext);  // After returning I want to come back
                                     // here to carry on with my work.
        if (backToFuture == 0)
        {
            setcontext(&context);  // rewind to get stuff-done
        }
    }
    // Finishe work
}

int main(void)
{
    getcontext(&context);
    if (rollback == 0)
    {
        printf("getcontext has been called\n");
        rollback++;
        func();

        // eventually always return here.
    }
    else
    {
        printf("setcontext has been called\n");
        // Do specialized work that needed to be done
        // May involve function calls.
        // 
        // I worry that anything the adds new stack frames
        // will disrupt the saved state of futureContext
        //
        // But without detailed information I can not be sure
        // if this is an allowed senario.
        backToFuture = 1;
        setcontext(&futureContext);
    }
}

最佳答案

getcontext 不复制堆栈,它只转储寄存器(包括堆栈指针)和一些上下文数据,如信号掩码等。

当您跳下堆栈时,它会使顶部上下文无效。即使您不会执行任何函数调用,也要考虑可以在那里执行的信号处理程序。如果你想在两个堆栈之间跳转,你需要 makecontext

我添加了表明您的代码无效的变量:

void func(void)
{
    // Some complex calc
    if (1)
    {
        volatile int neverChange = 1;
        getcontext(&futureContext);  // After returning I want to come back
                                     // here to carry on with my work.
        printf("neverchange = %d\n", neverChange);
        if (backToFuture == 0)
        {
            setcontext(&context);  // rewind to get stuff-done
        }
    }
    // Finishe work
}

在我的机器上它导致:

getcontext has been called
neverchange = 1
setcontext has been called
neverchange = 32767

关于c - 使用 getcontext/setcontext 向上/向下切换堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15115480/

相关文章:

c++ - 如何使用需要指向 C++ 中 void 函数的指针的 Functor 来调用 C 函数?

c - ESP32 - 带有本地 LwIP 库的 UDP 广播器/接收器

c - 输入一个字符作为整型变量的输入,给出无限循环

c - 实现用户级线程库但代码不断出现段错误,有什么想法吗?

c++ - 通过getcontext和setcontext实现swapcontext

C/多线程/段错误/(可能是)线程队列问题

用于读取测试结果的 C 程序

c - Xcode,释放了多少内存分配?(Valgrind 的替代方案)

c - 为什么我的函数没有运行并出现无效内存错误?

c++ - setcontext 和 makecontext 调用通用函数指针