2010-09-03 41 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