在 Linux 生成 core dump 文件

生成 core dump 文件

  如果进程在运行期间发生奔溃,操作系统会为进程生成一个快照文件,这个文件就叫做 core dump。之后我们可以对 core dump 文件进行分析,弄清楚进程为什么会奔溃。
  由于 core dump 文件会占据一定的磁盘空间,默认情况下,Linux 不允许生成 core dump 文件。例如,下面的命令显示,Linux 允许的最大 core dump 文件大小为 0:

1
2
$ ulimit -a | grep core
core file size (blocks, -c) 0

  可以通过下面设置,允许 Linux 生成 core dump 文件:

1
$ ulimit -c unlimited

  注意到,这个设置只对当前登录回话有效。如果想要这个设置持久有效,可以把它写入到/etc/security/limits.conf文件中:

1
2
3
$ sudo vi /etc/security/limits.conf
* soft core unlimited
* soft hard unlimited

core dump 文件的路径

  那么 core dump 会存放在哪个目录呢?这是由系统参数kernel.core_pattern决定的。例如,在 Ubuntu 16.04 中,它的值如下:

1
2
$ cat /proc/sys/kernel/core_pattern
|/usr/share/apport/apport %p %s %c %P

  开头的I表示,core dump 文件会交给 apport 程序去处理,而 apport 会将 core dump 文件保存在/var/crash目录下。
  在实践中,更好的做法是自己指定 core dump 目录,以及 core dump 文件的命名方式:

1
2
3
$ sudo vi /etc/sysctl.conf
kernel.core_pattern=/var/crash/%E.%p.%t.%s
$ sudo sysctl -p

  我们设置 core dump 目录为/var/crash,core dump 的命名方式为%E.%p.%t.%s,它们的含义:

  • %E:程序文件的完整路径(路径中的/会被!替代)
  • %p:进程 ID
  • %t:进程奔溃的时间戳
  • %s:哪个信号让进程奔溃

  下面是一个简单的 C++ 程序,我们用它来演示如何生成 core dump 文件:

1
2
3
4
5
6
7
8
9
#include <thread>
#include <chrono>
int main()
{
std::this_thread::sleep_for(std::chrono::hours(1)); // 休眠一个小时
return 0;
}

  这个文件的路径是/home/ubuntu/main.cpp,编译并运行这个程序:

1
2
3
$ clang++ -std=c++11 -g -o main main.cpp
$ ./main &
[1] 32453

  可以看到,进程 ID 是32453,只要杀死这个进程,就可以看到生成了 core dump 文件:

1
2
3
$ kill -s SIGSEGV 32453
$ ls /var/crash/
!home!ubuntu!main.32453.1514776059.11

参考资料