Linux 开启 core dump

Posted by Sunday on 2018-02-27

1. 什么是core文件

某些信号的操作是导致进程终止并生成核心转储文件,包含终止时进程内存的映像。
主要用于程序崩溃时,调试找原因的。

2. 配置系统生成 core 文件

1. 使用 ulimit 配置生成 core 文件大小

首先使用ulimit -c 确认系统是否生成 core 文件,若为 0,说明禁用了 core 文件生成,若要启用,根据需要配置 core 文件生成大小。 如不限制 core 文件大小,如下设置:

1
ulimit -c unlimited

2. 设置core文件名称和路径

a.设置pid作为扩展名

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

0:不添加pid作为扩展名,生成的文件名称为core,新的core会覆盖已存在的core。
1:可以将进程的pid作为作为扩展名,生成的core文件格式为core.xxx,其中xxx即为pid

b.设置core文件保存位置和格式

默认:|/usr/share/apport/apport %p %s %c %P
修改 将所有的core文件生成到/data/logs/core/目录下,文件名的格式为core-命令名-pid-时间戳.

1
echo "/data/logs/core-%e-%p-%t" > /proc/sys/kernel/core_pattern

c.永久生效

1
2
3
4
echo "ulimit -c unlimited" > /etc/profile
echo "kernel.core_uses_pid = 1" > /etc/sysctl.conf
echo "kernel.core_pattern = /data/logs/core/core_%e_%p" > /etc/sysctl.conf
sysctl -p

3. 测试是否能生成core文件

1
kill -s SIGSEGV $$

查看/data/logs/core/目录下是否生成了core文件

4.调试core文件

Eg. test.c

1
2
3
4
5
6
7
#include<stdio.h>
int main()
{
int *p = NULL;
*p = 0;
return 0;
}

1
2
3
root@ubuntu:~# gcc -o test test.c
root@ubuntu:~# ./test
Segmentation fault (core dumped)

bingo:这里出现段错误并生成core文件了
在/data/logs/core目录下发现core-test-31421-1476266571
开始调试
gdb ./test core_test_170871_1519869120

1
2
3
4
5
6
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./test...(no debugging symbols found)...done.
[New LWP 170871]
Core was generated by `./test'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 000000004004e6 in main ()

5.系统没生成 core 文件的原因

可能的情况比较多。

以下引用他人总结的:

一、要保证存放 coredump 的目录存在且进程对该目录有写权限。存放 coredump 的目录即进程的当前目录,一般就是当初发出命令启动该进程时所在的目录。但如果是通过脚本启动,则脚本可能会修改当前目录,这时进程真正的当前目录就会与当初执行脚本所在目录不同。这时可以查看”/proc/<进程pid>/cwd”符号链接的目标来确定进程真正的当前目录地址。通过系统服务启动的进程也可通过这一方法查看。

二、若程序调用了 seteuid()/setegid() 改变了进程的有效用户或组,则在默认情况下系统不会为这些进程生成 coredump。很多服务程序都会调用 seteuid(),如 MySQL,不论你用什么用户运行 mysqld_safe 启动 MySQL,mysqld 运行的有效用户始终是 msyql 用户。如果你当初是以用户 A 运行了某个程序,但在 ps 里看到的这个程序的运行用户却是 B 的话,那么这些进程就是调用了 seteuid 了。为了能够让这些进程生成 core dump,需要将 /proc/sys/fs/suid_dumpable 文件的内容改为 1(1或2都可以,ubuntu 16.04默认是2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
This value can be used to query and set the core dump mode for setuid
or otherwise protected/tainted binaries. The modes are

0 - (default) - traditional behaviour. Any process which has changed
privilege levels or is execute only will not be dumped
1 - (debug) - all processes dump core when possible. The core dump is
owned by the current user and no security is applied. This is
intended for system debugging situations only.
2 - (suidsafe) - any binary which normally not be dumped is dumped
readable by root only. This allows the end user to remove
such a dump but not access it directly. For security reasons
core dumps in this mode will not overwrite one another or
other files. This mode is appropriate when adminstrators are
attempting to debug problems in a normal environment.

三、要设置足够大的 coredump 文件大小限制。
程序崩溃时生成的 core 文件大小即为程序运行时占用的内存大小。但程序崩溃时的行为不可按平常时的行为来估计,比如缓冲区溢出等错误可能导致堆栈被破坏,因此经常会出现某个变量的值被修改成乱七八糟的,然后程序用这个大小去申请内存就可能导致程序比平常时多占用很多内存。因此无论程序正常运行时占用的内存多么少,要保证生成 core 文件还是将大小限制设为 unlimited 为好。

以上情况的解决方法是设置/proc/sys/fs/suid_dumpable成 1

http://jaminzhang.github.io/linux/Linux-core-file/
Linux core 文件介绍
Linux 下 core 文件产生的一些注意问题
Linux 下如何产生 core 文件(core dump 设置)
coredump 设置方法