『C/C++养成计划』C++项目遇到Aborted (core dumped)的处理方法

C++项目遇到Aborted (core dumped)的处理方法

一. 关于Core Dump的分析

在这里插入图片描述

1.1. 什么是Core Dump

  • Core Dump是一个运行时错误。
  • Core的意思是内存, Dump的意思是扔出来, 堆出来。在开发(或使用)一个程序时,有时程序莫名其妙的down了, 却没有任何的提示(有时候会提示core dumped)。虽然系统没事,但我们下次仍可能遇到相同的问题。这时候可以查看一下有没有形如core.PIDcore文件生成,这个文件便是操作系统把程序down掉时的内存内容扔出来生成的,让我们或是debugger做为参考。这个动作就叫作core dump
  • core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump简而言之,进程异常终止,进程用户空间的数据就会被写到磁盘。

1.2. 为何有时程序Down了,却没生成 Core文件

  • 有时候程序down了, 不像编译错误一样会提示到文件一行,而是没有任何信息。一种办法是用gdbsteplinux下调试工具gdb是很强大的调试器), 一步一步寻找,但要step一个上万行的代码让人难以想象。 我们还有更好的办法,这就是core file
  • 但是core文件却没有生成,这是因为core.PIDcore文件的生成跟你当前系统的环境设置有关系,系统默认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_namegdb [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
  • 如果第一行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 

在这里插入图片描述

  • 如果最后报出的信息是系统库,则可以在gdb下输入bt来调出堆栈信息,如果是多线程,则输入thread apply all backtrace 来显示所有线程栈回溯。我这里是原因是配置文件中忘记写use_keyframe_only

在这里插入图片描述

2.2. GDB 常用操作

  • 下边列出了GDB一些常用的操作。
启动程序:run
设置断点:b 行号|函数名
删除断点:delete 断点编号
禁用断点:disable 断点编号
启用断点:enable 断点编号
单步跟踪:next 也可以简写 n
单步跟踪:step 也可以简写 s
打印变量:print 变量名字
设置变量:set var=value
查看变量类型:ptype var
顺序执行到结束:cont
顺序执行到某一行: util lineno
打印堆栈信息:bt

三. 参考文献

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI新视界

感谢您的打赏,我会继续努力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值