【问题标题】:How to call ucontext.h getcontext from inside a function如何从函数内部调用 ucontext.h getcontext
【发布时间】:2021-01-03 18:19:49
【问题描述】:

我正在尝试将 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;
}

【问题讨论】:

    标签: c linux ucontext


    【解决方案1】:

    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 都发生在堆栈顶部位于同一地址的地方)。

    【讨论】:

    • 这是有道理的,因为通常情况下,调用getcontext() 时堆栈可能任意深。还值得注意的是,当通过makecontext()获取上下文时,调用者需要为堆栈提供空间,而当通过三参数信号处理程序的第三个参数获取上下文时,处理程序本身将要么在自己的堆栈空间中运行,要么在所提供上下文的堆栈顶部运行。
    猜你喜欢
    • 1970-01-01
    • 2017-03-05
    • 2010-10-09
    • 2014-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-10
    • 1970-01-01
    相关资源
    最近更新 更多