在linux系统中,core指的是core dump文件,也就是程序异常终止时,操作系统将程序当时的内存状态、寄存器信息、打开的文件描述符、调用栈等数据保存到磁盘上的文件,它相当于程序崩溃瞬间的完整快照,是排查程序崩溃问题的重要依据。

core文件的生成机制
linux下core文件的生成和程序接收到的信号直接相关,当程序接收到某些会导致进程终止的信号时,操作系统就会触发core dump流程,生成对应的core文件。常见的会触发core dump的信号包括:
- SIGSEGV:段错误信号,通常是程序访问了非法内存地址导致
- SIGABRT:中止信号,一般是程序调用abort函数主动触发
- SIGFPE:浮点异常信号,比如除零操作就会触发该信号
- SIGBUS:总线错误信号,通常和内存对齐问题相关
如果程序接收到的终止信号不会触发core dump,比如SIGINT(用户按下Ctrl+C发送的信号)、SIGTERM(默认终止信号),就不会生成core文件。
配置core文件生成规则
默认情况下,很多linux发行版会限制core文件的大小为0,也就是不会生成core文件,我们可以通过ulimit命令来修改这个配置。
临时配置core文件大小
使用ulimit -c命令可以查看和设置core文件的大小限制,单位是块(通常1块等于512字节),设置为unlimited表示不限制core文件大小:
# 查看当前core文件大小限制 ulimit -c # 设置core文件大小不限制 ulimit -c unlimited
这种配置方式是临时的,只在当前shell会话中生效,关闭终端后配置就会失效。
永久配置core文件大小
如果需要永久生效,可以将配置写入用户的bash配置文件,比如~/.bashrc或者~/.bash_profile:
# 在配置文件末尾添加以下内容 echo "ulimit -c unlimited" >> ~/.bashrc # 让配置立即生效 source ~/.bashrc
自定义core文件命名规则
默认生成的core文件会直接命名为core,很容易被覆盖,我们可以通过修改/proc/sys/kernel/core_pattern文件来自定义core文件的命名规则,比如添加进程ID、时间戳等信息:
# 设置core文件命名为core-进程名-进程ID-时间戳 echo "core-%e-%p-%t" > /proc/sys/kernel/core_pattern
常见的命名占位符含义如下:
| 占位符 | 含义 |
|---|---|
| %e | 进程的可执行文件名 |
| %p | 进程ID |
| %t | core文件生成的时间戳 |
| %h | 主机名 |
| %s | 导致core dump的信号编号 |
使用gdb分析core文件
生成core文件之后,我们可以使用gdb工具来分析它,定位程序崩溃的具体位置。首先我们需要有程序的可执行文件,并且编译时最好加上-g参数保留调试信息,这样分析出来的结果会更准确。
准备测试程序
我们先写一个会触发段错误的简单C程序:
#include <stdio.h>
int main() {
int *p = NULL;
// 访问空指针,触发段错误
*p = 10;
return 0;
}
编译这个程序,加上-g参数保留调试信息:
gcc -g -o test test.c
运行程序之后,如果已经配置了core文件生成规则,就会在当前目录生成对应的core文件。
使用gdb加载core文件
执行以下命令加载可执行文件和core文件:
gdb ./test core-test-test-1234-1690000000
进入gdb之后,我们可以使用以下常用命令分析问题:
- bt:查看调用栈,能直接看到崩溃时的函数调用链路
- frame 序号:切换到对应的栈帧,查看该栈帧的局部变量和上下文
- print 变量名:打印变量的值
- info registers:查看崩溃时的寄存器状态
比如执行bt命令后,输出可能如下:
#0 0x0000000000401132 in main () at test.c:6 6 *p = 10;
这样就可以直接看到程序是在test.c的第6行,执行*p = 10的时候发生了崩溃,结合代码就能知道是访问了空指针导致的段错误。
core文件的常见注意事项
需要注意的是,如果程序设置了setuid或者setgid权限,默认情况下操作系统不会为这类程序生成core文件,这是出于安全考虑,避免敏感信息泄露。如果需要为这类程序生成core文件,需要修改/proc/sys/fs/suid_dumpable文件的值为1。
另外,core文件可能会占用较大的磁盘空间,如果磁盘空间不足,可能会导致core文件生成失败,所以需要确保存放core文件的目录有足够的可用空间。