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.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文件最大为100kulimit -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_%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 常用操作

  • 下边列出了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