在 Linux 中,当进程接收到某些信号的时候,默认会产生一个 core dump 文件,它包含了进程崩
溃时候的内存快照。该文件可以配合调试器 gdb 用于定位程序崩溃的原因。能使程序产生 core dump 的
信号列表可以在 signal 的手册页(man 7 signal
)找到。
为什么不产生 core
core dump 有助于定位分析问题。但是有时候程序崩溃的时候明明提示产生了 core dump,如下所示:
Segmentation fault (core dumped)
但是我们却找不到该文件。可能的原因有:
-
当前用户的 ulimit 配置限制了 core dump 文件的大小为 0. 可以通过以下命令解决:
$ ulimit -c unlimited
-
发行版本供应商在系统中做了特定的设置。以在发生 crash 的时候将该文件上传,便于他们分析问题。 具体在
/proc/sys/kernel/core_pattern
中配置。大多数不产生 core dump 文件都是这个原因。 在man 5 core
的输出中这样说:Piping core dumps to a program
Since kernel 2.6.19, Linux supports an alternate syntax for the
/proc/sys/kernel/core_pattern
file. If the first character of this file is a pipe symbol (|), then the remainder of the line is interpreted as a user-space program to be executed. Instead of being written to a disk file, the core dump is given as standard input to the program. Note the follow‐ing points:- The program must be specified using an absolute pathname (or a pathname relative to the root directory, /), and must immediately follow the ‘|’ character.
- The process created to run the program runs as user and group root.
- Command-line arguments can be supplied to the program (since Linux 2.6.24), delimited by white space (up to a total line length of 128 bytes).
- The command-line arguments can include any of the % specifiers listed above. For example, to pass the PID of the process that is being dumped, specify %p in an argument.
可以执行以下指令设置:
$ su root # echo "/var/crash/core.%u.%E.%p" > /proc/sys/kernel/core_pattern
如何使程序崩溃时候默认产生 core
通过上面两步的设置,一般就可以让 crash 的进程 dump 出 core 文件了。但是这个设置仅仅针对当前 session 有效。当你另外打开一个终端或者重启系统的时候,默认仍然是不产生 core dump 的。要使设置 总是有效,可以通过修改相关配置文件实现。
-
修改登录用户的 ulimit。下面两种方式均可
在用户配置文件
~/.bashrc
中加入下面的语句:ulimit -c unlimited
或者,修改系统配置文件
/etc/security/limits.conf
,加入下面一句:* soft core unlimited
-
修改 kernel 参数
在配置文件
/etc/sysctl.conf
中加如下面的设定:kernel.core_pattern = /var/crash/core.%u.%E.%p
-
禁用 bug 上报程序 apport(适用于ubuntu)
配置好 ulimit 和 core_pattern 之后,还需要禁用 apport。否则,系统启动的时候,apport 会更改 core_pattern 。在配置文件
/etc/default/apport
中将 apport 禁用:enable=0
其它发行版本可能具有不同的 bug 上报程序,这一步需要根据实际情况修改。
经过以上设置之后,如果程序收到了相关信号之后,就会在 /var/crash
目录下面产生一个 core 文件。
使用下面指令就可以定位程序崩溃的原因了:
gdb crashed-program core-dump