7

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

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

谢谢!

4

1 回答 1

9

如果init终止,Linux 内核会故意强制系统崩溃(参见http://lxr.free-electrons.com/source/kernel/exit.c?v=3.12#L501,尤其是其中的调用panic)。因此,作为保障措施,内核不会向 传递任何致命信号initSIGKILL也不例外(参见http://lxr.free-electrons.com/ident?v=3.12&i=SIGNAL_UNKILLABLE)(但是,代码流程是足够复杂,我不确定,但我怀疑内核生成的SIGSEGV或类似的会通过)。

ptrace(2)(使用的系统调用strace)应用于进程 1 显然会禁用此保护。这可以说是内核中的一个错误。我不够熟练地在代码中挖掘以找到这个错误。

我不知道其他 Unix 变体是否对init. init如果终止(至少,如果它通过调用),让操作系统执行干净关闭或重新启动而不是恐慌是合理的,_exit但据我所知,所有现代 Unix 变体都有一个专用的系统调用请求这个,而不是(reboot(2))。

于 2014-01-09T21:31:09.783 回答