1. 前言
限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。
2. 配置 coredump
2.1 临时配置方法
# (1) 配置 coredump 文件大小:不受限。
# 相关配置文件还有 /etc/security/limits.conf ,
# 读者可自行探讨。
ulimit -c unlimited
# (2) 创建 coredump 目录。
# 目录路径可随意更改,不必和本例中相同。
mkdir /coredump
chmod 0777 /coredump
# (3) 配置 coredump 文件路径和文件名规则。
# 注意,路径中的 /coredump 要和上一步骤中创建的目录对应。
echo "/coredump/%e-%p-%s-%t.core" > /proc/sys/kernel/core_pattern
echo '1' > /proc/sys/kernel/core_uses_pid
临时配置在系统重启后会丢失,我们再来看一看永久的配置方法,该方式在系统重启后不会丢失。
2.2 永久配置方案
# (1) 配置 coredump 文件大小:不受限。
# 修改文件 /etc/profile ,增加语句,保存到文件,
# 运行 . /etc/profile 立即生效 或 重启后生效。
# 相关配置文件还有 /etc/security/limits.conf ,
# 读者可自行探讨。
ulimit -c unlimited
# (2) 创建 coredump 目录。
# 目录路径可随意更改,不必和本例中相同。
mkdir /coredump
chmod 0777 /coredump
# (3) 配置 coredump 文件路径和文件名规则。
# 注意,路径中的 /coredump 要和上一步骤中创建的目录对应。
# 修改文件 /etc/sysctl.conf ,增加下面的两条语句,并保存
# 文件,运行 sysctl -p 或 重启生效。
kernel.core_pattern=/coredump/%e-%p-%s-%t.core
kernel.core_uses_pid=1
2.3 重定向 coredump 输出
在 ubuntu 系统最近的一些版本上,ubuntu 系统默认启用 coredump ,但它们的配置和我们前面描述的有所不同,我们来看一看:
$ ulimit -c
0
$ cat /proc/sys/kernel/core_pattern
|/usr/share/apport/apport %p %s %c %d %P %E
从上面查询的信息看到两点:
(1) coredump 导出大小限制为0。
(2) coredump 导出文件路径名有点奇怪,前面有一个 '|'
符号。
文件 /proc/sys/kernel/core_pattern
内容的第一个字符为 '|'
,这是什么意思?难道导出的 coredump 文件会命名为 |/usr/share/apport/apport %p %s %c %d %P %E
?显然不是。原来内核提供另一种 coredump 内容的输出方式:如果 core_pattern
的第1个字符为 '|'
,表示将 coredump 的输出内容通过管道,传递给 '|'
后面指定的程序处理。本例是将 coredump 的输出内容传递给 /usr/share/apport/apport
程序处理,而导出文件的路径和名称都交由该程序定义的规则来处理。
/usr/share/apport/apport
是一个 Python 脚本文件,某些版本的 ubuntu
默认用它来处理程序的 coredump 内容。/usr/share/apport/apport
在程序运行目录下生成名为 core 文件
,如果配置 /proc/sys/kernel/core_uses_pid
为 1,则会生成 cord.<pid>
文件。ulimit -c 的配置对于 /usr/share/apport/apport
是否产生 coredump 不会产生影响。我们也可以选择关掉 apport
,转而使用前述章节的 coredump 配置方式。
3. 什么时候会产生 coredump ?
Signal Standard Action Comment
────────────────────────────────────────────────────────────────────────
SIGABRT P1990 Core Abort signal from abort(3)
SIGBUS P2001 Core Bus error (bad memory access)
SIGFPE P1990 Core Floating-point exception
SIGILL P1990 Core Illegal Instruction
SIGIOT - Core IOT trap. A synonym for SIGABRT
SIGQUIT P1990 Core Quit from keyboard
SIGSEGV P1990 Core Invalid memory reference
SIGSYS P2001 Core Bad system call (SVr4);
see also seccomp(2)
SIGTRAP P2001 Core Trace/breakpoint trap
SIGUNUSED - Core Synonymous with SIGSYS
SIGXCPU P2001 Core CPU time limit exceeded (4.2BSD);
see setrlimit(2)
SIGXFSZ P2001 Core File size limit exceeded (4.2BSD);
see setrlimit(2)
以上信号都可能会产生 coredump。但即使是上面的信号产生了,仍然可能不会生成 coredump 文件,下面列举这些例外情形:
1. 进程是 Set-user-ID ,而且当前用户并非程序文件的所有者;
2. 进程是 Set-group-ID,而且当前用户并非该程序文件的组所有者;
3. 用户没有 coredump 生成目录的写权限;
4. coredump 文件太大。
5. 其它情形。
其中,第 1. , 2.
两点可通过设置 /proc/sys/kernel/suid_dumpable
来改变。
4. coredump 调试
测试代码 coredump_test.c
:
void main(void)
{
*(int *)0 = 8;
}
编译测试:
$ gcc -g -o coredump_test coredump_test.c # 加 -g 选项编译,方便 gdb 查看程序的调试信息
$ ./coredump_test
Segmentation fault (core dumped)
$ ls
core.4192 coredump_test coredump_test.c
$ gdb coredump_test ./core.4192
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from coredump_test...done.
[New LWP 4192]
Core was generated by `./coredump_test'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00000000004004df in main () at coredump_test.c:3
3 *(int *)0 = 8;
(gdb)