我们知道 - 除了SIGKILL
和SIGSTOP
- 程序可以拦截 IPC 信号,并运行其内部处理程序来规避默认处理程序的操作。
我至少可以想到一个很好的理由来使用SIGINT
信号进行此操作。
- 即实现一个信号处理程序,该处理程序执行最后一次备份,保存内存转储或写入日志,然后恢复到终止进程的默认信号操作。
我还可以想到一个恶意软件可能会捕获并阻止 SIGINT 的一个很好的理由:
即延长流程的执行时间。对于大多数用户来说,Ctrl+C是大多数终端用户的键盘快捷键,有很多人不知道Ctrl+ Z(
SIGTSTP
它只会停止进程,保留在终端中jobs
),更不用说Ctrl+ \,它发送SIGQUIT
并创建一个核心转储。如果Ctrl+C被捕获并阻止,这些用户可能会尝试打开另一个终端窗口,并按照以下方式运行:
ps aux | grep [process name]
获取进程 PID,并执行 SIGKILL
kill -9 [$PID]
同样,连接到远程计算机上的终端会话的用户将尝试与新的终端会话建立第二个连接,并通过类似的进程/PID 搜索以终止罪魁祸首。显然,这种策略可能只会将进程运行时间延长一小段时间,但即使使用 10MB/s 的高带宽连接的文件传输过程额外 3 分钟也会传输近 2 GB 的额外数据,因此肯定有一些优点它。
然而,最近我注意到——也许只是因为我开始关注它——有些程序似乎属于另一个子集。
这些程序是开源的,并且对软件包进行了足够严格的维护和检查,因此隐藏主要恶意软件代码似乎不太可能。
他们不像
vim
其他文本编辑器那样控制键盘输入他们有内部处理程序可以捕获 SIGINT 并完全忽略它。没有最终的流程终止,并且据了解,没有尝试最后的关键任务。
我的问题:
一个进程可能出于合法目的选择拦截但完全放弃 SIGINT 是否有可能的原因?
换句话说,是否有充分的理由(从代码或系统的角度来看)或情况,当 SIGINT 的捕获和忽略比其已知的会终止正在运行的进程的默认操作更有利时?
正如您所发现的,程序忽略 SIGINT 的最可能原因是错误。表现良好的程序应该尊重信号,通常SIGINT 表示“请退出”,但这不是必需的行为。将 SIGINT 用于其自身目的完全属于程序的权利。与此类似,许多程序(通常是守护进程)使用 SIGHUP 来表示“重新加载配置文件”而不是“您的控制终端已挂起”。
当然,出于这些原因或任何其他原因,程序是否应该以不同的方式处理 SIGINT 是值得商榷的。这可能会让像您这样期望程序合理快速退出的用户感到惊讶或困惑。因此,考虑以不同寻常的方式处理 SIGINT 的行为良好的程序应该确保这种行为在(大多数)用户的上下文中是有意义的。
本文(链接自Wikipedia)详细介绍了 SIGINT 和正确处理,并讨论了在实施 SIGINT 处理时值得考虑的一些边缘情况。