linux内核信号机制
signal.c 涉及到内核中所有有关信号处理的函数,在linux系统中,信号是一种“软件中断”处理机制。
有许多较为复杂的程序使用到了信号,信号机制提供了一种处理异步事件的方法。
例如当发生硬件异常时,系统也会向正在执行的进程发送相应的信号。
另外一个进程也可以向另一个进程发送信号,例如使用kill()函数向同组的子进程发送终止信号。
在内核代码中通常使用一个无符号长整数(32位)中的比特位来表示各种不同的信号,因此最多可以表示
32个不同的信号。
在本版linux内核中定义了22种不同的信号,
2 对进程来说 ,当收到一个信号的时候,可以有三种不同的处理方式
(1) 忽略该信号。 大多数信号都可以被进程忽略,但是有两个信号忽略不掉:SIGKILL 和 SIGSTOP 。
其原因是为了给超级用户提供一个确定的方法来终止或停止 指定的任何进程。
(2 捕捉该信号。为了进行该操作,我们必须首先告诉内核在指定的信号发生时调用我们自定义的信号处理函数。
在该处理函数中,我们可以做任何操作,也可以什么都不做。自定义信号处理函数来捕获SIGTERM 信号,
并在该函数中做一些清理临时文件的工作。SIGTERM 信号是KILL命令发送的信号。
(3) 执行默认操作。 内核为每种信号都提供一种默认操作。通常这些默认操作就是终止进程的执行。
3 下面主要是对signal.c中的 do_signal()函数的解释,因为这个函数比较难理解
do_signal()函数是内核系统调用(int 0x80)中断处理程序中对信号的预处理程序,在进程每次调用系统调用的时候,
若进程已经接受到信号,则该函数会把信号的处理句柄插入到用户程序堆栈中去。 这样,在当前系统调用结束返回后就会
立刻执行信号句柄程序。
在信号处理程序插入到用户堆栈之前,do_signal()函数会首先把用户程序的堆栈指针向下扩展longs个长字,然后将相应的参数添加进其中。
(2) 当用户程序调用系统调用进入到内核堆栈的时候,内核堆栈如下所示:
内核态堆栈
原SS
原ESP
EFLAGS
CS
EIP
如上图所示,eip已经指向了 信号处理函数,而且现在新的esp也已经指向了 新的位置。