C++项目遇到Aborted (core dumped)的处理方法
文章目录 一. 关于Core Dump的分析 1.1. 什么是Core Dump 1.2. 为何有时程序Down了,却没生成 Core文件 1.3. 如何使用core文件 二. 具体实例分析 2.1. core dump的生成方式 2.1.1. 查看生成core文件的开关是否开启,输入命令 2.1.2.使用ulimit -c [kbytes] 可以设置系统允许生成的core文件大小。 2.1.3. 指定生成文件的路径和名字 2.1.4. 使用GDB确定错误 2.2. GDB 常用操作 三. 参考文献
一. 关于Core Dump的分析
1.1. 什么是Core Dump
Core Dump是一个运行时错误。Core的意思是内存, Dump的意思是扔出来, 堆出来。在开发(或使用)一个程序时,有时程序莫名其妙的down了, 却没有任何的提示(有时候会提示core dumped)。虽然系统没事,但我们下次仍可能遇到相同的问题。这时候可以查看一下有没有形如core.PID的core文件生成,这个文件便是操作系统把程序down掉时的内存内容扔出来生成的,让我们或是debugger做为参考。这个动作就叫作core dump。core dump又叫核心转储 , 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump。简而言之,进程异常终止,进程用户空间的数据就会被写到磁盘。
1.2. 为何有时程序Down了,却没生成 Core文件
有时候程序down了, 不像编译错误一样会提示到文件一行,而是没有任何信息。一种办法是用gdb的step(linux下调试工具gdb是很强大的调试器), 一步一步寻找,但要step一个上万行的代码让人难以想象。 我们还有更好的办法,这就是core file。 但是core文件却没有生成,这是因为core.PID的core文件的生成跟你当前系统的环境设置有关系,系统默认core文件的大小为0 (注意core file size (blocks, -c) 0这行,这表示的是分配给core文件的长度(单位为字节,一个块的大小要分系统而定了),为0肯定是不得行的,那就修改之),我的下面截图是不为0的
1.3. 如何使用core文件
发生core dump之后,使用gdb查看core文件的内容, 以定位文件中引发core dump的行,在在Linux下,查看core文件中的出错堆栈信息有二种方式,使用:gdb -c core.pid program_name或gdb [program_name] [core.pid]可以进入gdb模式: 在进入gdb后输入where并回车,就可以指出是在哪一行被Down掉,在哪个函数内,由谁调用等等。 在进入gdb后输入 bt,用bt命令查看backtrace以检查发生程序运行到哪里,来定位core dump的文件->行。
二. 具体实例分析
注意:如果程序是在docker中运行的,记得启动docker的时候加上--privileged 参数,该参数让 container内的root拥有真正的root权限。否则,container内的root只是外部的一个普通用户权限。privileged启动的容器,可以看到很多host上的设备,并且可以执行mount。甚至允许你在docker容器中启动docker容器 。
2.1. core dump的生成方式
Linux环境下进程发生异常而挂掉,通常很难查找原因,但是一般Linux内核给我们提供的核心文件,记录了进程在崩溃时候的信息 。但是生成core文件需要设置开关,具体步骤如下:
2.1.1. 查看生成core文件的开关是否开启,输入命令
ulimit -a
2.1.2.使用ulimit -c [kbytes] 可以设置系统允许生成的core文件大小。
ulimit -c 0
ulimit -c 100
ulimit -c unlimited
执行命令 ulimit -c unlimited,然后ulimit -a查看core
注意: 这样进程崩溃就可以生成core文件了,这种方法只能在shell中生效,需要此设置一直生效需要做如下设置
vim / etc/profile
ulimit - c unlimited
source / etc/profile
2.1.3. 指定生成文件的路径和名字
默认情况下,core dump生成的文件名为core,而且就在程序当前目录下 。新的core会覆盖已存在的core, 通过修改/proc/sys/kernel/core_uses_pid文件,可以控制core文件保存位置和文件格式。
vim / etc/sysctl. conf
kernel. core_pattern=/ tmp/corefile/core_%t_%e_%p
kernel. core_uses_pid=0
这里说一下core_pattern的命名参数如下:
% c 转储文件的大小上限
% e 所dump的文件名
% g 所dump的进程的实际组ID
% h 主机名
% p 所dump的进程PID
% s 导致本次coredump的信号
% t 转储时刻( 由1970年1月1日起计的秒数)
% u 所dump进程的实际用户ID
执行如下命令,设置修改马上生效,并且创建/tmp/corefile目录
sysctl - p / etc/sysctl. conf
mkdir / tmp/corefile
2.1.4. 使用GDB确定错误
gdb . / test_license / tmp/corefile/core_1680515069_test_license_24078
如果最后报出的信息是系统库,则可以在gdb下输入bt来调出堆栈信息,如果是多线程,则输入thread apply all backtrace 来显示所有线程栈回溯。我这里是原因是配置文件中忘记写use_keyframe_only
2.2. GDB 常用操作
启动程序:run
设置断点:b 行号| 函数名
删除断点:delete 断点编号
禁用断点:disable 断点编号
启用断点:enable 断点编号
单步跟踪:next 也可以简写 n
单步跟踪:step 也可以简写 s
打印变量:print 变量名字
设置变量:set var =value
查看变量类型:ptype var
顺序执行到结束:cont
顺序执行到某一行: util lineno
打印堆栈信息:bt
三. 参考文献
Linux 生成 core dump的方法及设:https://www.cnblogs.com/flyinggod/p/13415862.html Linux遇到Aborted (core dumped):https://blog.csdn.net/qq_35091353/article/details/112101738 C++项目经验(8)—— GDB快速定位程序崩溃(coredump)在哪行:https://blog.csdn.net/ROseeattimoo/article/details/127157248