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配置文件的方式对内核参数进行配置,对应的参数项依次为:
- kernel.core_uses_pid
- 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》