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
,用b
t命令查看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 0ulimit -c 100ulimit -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.confkernel.core_pattern=/tmp/corefile/core_%t_%e_%pkernel.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.confmkdir /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