近些年有些用户反馈进程退出,协助他们分析问题后,遂将这些问题和场景整理成本文。从经验来看,异常退出的进程主要有如下原因:

  • 自身异常退出
  • 因 OOM 被系统杀死
  • 被其它进程杀死

自身异常退出

进程退出很大一部分原因是业务方自身的问题,比如:

  • 内存访问越界
  • 非法指针
  • 堆栈溢出
  • 访问只读内存等等

开启 core dump 并且不限制 coredump 文件的大小。

ulimit -c unlimited

如果进程退出,则会在相关目录生成 coredump 文件,后续可用相关工具进行定位。

被系统 OOM

如果进程内存超出限制,会被内核或者 cgroup 杀死,请查询 /var/log/message 日志文件,或者通过 dmesg 命令找出 oom 详情。

被其它进程杀死

当进程收到其它进程发来的 SIGKILL 或者 SIGTERM 信号也会退出。我们常用通过如下工具来捕捉信号:

但是 audit 不支持在容器中运行,而 systemtap 的安装配置复杂,特别对于容器,操作更是繁杂。这时 strace 又一次显示了它强大的功能,借用 strace 可以定位哪个进程给本进程发送什么信号,例如:

在终端窗口 1 执行:

root@master:~ # sleep 10000 &
[1] 6922

root@master:~ # strace -tt -v -p 6922
Process 6922 attached
21:28:42.585287 restart_syscall(<... resuming interrupted call ...>) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)

在终端窗口 2 执行如下命令,杀死 sleep 进程:

root@master:~ # kill -15 6922 &
[1] 6984

终端窗口 1 显示:

21:28:54.496291 --- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=6984, si_uid=0} ---
21:28:54.496423 +++ killed by SIGTERM +++