一、概述
使用c++开发程序时,经常会遇到运行中core的情况,如果是偶发的就更加难以定位,本文讲解如何使用gdb进行core位置的分析定位。
二、打开coredump文件生成
# 1. 支持产生coredump
# 查看当前设置
cat /etc/security/limits.conf|grep core
ulimit -c # 如果是unlimited,说明设置成功
# 设置(最好加到业务启动命令里)
ulimit -c unlimited
# 2.控制core文件保存位置和文件名格式
# 查看目前使用的方式
cat /proc/sys/kernel/core_pattern
# 修改生成位置和命名规则(必须bash -c 'echo xxx'方式,不能通过vi修改)
sudo bash -c 'echo "/coredump/%e_%p_%t.core" > /proc/sys/kernel/core_pattern'
# 命名格式参数:
%p - insert pid into filename 添加pid
%u - insert current uid into filename 添加当前uid
%g - insert current gid into filename 添加当前gid
%s - insert signal that caused the coredump into the filename 添加导致产生core的信号
%t - insert UNIX time that the coredump occurred into filename 添加core文件生成时的unix时间
%h - insert hostname where the coredump happened into filename 添加主机名
%e - insert coredumping executable name into filename 添加命令名
# qnx系统下没有/proc/sys/kernel/core_pattern文件,需要用命令指定保存目录
dumper -d /coredump/
# 3.测试让程序产生一个coredump
kill -6 $pid
kill -11 $pid
三、使用gdb分析core
1、使用gdb分析coredump文件
# gdb <program> core
gdb ./bin/ipc_server ipc_server.core # 必须使用与core时一样的bin/lib文件
(gdb) set args zmq 6000 # 指定运行时的参数
(gdb) bt # backtrace显示当前调用堆栈
(gdb) q # 退出gdb
2、使用gdb调试bin文件
# gdb <program>
gdb ./bin/ipc_server
(gdb) set args zmq 6000 # 指定运行时的参数
(gdb) set env USER=yan # 设置环境变量
#(gdb) b main # 添加调试断点:main函数入口
#(gdb) b test.cc:1618 # 添加调试断点:test.cc文件的第1618行
#(gdb) b test.cc:func # 添加调试断点:test.cc文件的func函数入口
#(gdb) info b # 显示设置的所有断点
#(gdb) delete <bid> # 删除某个断点
(gdb) r # run运行程序,直到遇到断点、coredump或正常结束
#(gdb) n # 断点next运行到下一行
#(gdb) s # 断点step单步执行,遇到函数会进入
(gdb) bt # backtrace显示当前调用堆栈
(gdb) quit # 退出gdb
三、使用gdb/strace分析进程或线程卡死
1、使用gdb定位假死进程
# gdb -p <PID> 或 gdb <program> <PID>
# 找到运行中的进程PID
ps aux | grep ipc_server
# 启动gdb,附加到PID=xxx的进程
gdb -p xxxx 或 gdb ./bin/ipc_server xxxx
# 查看进程信息
(gdb) bt # 查看当前堆栈跟踪(可多次运行查看变化,以确认是否已卡死在某个位置)
(gdb) info threads # 显示所有线程运行情况
(gdb) thread apply all bt # 显示所有线程的堆栈跟踪(可多次运行查看变化,以确认是否死锁假死等)
# 完成后分离和退出
(gdb) detach
(gdb) quit
2、使用strace定位进程的线程卡死状态
strace -T -tt -f -p <PID> -o strace.log # 从log中查看线程ID的状态
xxxx 20:44:50.328393 futex(0xaaaaede91058, FUTEX_WAIT_PRIVATE, 0, NULL <unfinished ...>
参考:
【调试】Linux查看程序卡死位置|GDB|分析进程调用pstack和starce|分析耗时函数