Linux下core文件的生成和使用

本文对作者2018年的博文Linux下core文件使用做了一系列更新,特别是针对Ubuntu 20.04core文件生成异常做了分析与解决。


什么是core文件

Linux下遇到程序异常退出或者中止,操作系统通常会把程序当前的工作状况存储在一个名为core的文件中,其中包含了程序运行时的内存、寄存器和堆栈指针等信息,格式为ELF,这个过程叫做coredump,又称作核心转储。

通过工具分析这个文件,我们可以定位到程序异常退出或者终止时相应的堆栈调用等信息。

如何生成core文件

查看coredump是否生效

1
2
3
4
$ ulimit -a
...
-c: core file size (blocks) 0
...

0 表示core文件大小限制为0,不允许写入,所以无法生成core文件,需要修改为正数大小或unlimited才可使coredump生效。

修改core文件大小的限制

取消core文件大小限制:

1
2
3
4
5
ulimit -c unlimited
ulimit -a
...
-c: core file size (blocks) unlimited
...

也可以对core文件的大小进行有效限制,单位为blocks,一般1 block=512 bytes,设置太小可能导致不会生成文件:

1
2
3
4
5
$ ulimit -c 1024
$ ulimit -a
...
-c: core file size (blocks) 1024
...

上面对core文件的操作仅对当前生效,若需要永久生效,则要将相应操作写入/etc/profile

设置core文件存储路径

core文件默认存储在程序的工作目录,可以通过命令cat /proc/sys/kernel/core_pattern查看。

在文件/etc/sysctl.conf末尾加入如下信息,可以指定core文件的存储路径:

1
kernel.core_pattern=/dumpdir/core_%e_%p_%t

控制core文件的文件名中是否添加pid作为扩展:

1
echo "1" > /proc/sys/kernel/core_uses_pid

/proc/sys/kernel/core_uses_pid这个文件的值若为1,则无论是否配置%p,最后生成的core文件都会添加pid

通常情况下,重启即可生效。

core文件命名使用的参数列表:

1
2
3
4
5
6
7
%p - insert pid into filename  # 添加 pid 
%u - insert current uid into filename # 添加当前 uid
%g - insert current gid into filename # 添加当前 gid
%s - insert signal that caused the coredump into the filename # 添加导致产生 core 的信号
%t - insert UNIX time that the coredump occurred into filename # 添加 core 文件生成时的 unix 时间
%h - insert hostname where the coredump happened into filename # 添加主机名
%e - insert coredumping executable name into filename # 添加命令名

关闭apport.service服务

Ubuntu 20.04中,执行完上述操作,会发现还是无法在指定目录生成core文件。

查看core文件存储路径:

1
2
$ cat /proc/sys/kernel/core_pattern
|/usr/share/apport/apport %p %s %c %d %P %E

发现core文件存储路径并非自己设置的,而是由管道交给了一个apport的程序,通过查询可知其是Ubuntu官方为了自动收集错误,生成程序崩溃报告的一个服务,即apport.service

我们可以关闭apport.service这个服务:

1
sudo service apport stop

使用sudo service apport start可以开启这个服务。

如果这个命令无效的话,可以修改/etc/default/apport文件,将enabled改成0

如上,可以在指定路径生成core文件。

使用core文件调试

可以使用gdbcore文件进行调试:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ gdb a.out
...
(gdb) core-file core
...
(gdb) bt
...

or

$ gdb a.out core
...
(gdb) bt
...

编译可执行程序时需要带上-g选项。

如需要在PC上调试嵌入式设备产生的core文件,则需要选取相应平台的gdb工具,并在进入gdb后设置符号文件的位置:

1
2
3
4
5
6
7
8
$ xxx-xxx-gdb a.out
...
(gdb) solib-search-path xxx.so:xxx.so
...
(gdb) core-file core
...
(gdb) bt
...


Author

微信公众号同步更新,微信搜索"AnSwEr不是答案"或者扫描二维码,即可订阅。
AnSwEr(Weijie Yuan) wechat