Linux向進程發送信號及執行信號處理函數的時機

Linux內核中由於不同原因(例如非法地址、按下Ctrl+C、用戶進程系統調用等等)向進程發送信號的函數調用路徑最後公用的函數是send_signal(),這個函數位於linux-3.13/kernel/signal.c文件中。這個函數接下來的調用鏈爲complete_signal()->signal_wake_up()->signal_wake_up_state()->wake_up_state()->try_to_wake_up()函數,從上一篇文章可以知道try_to_wake_up()函數做了三件事:將任務重新添加到就緒隊列,將運行標誌設置爲TASK_RUNNING,如果被喚醒的任務可以搶佔當前運行任務則設置當前任務的TIF_NEED_RESCHED標誌。
在發生中斷時,系統在將中斷向量號壓入堆棧後,會跳轉到linux-3.13/arch/x86/kernel/entry_32.S中的common_interrupt處運行,其代碼如下:

common_interrupt:
    ASM_CLAC
    addl $-0x80,(%esp) /* Adjust vector into the [-256,-1] range */
    SAVE_ALL
    TRACE_IRQS_OFF
    movl %esp,%eax
    call do_IRQ            //調用do_IRQ函數,是個C函數,在此函數中處理中斷
    jmp ret_from_intr      //從中斷返回
ENDPROC(common_interrupt)

其中do_IRQ()是個C函數,它先取得對應的中斷請求描述符,然後執行該中斷請求描述符中的中斷處理函數,最後軟中斷也會在這個函數中運行。執行完do_IRQ()函數之後,會跳轉到ret_from_intr處,之後的執行序列會先檢查TIF_NEED_RESCHED標誌,決定是否進行調度,然後會進行信號的投遞,代碼如下:

work_pending:
    testb $_TIF_NEED_RESCHED, %cl
    jz work_notifysig
work_resched:
    call schedule
    LOCKDEP_SYS_EXIT
    DISABLE_INTERRUPTS(CLBR_ANY)    # make sure we don't miss an interrupt
                    # setting need_resched or sigpending
                    # between sampling and the iret
    TRACE_IRQS_OFF
    movl TI_flags(%ebp), %ecx
    andl $_TIF_WORK_MASK, %ecx # is there any work to be done other
                    # than syscall tracing?
    jz restore_all
    testb $_TIF_NEED_RESCHED, %cl
    jnz work_resched

work_notifysig:             # deal with pending signals and
                    # notify-resume requests
#ifdef CONFIG_VM86
    testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)
    movl %esp, %eax
    jne work_notifysig_v86      # returning to kernel-space or
                    # vm86-space
1:
#else
    movl %esp, %eax
#endif
    TRACE_IRQS_ON
    ENABLE_INTERRUPTS(CLBR_NONE)
    movb PT_CS(%esp), %bl
    andb $SEGMENT_RPL_MASK, %bl
    cmpb $USER_RPL, %bl
    jb resume_kernel
    xorl %edx, %edx
    call do_notify_resume              //在這個函數中進行信號處理函數的執行
    jmp resume_userspace

然後在do_notify_resume()中會調用do_signal()函數執行信號處理程序。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章