SIGKILL init进程(PID 1)

时间:2014-01-09 21:28:10

标签: unix signals init pid sigkill

我面临一个关于向init进程(PID 1)发送信号9(SIGKILL)的奇怪问题。 您可能知道,SIGKILL不能通过信号处理程序忽略。当我尝试向SIG发送SIGKILL时,我发现没有发生任何事情; init不会被终止。试图弄清楚这种行为,我决定将自己附加到使用strace的init进程,也可以更清楚地看到发生了什么。现在是奇怪的部分。如果我正在使用strace“查看”init进程并将其发送给SIGKILL,则系统崩溃。

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

谢谢!

1 个答案:

答案 0 :(得分:6)

如果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显然会禁用此保护。这可以说是内核中的一个错误。我没有足够的技巧去挖掘代码中找到这个bug。

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