linux 信号响应

  • s4 异常分析

1.信号响应时机

  对一个进程发送一个信号以后,其实并没有硬中断发生,只是简单把信号挂载到目标进程的信号 pending 队列上去,信号真正得到执行的时机是进程执行完异常/中断返回到用户态的时刻。

  让信号看起来是一个异步中断的关键就是,正常的用户进程是会频繁的在用户态和内核态之间切换(这种切换包括:系统调用、缺页异常、系统中断…),所以信号能很快的能得到执行。但这也带来了一点问题,内核进程是不响应信号的,除非它刻意的去查询。所以通常情况下无法通过kill命令去杀死一个内核进程。

在这里插入图片描述

2.信号的响应

  内核在每次跳转到用户空间之前,都会检查一下当前这个 task 的标志状态,如果 TIF_SIGPENDING 标志被置位,那么就说明当前这个 task 有信号需要处理,内核就会开始进行信号的响应处理。下面是内核跳转到用户空间前的汇编代码 ret_from_exception:

arch/mips/kernel/entry.s:

 30 #ifndef CONFIG_PREEMPT
 31 FEXPORT(ret_from_exception)
 32     local_irq_disable           # preempt stop
 33     b   __ret_from_irq
 34 #endif

 37 FEXPORT(__ret_from_irq)
 42 resume_userspace_check:
 43     LONG_L  t0, PT_STATUS(sp)       # returning to kernel mode?
 44     andi    t0, t0, KU_USER
 45     beqz    t0, resume_kernel
 46 
 47     __cond_branch_hazard
 48 resume_userspace:
 49     local_irq_disable       # make sure we dont miss an
 50                     # interrupt setting need_resched
 51                     # between sampling and return
 52     LONG_L  a2, TI_FLAGS($28)   # current->work
 53     andi    t0, a2, _TIF_WORK_MASK  # (ignoring syscall_trace)
 54     bnez    t0, work_pending
 55     j   restore_all
 57 #ifdef CONFIG_PREEMPT
 58     __cond_branch_hazard
 59 resume_kernel:
 60     local_irq_disable
 61     lw  t0, TI_PRE_COUNT($28)
 62     bnez    t0, restore_all
 63 need_resched:
 64     LONG_L  t0, TI_FLAGS($28)
 65     andi    t1, t0, _TIF_NEED_RESCHED
 66     beqz    t1, restore_all
 67     LONG_L  t0, PT_STATUS(sp)       # Interrupts off?
 68     andi    t0, 1
 69     beqz    t0, restore_all
 70     jal preempt_schedule_irq
 71     b   need_resched
 72 #endif

128 work_pending:
129         andi    t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS
130         beqz    t0, work_notifysig
131         __cond_branch_hazard
147 work_notifysig:                         # deal with pending signals and
148                                         # notify-resume requests
149         move    a0, sp
150         li      a1, 0
151         jal     do_notify_resume        # a2 already loaded                                                                                                                                                                              
152         j       resume_userspace_check
  • 第53行:andi t0, a2, _TIF_WORK_MASK # (ignoring syscall_trace)
148 /* work to do on interrupt/exception return */
149 #define _TIF_WORK_MASK          \                                                                                                                                                                                                        
150         (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME |     \
151          _TIF_UPROBE)

  这条指令判断当前的 task 判断标志,如果有需要处理的标志,那么就跳转到 work_pending,在这里判断如果有收到信号,那么就调用 do_signal 进行信号的响应。

arch/mips/kernel/signal.c:
–> do_notify_resume() -> do_signal() -> get_signal()/handle_signal()

  878 asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,                                                                                                                                         
  879     __u32 thread_info_flags)
  880 {
  881     local_irq_enable();
  882 
  883     user_exit();
  884 
  885     if (thread_info_flags & _TIF_UPROBE)
  886         uprobe_notify_resume(regs);
  887 
  888     /* deal with pending signal delivery */
  889     if (thread_info_flags & _TIF_SIGPENDING)
  890         do_signal(regs);
  891 
  892     if (thread_info_flags & _TIF_NOTIFY_RESUME) {
  893         clear_thread_flag(TIF_NOTIFY_RESUME);
  894         tracehook_notify_resume(regs);
  895         rseq_handle_notify_resume(NULL, regs);
  896     }
  897 
  898     user_enter();
  899 }

refer to

  • https://wushifublog.com/2020/05/16/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3Linux%E5%86%85%E6%A0%B8%E2%80%94%E2%80%94signals/
  • http://lzz5235.github.io/2015/06/04/signal.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值