Linux系统不记录信号发送历史,因信号是内核向进程发送的瞬时异步通知,仅修改task_struct中pending位图,不落盘、不记日志;需提前配置auditd规则(如auditctl -a always,exit -F arch=b64 -S kill)才能捕获kill系统调用。

Linux系统不记录信号发送的历史记录。
这不是功能缺失,而是设计使然:信号是内核向进程发送的瞬时、异步通知,本身不带持久化日志属性。内核在发送信号时,只是把对应编号写入目标进程 PCB(task_struct)中的 pending 位图,然后由调度器在合适时机触发处理——整个过程不落盘、不记日志、不存档。
所以,如果你在找类似“进程 A 在 14:23:05 向进程 B 发送了 SIGTERM”这样的操作痕迹,默认情况下——
✅ 系统不会保存
❌ journalctl、/var/log/*、ps、/proc/*/status 都查不到
❌ auditd 也不会捕获,除非你提前配置了专门针对 kill() 系统调用的审计规则
真实可行的排查路径(需提前部署或间接推断)
✅ 查看当前哪些信号正挂起在进程中
适用于诊断“为什么进程没响应”:
-
cat /proc/[PID]/status | grep SigQ:显示 pending + blocked 信号队列长度 -
cat /proc/[PID]/status | grep SigPnd:十六进制位图,表示已收到但尚未处理的信号(pending) -
cat /proc/[PID]/status | grep SigBlk:被阻塞的信号掩码
示例:
SigPnd: 0000000000000002表示第 2 号信号(SIGINT)已送达但未处理。
✅ 审计 kill 系统调用(唯一接近“历史记录”的方式)
必须提前启用 auditd 并添加规则:
sudo auditctl -a always,exit -F arch=b64 -S kill -F a2=0 -k signal_kill
之后可用:
sudo aureport -m --key signal_kill --start today
输出会包含:谁(uid)、哪个进程(pid)、向谁(a1 参数为目标 pid)、发了什么信号(a2 是信号编号)。
⚠️ 注意:
- 规则中
a2=0表示匹配所有信号;若只关心 SIGTERM,可写a2=15 - 没启用 auditd 就没有数据,事后无法补录
✅ 结合 systemd 日志反推服务级信号行为
如果进程由 systemctl 管理,且因 OOM、超时或依赖失败被自动终止,journald 可能记录上下文:
journalctl -u nginx.service --since "2026-09-15" | grep -i -E "(killed|oom|timeout|stopping)"
但这不是“信号发送记录”,而是服务管理器的决策日志,信号只是执行手段之一。
✅ shell 历史 + 进程启动时间交叉比对(仅限人工回忆场景)
比如你记得自己执行过:
kill -USR2 12345
那就查:
history | grep "kill.*12345" ps -o pid,comm,lstart -p 12345 2>/dev/null
再结合应用自身日志(如 Nginx 收到 USR2 会 reload,通常会在 error_log 写一行),才能拼出完整链条。
为什么没有默认信号历史?
- 信号本质是轻量级事件通知,类似“拍一下肩膀”,不是 RPC 或事务操作
- 记录每次
kill()调用会产生显著性能开销和磁盘压力(尤其高频场景) - 安全上也需权衡:过度日志可能暴露敏感操作意图
所以 Linux 的哲学是:需要日志,就主动加;不加,就不该有。
不复杂但容易忽略











