信号的处理时机--内核态的进程(线程)能kill掉进程吗?
信号在如下时机进行处理:
当从中断或异常(包括系统调用)返回用户态时。
注意:这里是返回“用户态”,也就是说,当当前进程正在内核态执行时,是不能处理信号的,必须等到其返回用户态时才能处理信号。
相关代码如下:
entry_32.S(汇编)
-
ret_from_exception:
-
/*
-
* 这里为什么要关中断?而从中断返回不需要? 因为异常走的是陷阱门,
-
* 默认是不关中断执行的,而中断走的是中断门,默认是关中断执行的?
-
*
-
*/
-
preempt_stop(CLBR_ANY)
-
ret_from_intr:
-
...
-
// 判断是否返回用户态或者v8086模式,如果不是,则转入resume_kernel
-
cmpl $USER_RPL, %eax
-
jb resume_kernel # not returning to v8086 or userspace
-
-
// 如果是返回用户态
-
ENTRY(resume_userspace)
-
LOCKDEP_SYS_EXIT
-
...
-
andl $_TIF_WORK_MASK, %ecx # is there any work to be done on
-
# int/exception return?
-
// 进行信号及其它处理
-
jne work_pending
-
jmp restore_all
-
END(ret_from_exception)
-
-
---
-
work_pending:
-
# 返回用户态时,只需要判断need_resched是否置位,不需要判断preempt_count
-
# 如果need_resched置位,则发生调度,否则跳转到work_notifysig
-
testb $_TIF_NEED_RESCHED, %cl
-
jz work_notifysig
-
...
-
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
-
// 调用C函数,其中进行通知链及信号的处理
-
call do_notify_resume
-
jmp resume_userspace
signal.c
-
do_notify_resume()
-
do_signal()
所以,从这个角度看,处于内核态执行的进程(或线程)是kill不掉了。
类似道理,内核线程也是kill不掉的,至少从用户态是kill不掉的,在kill给内核线程发送信号时,会对pid进行判断,如果目标pid是内核线程,会直接丢弃信号。
阅读(3894) | 评论(0) | 转发(0) |