makecontext 段错误?
Posted
技术标签:
【中文标题】makecontext 段错误?【英文标题】:makecontext segfault? 【发布时间】:2010-12-28 17:55:04 【问题描述】:我正在做下学期要交的家庭作业。它要求我们使用 ucontext API 实现我们自己的上下文切换/线程库。教授提供了执行此操作的代码,但在线程返回之前,他手动执行了一些工作并调用 ISR,该 ISR 找到另一个要使用的线程并将上下文交换给它,或者如果没有留下,则退出。
分配的重点是使用上下文的 uc_link 字段,以便在返回时处理工作。我创建了一个函数(类型 void/void args),它只完成函数之前所做的工作(清理然后调用 ISR)。教授说他想要这个。
所以剩下的就是在 uc_link 字段的上下文中沿途的某个地方做一个 makecontext 以便它运行我的线程,对吗?好吧,当我对 ucontext_t 和函数的任意组合执行 makecontext 时,我得到一个段错误,而 gdb 没有提供任何帮助。我可以跳过 makecontext 并且我的程序在我创建的线程中遇到返回时“正常”退出,因为(可能)uc_link 字段设置不正确(即我正在尝试做的事情)。
我也找不到任何关于为什么 makecontext 会出现段错误的信息。有人可以帮忙吗?
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;
【问题讨论】:
请在此处或 pastebin 之类的地方发布一些代码。 【参考方案1】:这里发生了很多事情,但我会给出我最好的想法。我也在尝试在不做作业的情况下回答问题。
thread_rtn
是在什么上下文中声明的,它是否使用任何非静态变量?
段错误可能是由已分配但不再可用的内存(脱离上下文或已释放)引起的。
我无法判断main_context
是否与线程上下文相同,两者应该不同。
看起来每个线程都需要自己的堆栈,它不应与主上下文的堆栈相同(或与任何其他线程的堆栈相同)。想想每个线程可以从哪里获得内存以用作堆栈。在什么情况下malloc(STACKSIZE)
会返回NULL
?
将线程上下文添加到主上下文时,main_context.uc_link
应该递增。看起来main_context.uc_link
正在跟踪有多少线程链接到主上下文。想想当计数减少时会发生什么(我试图留下一些与课程相关的工作,而不是说如何处理减少的计数)。请注意特殊值 0,这意味着不再有任何线程与此主上下文相关联。 main_context.uc_link
有最大值吗?
希望这会有所帮助。
【讨论】:
【参考方案2】:我遇到了完全相同的问题,经过大量调试后,我找到了解决方案。
makecontext() 需要你传递栈底,它会根据传递给它的大小自动计算栈顶。
就我而言,
因为在linux中,堆栈是从上到下增长的,我是按照克隆系统调用的要求传递堆栈的顶部。所以,它给出了分段错误。
试一试,也许会奏效。
【讨论】:
我在十多年前就发过这个了,哈哈 C 和它的错误即使在几十年后也不会变老。也许这有时会帮助某人:)以上是关于makecontext 段错误?的主要内容,如果未能解决你的问题,请参考以下文章