我的进程为什么退出了
近些年有些用户反馈进程退出,协助他们分析问题后,遂将这些问题和场景整理成本文。从经验来看,异常退出的进程主要有如下原因:
- 自身异常退出
- 因 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 +++