1

我正在尝试将 getcontext 调用到另一个函数中(而不是直接将其调用到 main 中),以便复制线程的堆栈并稍后恢复它。此代码应重复打印,但一旦调用 getcontext 的函数返回,它将无法工作。

有没有办法绕过这个限制并在另一个函数(内联宏除外)中调用 getcontext ?

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

ucontext_t context;

void set_context() {
    setcontext(&context);
}

void get_context() {
    getcontext(&context);
}

int main() {
    get_context();
    puts("Hello world");
    sleep(1);
    set_context();
    return 0;
}
4

1 回答 1

4

getcontext仅保存调用点的机器寄存器状态。它不在该位置存储堆栈内存的内容。当您调用时setcontext,它跳转执行代码,get_context但下一条指令会弹出set_context调用的返回地址:

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

ucontext_t context;

void set_context() {
    puts("Calling setcontext");
    setcontext(&context);
    puts("Returned from setcontext");
}

void get_context() {
    puts("Calling getcontext");
    getcontext(&context);
    puts("Returned from getcontext");
}

int main() {
    get_context();
    puts("Hello world");
    sleep(1);
    set_context();
    return 0;
}

输出:

Calling getcontext
Returned from getcontext
Hello world
Calling setcontext
Returned from getcontext

你想做的事情——延续——原则上可以这样做,但它们在实践中是行不通的……也就是说,你永远不会得到你想做的事情来处理这两者之间的随机 C 程序来电。此外,您的测试没有导致崩溃只是偶然的......(setcontext 和 getcontext 都发生在堆栈顶部位于同一地址的地方)。

于 2021-01-03T18:35:34.350 回答