C语言 是否创建上下文段错误?

9o685dep  于 2022-12-03  发布在  其他
关注(0)|答案(3)|浏览(138)

我正在做一个家庭作业,下学期就要交了。它要求我们使用 ucontext API来实现我们自己的上下文切换/线程库。教授提供了实现这一点的代码,但在线程返回之前,他手动做了一些工作,并调用一个ISR,该ISR找到另一个要使用的线程,并将上下文切换到该线程,如果没有剩余的线程,则退出。
赋值的重点是使用上下文的 uc_link 字段,这样当它遇到return时,它就可以处理这项工作。我创建了一个函数(类型为void/void args),它只做以前函数所做的工作(清理,然后调用ISR)。教授说他想要这样做。
因此,剩下的工作就是在 uc_link 字段中的上下文上执行 makecontext,以便它运行我的线程,对吗?当我在 ucontext_t 和函数的任意组合上执行 makecontext 时,我得到了一个segfault,gdb没有提供任何帮助。我可以跳过 makecontext,当我的程序在我创建的线程中遇到一个return时,它会“正常”退出,因为(大概)uc_link 字段没有正确设置(这正是我要做的)。
我也找不到任何关于为什么 makecontext 会出现segfault的信息。有人能帮忙吗?

stack2.ss_sp = (void *)(malloc(STACKSIZE));
if(stack2.ss_sp == NULL){
printf("thread failed to get stack space\n");
exit(8);
}
stack2.ss_size = STACKSIZE;
stack2.ss_flags = 0;

if(getcontext(&main_context) == -1){
perror("getcontext in t_init, rtn_env");
exit(5);
}

//main_context.uc_stack = t_state[i].mystk;                                                                                                                
main_context.uc_stack = stack2;
main_context.uc_link = 0;
makecontext(&main_context, (void (*)(void))thread_rtn, 0);

我还尝试了 thread_rtn&thread_rtn 和其他方法。thread_rtn 被声明为 void thread_rtn(void)
稍后,在每个线程中(run_env 的类型为 ucontext_t):...

t_state[i].run_env.uc_link = &main_context;
c3frrgcw

c3frrgcw1#

这里有很多事情要做,但我会给予我最好的想法。我也试图在不解决家庭作业的情况下回答问题。
thread_rtn是在什么上下文中声明的?它是否使用了任何非静态变量?
segfault可能是由已分配但不再可用(超出上下文或已释放)的内存引起的。
我无法判断main_context是否与线程上下文相同,两者应该不同。
看起来每个线程都需要自己的堆栈,它不应该和主上下文的堆栈相同(或者和其他线程的堆栈相同)。想一想每个线程可以从哪里获得内存作为堆栈使用。在什么情况下malloc(STACKSIZE)会返回NULL
当线程上下文被添加到主上下文时,main_context.uc_link应该递增。看起来main_context.uc_link正在跟踪有多少线程链接到主上下文。(我试图留下一些与课程相关的思考工作,而不是说明如何处理递减的计数)。注意特殊值0,表示不再有任何线程与此主上下文关联。main_context.uc_link是否有最大值?
希望这对你有帮助。

a11xaf1n

a11xaf1n2#

我有完全相同的问题,经过相当多的调试,我找到了解决方案。
makecontext()要求你传递栈底,它会根据传递给它的大小自动计算栈顶。
就我而言,
因为在linux中,堆栈是从上到下增长的,我传递的是clone系统调用所要求的栈顶,所以,它会产生分段错误。
试试看,也许有用。

h4cxqtbf

h4cxqtbf3#

我遇到了同样的错误,我弄清楚了,错误的原因是堆栈的大小太小,增加它,错误就消失了。

pco->_context.uc_stack.ss_sp = _stack.get();
// change STACKSIZE from 2<<10 to 2<<20, the error was fixed!
pco->_context.uc_stack.ss_size = STACKSIZE;

相关问题