关于将信号9(SIGKILL)发送到init进程(PID 1),我遇到了一个奇怪的问题.您可能知道,SIGKILL不能通过信号处理程序忽略.当我尝试将SIGKILL发送给init时,我发现没有发生任何事情; init不会被终止.试图弄清楚这种行为,我决定将自己附加到使用strace的init进程,也可以更清楚地看到发生了什么.现在是奇怪的部分.如果我用strace"查看"init进程并发送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显然会禁用此保护.这可以说是内核中的一个错误.我在挖掘代码中找不到这个bug是不够熟练的.
我不知道其他Unix变种是否应用相同的崩溃退出语义或信号保护init
.让操作系统执行干净关机或重启是合理的,而不是恐慌,如果init
终止(至少,如果它通过调用这样做_exit
)但据我所知,所有现代Unix变种都有一个专用的系统调用请求这个,而不是(reboot(2)
).