C++项目遇到Aborted (core dumped)的处理方法 |
一. 关于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
- 如果第一行core文件大小为0,没有开启。
2.1.2.使用ulimit -c [kbytes] 可以设置系统允许生成的core文件大小。
ulimit -c 0 #不产生core文件
ulimit -c 100 #设置core文件最大为100k
ulimit -c unlimited #不限制core文件大小
- 执行命令
ulimit -c unlimited
,然后ulimit -a
查看core
- 注意: 这样进程崩溃就可以生成core文件了,这种方法只能在shell中生效,需要此设置一直生效需要做如下设置
vim /etc/profile
# 然后进入编辑模式,在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
文章来源:https://www.toymoban.com/news/detail-406270.html
- 如果最后报出的信息是系统库,则可以在gdb下输入
bt
来调出堆栈信息,如果是多线程,则输入thread apply all backtrace
来显示所有线程栈回溯。我这里是原因是配置文件中忘记写use_keyframe_only
文章来源地址https://www.toymoban.com/news/detail-406270.html
2.2. GDB 常用操作
- 下边列出了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
到了这里,关于『C/C++养成计划』Linux遇到Aborted (core dumped)的处理方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!