Linux向进程发送信号及执行信号处理函数的时机
2018-01-23 21:16
736 查看
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()函数执行信号处理程序。
相关文章推荐
- linux信号处理、killall、SIGALRM、sigaction函数和结构体、向进程发送信号
- linux信号处理、killall、SIGALRM、sigaction函数和结构体、向进程发送信号
- linux进程通信---几个发送信号的函数(kill,raise,alarm,pause)
- linux进程通信---几个发送信号的函数(kill,raise,alarm,pause)
- linux进程通信---几个发送信号的函数(kill,raise,alarm,pause)
- linux信号处理--通过发送信号控制进程
- 【linux信号】信号处理函数执行后返回到信号发生处
- 详解Linux内核进程调度函数schedule()的触发和执行时机
- linux进程通信---几个发送信号的函数(kill,raise,alarm,pause)
- linux进程通信---几个发送信号的函数(kill,raise,alarm,pause)
- Linux下C语言编程--信号处理函数
- linux下的僵尸进程处理SIGCHLD信号
- 10_26 当调用system函数时子进程与父进程对信号的处理,尤其是SIGCHLD
- Linux信号处理和守护进程
- Linux信号、信号处理和信号处理函数
- Linux 信号signal处理函数
- [Linux进程]使用atexit登记终止处理函数
- 2信号处理之:信号产生原因,进程处理信号行为,信号集处理函数,PCB的信号集,sigprocmask()和sigpending(),信号捕捉设定,sigaction,C标准库信号处理函数,可重入函数,
- linux系统编程之信号(六):信号发送函数sigqueue和信号安装函数sigaction
- Linux 多线程应用中如何编写安全的信号处理函数