Core 文件(核心转储文件)是 Linux 和其他类 Unix 系统中一个非常重要的调试工具。当程序崩溃时,系统可以生成一个 core 文件,其中包含了程序崩溃时的内存状态、寄存器值、堆栈信息等详细内容。
core文件生成的两个条件
一般,不管在什么系统下,当程序崩溃时,是否能够生成core文件,需要满足两个条件:
- core文件限制的大小是否足够大;
- core文件存放的位置是否配置正确;
下面逐一说下两个条件的配置方式。
设置core文件大小
使用ulimit -c命令可以查看系统对于core文件的大小限制,默认情况下,core文件的大小限制为0,即程序崩溃时,不产生core文件。通过一下中方式修改:
临时修改
在当前shell环境下,临时修改core文件大小的方式如下:
ulimit -c unlimited
写入环境配置文件
临时修改只在当前shell有效,打开新shell后,需要重新配置执行上面的命令,可以将该命令写入到用户的~/.bashrc下,那么该用户每次打开shell终端后,该命令都会自动执行。
写入用户资源限制文件
如果需要使系统下的所有用户,都打开core文件的限制,可以在/etc/security/limits.conf文件下,增加下面两条:
* soft core unlimited
* hard core unlimited
注意,limits.conf文件的修改,系统重启后生效。
指定core文件存放位置
- /proc/sys/kernel/core_uses_pid可以控制产生的core文件的文件名中是否添加pid作为扩展,如果添加则文件内容为1,否则为0。
- /proc/sys/kernel/core_pattern可以设置格式化的core文件保存位置或文件名,比如原来文件内容是core-%e。
可以通过echo命令或者修改sysctl.conf文件的方式将core文件,配置core文件的存放位置,如下:
echo “/var/corefile/%e-%s-%u-%g-%p-%t.core” > /proc/sys/kernel/core_pattern
或者修改sysctl.conf文件,如下:
kernel.core_pattern = /var/corefile/%e-%s-%u-%g-%p-%t.core
kernel.core_uses_pid = 1
使用sudo sysctl -p /etc/sysctl.conf使sysctl.conf的配置生效。
/var/corefile/%e-%s-%u-%g-%p-%t.core的含义如下:
- 将core文件存放到/var/corefile目录下,corefile目录需要手动创建,注意,corefile目录的权限,corefile需要具有写权限,如下:
如果不是上面的权限,执行如下命令修改目录权限:
sudo chmod a+w /var/corefile
%%:相当于%
%p:相当于<pid>
%u:相当于<uid>
%g:相当于<gid>
%s:相当于导致dump的信号的数字
%t:相当于dump的时间
%e:相当于执行文件的名称
%h:相当于hostname
core文件生成测试
首先,检查上面两个core文件的生成条件:
core文件大小限制:
core文件的存放位置:
然后,编写测试程序如下:
1 #include <stddef.h>
2
3 int main(void)
4 {
5 char *str = NULL;
6 str[0] = '0';
7 return 0;
8 }
第6行代码,直接操作str 空指针,导致程序崩溃。
正常情况下,/var/corefile下,将产生core文件。
使用gdb可以调试程序崩溃的情况。
Q&A
-
core文件存放目录权限问题。
如果core文件生成的两个条件都满足,但是,在core文件存放目录下,就是看不到core文件,那么,可能是core文件存放目录权限配置错了,没有**“写”**权限。
找到core文件存放目录,例如/var/corefile,使用ls -l,查看目录权限,如果没有写权限,如下:
执行,sudo chmod a+x /var/corefile,给corefile目录加上写权限。 -
Ubuntu apport开启后,看不到core文件问题。
Apport 是 Ubuntu 系统中的一个错误报告工具,主要用于捕捉应用程序崩溃或系统错误,并生成详细的错误报告。如果apport开启后,会修改/proc/sys/kernel/core_pattern的设置,导致core文件不能正确生成,如下:
打开/etc/default/apport文件,将enable置为0,关闭apport功能,即可。
执行sudo systemctl restart apport,重启apport。然后,重新配置core_pattern环境变量,如下,可以看到core文件的生成目录配置正确了。