You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么ucontext_t执行完成后未返回到uc_link指定的上下文?

问题根因

你代码的核心错误是协程栈内存分配在函数局部栈帧上,生命周期不匹配:

  • 在create_ctx函数中定义的char stack[STACK_SIZE]是当前函数的局部变量,存在于程序的调用栈上,当create_ctx执行结束返回后,这块内存会被系统自动回收,后续其他函数调用会直接覆盖这块地址的内容。
  • 你给协程上下文的uc_stack.ss_sp赋值为这个局部栈的地址,等于协程运行时用的是一块已经被释放的野内存,后续协程切换、执行过程中栈内容、uc_link等关键数据都会被意外篡改,行为完全未定义。
  • 你观察到的退出码是19,是因为routine2最后一次printf的返回值刚好存在rax寄存器中,上下文被破坏后程序异常跳转到了进程退出逻辑,直接把rax的值作为了进程退出状态码。

修复方案

协程的栈内存需要分配在堆上,保证在协程整个生命周期内都有效,修改create_ctx函数即可:

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

typedef void (*coroutine_func)();

#define STACK_SIZE (1<<15)

ucontext_t ctx_main;
ucontext_t c1, c2;

ucontext_t create_ctx(coroutine_func func, ucontext_t *ret_ctx) {
    ucontext_t ctx;
    getcontext(&ctx);
    // 堆分配协程栈,生命周期由自己管控
    char *stack = malloc(STACK_SIZE);
    ctx.uc_stack.ss_sp = stack;
    ctx.uc_stack.ss_size = STACK_SIZE;
    ctx.uc_link = ret_ctx;
    makecontext(&ctx, func, 0);
    return ctx;
}

void routine1() {
    printf("routine1 running\n");
    swapcontext(&c1, &c2);
    printf("routine1 returning\n");
}

void routine2() {
    printf("routine2 running\n");
    swapcontext(&c2, &c1);
    printf("routine2 returning\n");
}

int main() {
    c1 = create_ctx(routine1, &ctx_main);
    c2 = create_ctx(routine2, &ctx_main);

    swapcontext(&ctx_main, &c1);
    swapcontext(&ctx_main, &c2);

    printf("main exiting.\n");
    // 记得释放堆内存,避免泄漏
    free(c1.uc_stack.ss_sp);
    free(c2.uc_stack.ss_sp);
    return 0;
}

修复后运行结果:

routine1 running
routine2 running
routine1 returning
routine2 returning
main exiting.

Process finished with exit code 0

内容的提问来源于stack exchange,提问作者rubys

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 19:54:03