![Linux内核如何处理信号](https://linux22.com/image/147984/Linux%E5%86%85%E6%A0%B8%E5%A6%82%E4%BD%95%E5%A4%84%E7%90%86%E4%BF%A1%E5%8F%B7.png)
我的问题是关于信号以及在操作系统内核内部处理它们。
我知道每个进程都有自己的signal_handler()
表:一个31位的信号数组(pending_signals
),当信号到达时,do_signal()被调用,它调用相关的signal_handler()
例程,该例程在用户模式下运行,而不是在内核模式(顺便问一下为什么会这样?)。
假设进程收到了一些信号,即他的信号数组中的某个位处于打开状态,谁正在将其写入该数组(我猜这是调用该信号的进程 - 我们当前处于其上下文中的进程),因此,流程如下:
A
调用信号并将其写入 的B
信号数组(在返回用户模式之前?)然后在相同的上下文中(不切换到 B)调用 的该信号的特定信号处理程序B
(我们什么时候切换到用户模式? ),然后我们返回A
并检查是否需要重新安排并继续……
第二件事是当信号为 时发生的事情SIG_CHILD
,我认为它应该发生在do_exit()
子进程调用的某个地方。
最后一件事是如何waitpid(pid_t num)
运作的?
父亲如何忽略SIG_CHILD
其他儿子的所有信号而只关心特定的儿子?
如果有阅读以下内容的良好来源,那就太好了(没有找到这样的来源)。
答案1
在阅读您的问题时。我认为您说过 的信号句柄B
是在 的上下文中运行的A
。这听起来不正确。这会导致安全漏洞。信号处理程序始终在所属进程的上下文中调用。
这将回答你关于 的第二部分SIG_CHILD
。
您还会问为什么在用户空间中运行信号句柄。这是因为我们不想允许进程将代码注入内核。如果他们这样做了,他们就会成为这个系统的上帝。
信号处理程序在什么进程中运行?
如果一个进程调用 exec,并且加载的代码包含 signal_handler,并且如果此信号处理程序运行,那么(与加载的所有其他代码一样)它会在此进程中运行。您不会发现一个进程中的代码意外地在另一进程中运行。