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()函数执行信号处理程序。

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