Linux进程core dump机制

前言

当程序在运行的过程中出现异常终止或崩溃,系统会将程序当时的状态记录下来,保存在一个core文件中,这种机制称为Core Dump,又称“核心转储”。Core dump机制记录了程序异常时的内存数据、寄存器状态以及运行堆栈等信息,开发人员可以使用调试工具分析Core文件来快速定位程序异常原因。

Core dump基本配置

core文件的生成开关和大小限制

ulimit命令的-c选项专门用于控制core文件的生成以及对core文件大小进行限制:

  • 使用ulimit -c命令可查看core文件的生成开关。若结果为0,则表示关闭了此功能,不会生成core文件;
  • 使用ulimit -c filesize命令,可以限制core文件的大小(filesize的单位为kbyte)。如果生成的信息超过此大小,将会被裁剪,最终生成一个不完整的core文件,在调试此core文件的时候,gdb会提示错误。若设置成ulimit -c unlimited,则表示core文件的大小不受限制。

使用ulimit命令打开core文件的生成开关,并且不限制core文件的生成大小:
在这里插入图片描述
命令执行完成后,系统就会在程序崩溃时,为其生成核心转储文件。需要注意的,上述的配置是临时性的,在系统重启后就会丢失,为了配置永久有效,需要将修改保存到配置文件中。这里修改方式有两种:

  • 修改/etc/profile文件:在/etc/profile文件中,添加ulimit -c unlimited,然后保存退出即可。如果要让配置立即生效,可以执行source /etc/profile命令;
  • 修改/etc/security/limits.conf文件:将#* soft core 0修改成:* soft core unlimited即可。

core文件的名称和生成路径

默认情况下,core文件生成在可执行文件运行命令的同一路径下。若系统生成的core文件不带其它任何扩展名称,则全部命名为core,并且新的core文件生成将覆盖原来的core文件。Linux在proc文件系统中提供了入口用以支持对core文件的名称以及生成路径进行配置:

  • /proc/sys/kernel/core_uses_pid:该参数用于控制core文件的文件名中是否添加pid作为扩展。文件内容为1,表示添加pid作为扩展名;
  • /proc/sys/kernel/core_pattern:该参数用于控制core文件保存位置和文件名格式,也是core dump的主要配置入口。

为了配置core文件保存到特定的目录下,可以通过以下命令修改/proc/sys/kernel/core_pattern文件的内容(需要注意的是配置的路径必须是有效的,否则core文件无法生成):
在这里插入图片描述
上述的命令会让系统在进程崩溃时将core文件统一生成到/corefile目录下,并且产生的core文件名格式为core-命令名-pid-时间戳,其中使用到了一些格式化参数。core_pattern文件支持的参数及其意义罗列如下:

  • %p:添加core dump进程的进程ID
  • %u:添加core dump进程的用户ID
  • %g:添加从热 dump进程的组ID
  • %s:添加触发进程core dump的信号类型
  • %t:添加进程core dump的时间
  • %h:添加主机名
  • %e:添加可执行程序文件名

使用sysctl进行配置

sysctl命令用于运行时配置内核参数,这些参数位于/proc/sys目录下,因此也可以使用sysctl配置core文件:
在这里插入图片描述
除了直接使用命令的方式,sysctl支持使用/etc/sysctl.conf配置文件的方式对内核参数进行配置,对应的参数项依次为:

  1. kernel.core_uses_pid
  2. kernel.core_pattern

Core文件的生成与使用

准备测试程序:

#include <stdio.h>
#include <stdlib.h>

int crash()
{
    char *crash_info = "crash!!!";

    crash_info[1] = 'D';

    return 0;
}

int main()
{
    crash();

    return 0;
}

由于程序访问了只读数据,执行上述程序会触发程序崩溃,程序的运行结果中出现了core dumped字眼,说明core文件已经生成:
在这里插入图片描述
查看生成的core文件以及信息如下:
在这里插入图片描述

coredump文件的使用

完成core文件的收集后,后续就是调试工具对core文件进行分析查找程序崩溃的原因了。使用gdb工具读取core文件的命令如下:
在这里插入图片描述
对于gdb的使用,不是本文的重点,网上也有很多资料可以查找,在此跳过。

使用systemd的系统下获取core文件

在使用systemd的系统中,/proc/sys/kernel/core_pattern的文件内容可能是如下的结果:
在这里插入图片描述
这里core_pattern被配置成以|管道字符开头的字符串,意味着程序的coredump信息将会作为标准输入交由systemd-coredump程序进行处理。systemd-coredump默认会为所有进程在/var/lib/systemd/coredump目录下以特定的压缩格式生成core文件。

使用coredumpctl获取core文件

systemd提供了专门的命令coredumpctl用于查找和获取coredump文件信息。使用coredumpctl列出系统已捕获的core信息:
在这里插入图片描述

systemd控制生成的core文件使用特定的格式进行了压缩,为了获取原生可调试的coredump文件,需要使用coredumpctl命令进行获取:
在这里插入图片描述

使用gdb生成core dump文件

在一些情况下,可能希望获取程序正常运行过程中的信息,gdb支持使用子命令generate-core-file在调试程序的过程中生成core文件,示例如下:

在这里插入图片描述## 相关参考

  • 《Arch wiki》
posted @ 2020-07-05 22:32  Aspiresky  阅读(124)  评论(0编辑  收藏  举报