c - 为什么 ucontext_t 执行后不返回 un_lick?
问题描述
我正在尝试实现一个协程,但是在我的代码中,我指定ctx_main
了 for uc_lick
,但是在执行完routine2
对应的子程序后ucontext_t
,程序直接退出而不是返回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 running\n");
swapcontext(&c1, &c2);
printf("routine1 returning\n");
}
void routine2() {
printf("routine2 running\n");
swapcontext(&c2, &c1);
printf("routine2 returning\n"); // 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;
如何检查:使用 sanitizer 选项进行编译,它们将帮助您调试程序:
+ 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
推荐阅读
- react-native - 如何在本机反应中显示带有接受和拒绝按钮的来电通知
- jquery - 将 Jquery 页面作为 web 组件附加到 shadow dom 中
- javascript - 如何重置 otp 字段的输入值?
- android - 避免在 Androids SharedPreferences 中使用默认值
- r - 将多个查询的结果组织到表中
- python - 使用两个非静态相机相对于固定点的 3D 对象位置估计
- elasticsearch - Elasticsearch 导入/导出“模式”对象
- javascript - puppeteer recaptcha invisible 不验证我的机器人
- android - 如何在flutter中使用回调(在发送通知之前调用)调度和发送周期性的flutter本地通知
- orocrm - 有注释的实体