【问题标题】:SIGKILL init process (PID 1)SIGKILL 初始化进程(PID 1)
【发布时间】:2014-01-09 21:28:10
【问题描述】:

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

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

谢谢!

【问题讨论】:

  • 没有init,我认为您的操作系统无法正常运行。如果你想杀死init,你也可以shutdown/halt/poweroff。
  • 是的,你是对的,但我的“实验”纯粹是出于好奇。
  • 你说得对,这很有趣。

标签: unix signals init pid sigkill


【解决方案1】:

如果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 终止),让操作系统执行干净的关闭或重新启动而不是恐慌是合理的,但据我所知,所有现代 Unix 变体有一个专门的系统调用来请求这个,而不是 (reboot(2))。

【讨论】:

  • 非常感谢您的解释!
  • 顺便说一句,在 Debian 7 上,SIGSEGV 不会使 init 崩溃。在 Arch 和 CentOS 上,确实如此。
  • 恐怕“Debian 7”、“Arch”和“CentOS”都指的是年代不确定的各种软件的大捆绑包,因此这作为数据点毫无用处。此外,如果您尝试过kill -SEGV 1,则不会告诉您 kernel-generated SIGSEGV 会发生什么,例如如果init 实际上试图取消引用一个无效的指针。
猜你喜欢
  • 1970-01-01
  • 2014-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-18
  • 1970-01-01
  • 2020-12-13
  • 2012-01-31
相关资源
最近更新 更多