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
文件进行调试了: