为什么uncontext_t执行后不返回un_lick ?

  • 本文关键字:返回 un lick 执行 uncontext c
  • 更新时间 :
  • 英文 :


我试图实现一个协程,但在我的代码中,我为uc_lick指定了ctx_main,但在执行了ucontext_t对应的子程序routine2后,程序直接退出,而不是返回到main函数继续执行。

我已经阅读了linux手册。根据我的理解,执行完子程序后应该可以返回到main函数,但是目前执行完后只有routine1返回到main,执行完routine2后程序直接退出。

退出状态码为routine2中最后一个函数的返回值(19为printf的返回值)。为什么会发生这种情况?

#include <stdio.h>
#include <ucontext.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[STACK_SIZE];
ctx.uc_stack.ss_sp = stack;
ctx.uc_stack.ss_size = sizeof(stack);
ctx.uc_link = ret_ctx;
makecontext(&ctx, func, 0);
return ctx;
}
void routine1() {
printf("routine1 runningn");
swapcontext(&c1, &c2);
printf("routine1 returningn");
}

void routine2() {
printf("routine2 runningn");
swapcontext(&c2, &c1);
printf("routine2 returningn"); // return value is 19
}
int main() {
c1 = create_ctx(routine1, &ctx_main);
c2 = create_ctx(routine2, &ctx_main);
swapcontext(&ctx_main, &c1);
swapcontext(&ctx_main, &c2);
// Will not run to here, exit after routine2 is executed.
printf("main exiting.n");
return 0;
}

结果:

routine1 running
routine2 running
routine1 returning
routine2 returning
Process finished with exit code 19

你正在使用一个已经不存在的变量

ucontext_t create_ctx(coroutine_func func, ucontext_t *ret_ctx) {
char stack[STACK_SIZE]; // allocated on stack
ctx.uc_stack.ss_sp = stack;
return ctx; // ss_sp is invalid pointer
}               // variable stack stops existing

您必须分配具有足够生命周期的内存。例如:

char *stack = malloc(STACK_SIZE);
ctx.uc_stack.ss_sp = stack;
ctx.uc_stack.ss_size = STACK_SIZE;

如何检查:编译与消毒选项,他们将帮助您调试您的程序:

+ gcc -D_FORTIFY_SOURCE=2 -D_GLIBCXX_ASSERTIONS -fstack-clash-protection -fstack-protector-all -fstack-protector-strong -ggdb3 -grecord-gcc-switches -fcf-protection -O -Wall -Wextra -Wwrite-strings -Wno-unused-function -Wno-unused-parameter -Wno-implicit-function-declaration -fsanitize=address,undefined,pointer-compare,pointer-subtract /tmp/1.c
==1265711==WARNING: ASan doesn't fully support makecontext/swapcontext functions and may produce false positives in some cases!
routine1 running
routine2 running
routine2 returning
*** stack smashing detected ***: terminated

最新更新