进程被 kill -9 杀掉后找不到日志,因为 SIGKILL 不可捕获,进程立即终止且不执行任何清理逻辑;需排查 oom_killer、容器运行时、人为 kill 或 systemd 超时等来源。

进程被 kill -9 杀掉后为什么找不到日志?
因为 SIGKILL(信号 9)无法被捕获、阻塞或忽略,进程在收到该信号后立刻终止,连清理逻辑(比如写日志、关闭文件描述符)都不会执行。所以你查 systemd 日志、应用自身日志、甚至 strace 跟踪都看不到“主动退出”痕迹。
真正要查的不是“它怎么退出”,而是“谁发了 SIGKILL”。常见来源有:
-
oom_killer:内存耗尽时内核主动干掉进程,会在dmesg中留下记录,关键词是Out of memory: Kill process - 容器运行时(如
dockerd或containerd)因内存 limit 触发 OOM,也会走内核 oom_killer 流程 - 人为执行了
kill -9,但没留操作记录;可检查auditd日志(/var/log/audit/audit.log)中SYSCALL arch=c000003e syscall=62 success=yes(对应kill系统调用) -
systemd的TimeoutStopSec超时后 fallback 到SIGKILL,此时journalctl -u xxx.service会显示Stopping timed out. Killing.
如何确认是不是 oom_killer 干的?
直接看内核环形缓冲区:
dmesg -T | grep -i "killed process"
注意时间戳是否与进程终止时间吻合。如果匹配,你会看到类似:
[Wed Jun 12 14:22:35 2024] Out of memory: Kill process 12345 (python3) score 892 or sacrifice child
关键字段解释:
-
score是 oom_score,数值越高越可能被选中;可通过cat /proc/12345/oom_score查看当前值 -
sacrifice child表示杀的是子进程而非主进程,说明父进程还在,但某个子任务吃光了内存 - 该日志只存在于内核 log,不会进
journald,也不会写入任何用户空间日志文件
进程收到 SIGTERM 却没响应?检查 signal handler 是否被覆盖
很多程序用 signal() 或 sigaction() 注册 SIGTERM 处理函数,但第三方库(尤其是 C 扩展或嵌入式运行时)可能重置信号行为。典型表现是:手动 kill 后进程卡住不退出。
验证方式:
- 用
strace -p观察是否收到-e trace=signal SIGTERM,以及是否调用了rt_sigaction设置 handler - 检查进程是否屏蔽了
SIGTERM:cat /proc/,输出是十六进制掩码,需转换——/status | grep SigBlk SIGTERM对应 bit 15(从 0 开始计),若该位为 1 则被屏蔽 - Python 进程尤其容易出问题:若主线程已退出,而子线程仍在运行且未设
daemon=True,SIGTERM可能无法触发atexit或signal.signal()注册的回调
用 strace 捕获信号传递全过程
strace 是唯一能在用户态看到“信号到达→处理→返回”的工具,但默认不显示信号细节。正确用法是:
strace -e trace=signal,process -f -p
其中:
-
signal跟踪kill、sigreturn、rt_sigprocmask等信号相关系统调用 -
process跟踪fork、execve、exit_group,便于关联父子进程行为 -
-f必须加,否则子线程/子进程的信号事件看不到
典型输出片段:
--- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=1001, si_uid=0} ---
rt_sigreturn({mask=[]}) = 0
exit_group(143) = ?
这表示进程收到了用户态发起的 SIGTERM,执行了信号返回,然后调用 exit_group 正常退出。如果只有第一行而没有后续,说明 handler 没有调用 exit 或被阻塞了。
信号调试最难的一点:它发生在内核和用户栈交界处,既不能靠源码断点(handler 可能不在你的代码里),也不能靠日志(log 写入本身可能被信号中断)。必须用 strace 或 perf trace -e syscalls:sys_enter_kill 这类内核级观测手段。










