2010-09-03 33 views
6

当进程正在执行阻塞系统调用,比如读或写,信号已经到达。 系统调用是否以错误EINTR结束? 处理系统调用后系统调用是否重新启动?问题与信号处理,中断处理

假设系统调用以错误EINTR结束,内核在回到用户空间之前处理信号。

信号句柄是否在用户模式/内核模式下执行? 如果处于用户模式,那么在系统调用(读/写)后信号到达或在处理信号后再次进入内核模式并从ret_from_syscall返回给用户,将会返回到指令。信号到达时系统调用旁边的指令如何恢复执行?

是否可以通过在sigaction中传递SA_RESTART标志来重新启动系统?

回答

3

信号在用户执行模式,但具有不同的用户上下文,然后返回到内核,它返回与ret_from_syscall到user_mode。 当SA_RESTART安装信号处理程序时,系统调用的行为取决于系统调用。

哪个系统调用的描述重新启动可在最新版本的signal overview manpage的:

man 7 signal 

如果不使用SA_RESTART标志,系统调用不重新启动。

+1

现在我明白了你的意思是在用户模式下用不同的用户上下文执行信号。在进程接收到信号的情况下,进程切换到内核模式,以处理在当前进程的信号阵列的位掩码中设置的异常。在返回到用户模式之前,内核会检查待处理的信号并调用do_signal函数来处理信号,然后调用handle_signal来复制内核硬件上下文,并通过调用setup_frame来修改用户模式堆栈。 – 2010-09-21 19:50:19

+0

新的堆栈帧包含signum,指向用户模式信号处理程序的PC值,包含系统调用sigreturn地址的返回地址字段。在进程返回用户模式时,它开始执行信号处理程序,并在终止时执行sigreturn,这使进程切换到内核模式,其中来自用户模式堆栈的硬件环境通过restore_sigcontext被复制回内核堆栈(将用户模式堆栈还原到原始状态)。当sigreturn系统调用终止时,进程切换回用户模式,并在信号前继续离开。 – 2010-09-21 19:54:48

+0

重要的是要注意SA_RESTART并不总是适用。无论是否使用SA_RESTART,某些接口在被信号处理程序中断后都不会重新启动;当被信号处理程序中断时,它们总是失败,出现错误EINTR。检查[信号手册页的详细信息](http://man7.org/linux/man-pages/man7/signal.7.html)。 – kikeenrique 2013-09-20 08:29:47