我面临有关将信号9(SIGKILL)发送到初始化进程(PID 1)的怪异问题。
如您所知,不能通过信号处理程序忽略SIGKILL。当我尝试将SIGKILL发送到init时,我发现没有任何 react 。 init不会终止。为了弄清楚这种行为,我决定通过strace将自己附加到初始化过程中,以便更清楚地了解正在发生的情况。现在来了怪异的部分。如果我正在使用strace“查看”初始化过程并将其发送给SIGKILL,则系统崩溃。

我的问题是为什么会这样?为什么当我查看该过程时系统崩溃,为什么当我不查看该过程时却不崩溃?正如我所说,在两种情况下,我都将SIGKILL发送给init。在CentOS 6.5,Debian 7和Arch上进行了测试。

谢谢!

最佳答案

如果init终止,则Linux内核有意迫使系统崩溃(请参阅http://lxr.free-electrons.com/source/kernel/exit.c?v=3.12#L501,尤其是其中对panic的调用)。因此,作为一种安全措施,内核不会向init传递任何致命信号,并且SIGKILL也不会被排除(请参阅http://lxr.free-electrons.com/ident?v=3.12&i=SIGNAL_UNKILLABLE)(但是,代码流非常复杂,我不确定,但是我怀疑内核生成的SIGSEGV或类似的东西会通过)。

ptrace(2) (strace使用的系统调用)应用于进程1显然会禁用此保护。可以说这是内核中的错误。我没有足够的技巧来挖掘代码来查找此错误。

我不知道其他Unix变体是否对init应用了相同的退出时崩溃语义或信号保护。如果init终止(至少是通过调用_exit终止),则让操作系统执行干净的关机或重新启动而不是 panic 是合理的,但据我所知,所有现代Unix变体都有专用的系统调用以请求此请求,而不是( reboot(2) )。

关于unix - SIGKILL初始化过程(PID 1),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21031537/

10-10 10:16