工具:GDB 分析
导致进程异常退出的这两类情况:
第一类:向进程发送信号导致进程异常退出;
第二类:代码错误导致进程运行时异常退出。
代码错误导致异常退出的场景有:
内存非法访问是指:进程在运行时尝试访问尚未分配(即,没有将物理内存映射进入进程虚拟内存空间)的内存,或者进程尝试向只读内存区域写入数据。当进程执行内存非法访问操作时,内存管理单元 MMU 会产生内存保护异常 GPF(General Protection Fault),异常号是 13。系统会立刻暂停进程的非法操作,并且跳转到 GPF 的异常处理程序,终止进程运行。
当进程执行除 0 操作时,处理器上的浮点单元 FPU(Floating-point unit) 会产生 DEE 除 0 异常 (Divide Error Exception),异常号是 0。
异常处理函数首先查看异常是否可以恢复。如果无法恢复异常,异常处理函数向进程发送信号。发送的信号根据异常类型而定,比如内存保护异常 GPF 相对应的信号是 SIGSEGV,而除 0 异常 DEE 相对应的信号是 SIGFPE;
所以,信号是进程异常退出的直接原因。当进程异常退出时,进程必然接收到了信号。因此,信号,是第一消息来源。
那么如何抓Core Dump呢?具体方法,就需要按照下面的方法来逐步操作:
服务器配置
Linux配置服务器
#ulimit -c unlimited //ulimit -c 如果为0,说明关闭了core dump
#echo “ulimit -c unlimited” >> /etc/profile
# cat /proc/sys/kernel /core_uses_pid //如果为1,则产生的core文件名
# echo “/corefile/core-%e-%p-%t” > /proc/sys/kernel/core_pattern //修改文件存储路径及名称,产生的文件名为core-命令名-pid-时间戳
# reboot //重启服务器,配置生效
# kill -s SIGSEGV $$ //验证,看是否在corefile下生成了core-bash-2143-149760
win配置服务器
参见:https://help.aliyun.com/knowledge_detail/41013.html
使用Core文件
#kill -s SIGSEGV $$ //发送“无效内存引用信号”
# which gdb
/usr/bin/gdb
# gdb -c core-bash-2143-1497604833 top
(gdb) bt //键入bt,用bt命令查看backtrace以检查发生程序运行到哪里, 来定位core dump的文件->行
[New LWP 2143]
Core was generated by `-bash’.
Program terminated withsignal 11, Segmentation fault.
查看11对应的信号内容为“无效的内存引用”符合预期
分析方法:
1) 首先,分析 core dump 查看导致进程异常退出的具体信号和退出原因。
# gdb demoSegfault core.24065
Program terminated with signal 11, Segmentation fault.
分析结果显示,终止进程运行的信号是 11,SIGSEGV,原因是内存非法访问。
2) 然后,定位错误代码。输入“bt”指令打印进程退出时的代码调用链,用 gcc 编译程序时加入参数 -g 可以生成符号文件,帮助调试
# gcc -o demoSegfault demoSegfault.c -g
3) 最后,在定位到错误代码行后,就可以很快知道根本原因,并且修改错误代码
注意:
如何判断一个文件是coredump文件
readelf -h $file 看type类型是否为core
可以通过简单的file命令进行快速判断
信号含义备查:
Linux支持的信号列表如下。很多信号是与机器的体系结构相关的
信号值 默认处理动作 发出信号的原因
SIGHUP 1 A 终端挂起或者控制进程终止
SIGINT 2 A 键盘中断(如break键被按下)
SIGQUIT 3 C 键盘的退出键被按下
SIGILL 4 C 非法指令
SIGABRT 6 C 由abort(3)发出的退出指令
SIGFPE 8 C 浮点异常
SIGKILL 9 AEF Kill信号
SIGSEGV 11 C 无效的内存引用
SIGPIPE 13 A 管道破裂: 写一个没有读端口的管道
SIGALRM 14 A 由alarm(2)发出的信号
SIGTERM 15 A 终止信号
SIGUSR1 30,10,16 A 用户自定义信号1
SIGUSR2 31,12,17 A 用户自定义信号2
SIGCHLD 20,17,18 B 子进程结束信号
SIGCONT 19,18,25 进程继续(曾被停止的进程)
SIGSTOP 17,19,23 DEF 终止进程
SIGTSTP 18,20,24 D 控制终端(tty)上按下停止键
SIGTTIN 21,21,26 D 后台进程企图从控制终端读
SIGTTOU 22,22,27 D 后台进程企图从控制终端写
参考文档:
阿里云 Linux Core dump 详解:https://yq.aliyun.com/articles/74174
详谈Unix环境进程异常退出:https://www.ibm.com/developerworks/cn/aix/library/1206_xiejd_unixexception/