Linux下开启coredump转储以及生成core文件的配置
在C/C++开发过程中经常会使用到gdb调试,而coredump作为程序发生崩溃或异常终止时生成的一种文件,包含了程序在崩溃时内存的快照和其他信息,能够让我们第一时间内快速开始排查错误发生的原因。而默认情况下,Linux是关闭了coredump转储文件的生成,毕竟开启这个功能,会产生一定的系统开销。
1、开启coredump转储以及core文件生成
可以通过如下命令ulimit -c查看系统能否生成coredump:
1 | |
0表示不会生成,可以通过下面的命令设置core 文件的大小:
- 生成不受限的core文件
1 | |
- 生成受限大小的core文件
1 | |
以上的配置都只是临时开启的,当系统重启或者是用户重新登录便会失效,所以若要永久开启coredump转储,需要修改配置文件/etc/security/limits.conf,增加如下项:
1 | |
该项表示设置core文件的大小为unlimited,如果想要设置具体的文件大小,也可以改为具体的数值。
修改成功后,重新登录用户并执行ulimit -c命令就可以看到修改已经起作用了。
2、配置core的文件名以及生成位置
网上的一些文章提到:
coredump的core文件默认生成路径可以通过修改 /proc/sys/kernel/core_pattern 文件来自定义。
但在ubuntu系统下,执行more /proc/sys/kernel/core_pattern显示的是如下内容:
1 | |
其中的|/usr/share/apport/apport是一个脚本(用于自动错误报告的工具),它利用%p %s %c %d %P %E这些参数来生成core文件以及文件名,这些参数的具体意义如下:
%p:进程ID(Process ID),表示崩溃的应用程序的进程ID。%s:信号(Signal),表示导致崩溃的信号。%c:核心转储文件(Core Dump File),表示核心转储文件的路径。%d:日期(Date),表示崩溃发生的日期和时间。%p:包名(Package Name),表示崩溃的应用程序所属的软件包的名称。%E:执行命令(Executable Path),表示崩溃的应用程序的可执行文件路径。
进一步地,我们可以简单地看一下core文件的默认名称是什么:

可以看到,它应该默认是生成于可执行文件所在的目录下以及名称是core。在这种设置下,新生成的core文件会覆盖旧的core文件,如果我们需要某一时刻下的core文件时,就比较麻烦。
core文件的参数格式:
| 参数 | 意义 |
|---|---|
%% |
符号% |
%p |
进程号 |
%u |
进程用户id |
%g |
进程用户组id |
%s |
生成core文件时收到的信号 |
%t |
生成core文件的时间戳(seconds since 0:00h, 1 Jan 1970) |
%h |
主机名 |
%e |
程序文件名 |
要让core文件带有pid,需要配置/proc/sys/kernel/core_uses_pid的内容为1,执行如下命令进行配置:
1 | |
指定生成的core文件在指定目录下,并按照一定的格式命名core文件:
1 | |
需要注意的是:由于/proc目录是动态更新的,系统会初始化core_pattern文件的值,所以直接修改/proc/sys/kernel/core_pattern是无法永久地指定core文件生成到指定的目录下的,所以需要按照上面的配置来修改才能永久的起作用。
3、测试生成的core文件
简单地写了如下的demo程序:
1 | |
使用g++编译一下(不带-g参数也可以的):
1 | |
执行该程序后,由于存在野指针,会提示发生段错误:
1 | |
这时就可以从/dump目录下看到对应的core文件,并且可以根据该core文件进行调试了:
