我已经减少了一个巨大的光纤调度程序代码,这个代码产生了以下几行的问题 我所期待的是每次都清楚地回到上下文,传递给处理程序 我得到的是“处理程序。”打印出三次,然后是分段错误。
#include <ucontext.h>
#include <signal.h>
#include <stdio.h>
ucontext_t currently_executed_context;
void handler_sigusr1(int signum, siginfo_t* siginfo, void* context)
{
currently_executed_context = (*(ucontext_t*)context);
printf("Handler. ");
setcontext(¤tly_executed_context);
}
int main()
{
setbuf(stdout,0);
struct sigaction action_handler;
action_handler.sa_sigaction = handler_sigusr1;
action_handler.sa_flags = SA_SIGINFO;
sigaction(SIGUSR1,&action_handler,NULL);
for(;;) { kill(getpid(),SIGUSR1); sleep(1); }
return 0;
}
在两个不同的Linux发行版上使用gcc-4.4.3和gcc-4.4.5。
答案 0 :(得分:1)
此时,我自己对问题的研究可以作为部分答案提供。
首先,我找到了this article,这是旧的,并没有引用任何官方信息来源:http://zwillow.blogspot.com/2007/04/linux-signal-handling-is-broken.html。这是一个相关的引文:
第二个问题:你不能使用setcontext()离开信号处理程序并跳转到另一个先前保存的上下文中。 (或者,就此而言,您无法使用它返回到作为参数传递给信号处理程序的相同上下文。)换句话说,信号处理程序如
static void sighandler( int signo, siginfo_t *psi, void *pv) { memcpy(puc_old, pv, sizeof(ucontext_t)); /* choose another context to dispatch */ setcontext(puc_another); }
不起作用。它不会恢复puc_other中指定的信号掩码,也不会重新建立备用信号堆栈等。但是,这种方案在Solaris上完美运行。
如果有人可以确认有关Solaris的部分,我们将不胜感激。
其次,在与大学讲师交谈之后,我逐渐明白,在信号处理程序中设置/交换上下文并不像在其他情况下那样直接。可悲的是,向我解释这个问题的人当时无法提供进一步的细节。
因此,我的两个来源似乎都不完全可靠,但仍然是线索。