1. 什么是core文件
  core 文件是大多数 UNIX 系统实现的一种特性,当进程崩溃时,操作系统会将进程当前的内存映像和一部分相关的调试信息写入 core 文件,方便人们后面对问题进行定位。
  2. 哪些信号可能会产生core文件
  操作系统里面有很多信号(每个信号都有一个名字,且已SIG开头,用正整数表示,Linux系统一般在<bits/signum.h>头文件中定义),分别代表了不同的含义,在Linux系统中,我们可以通过shell命令 kill -l 来查看系统有哪些信号。操作系统收到信号时,内核会按照以下三种方式之一去对信号进行处理:
  忽略此信号。大多数的信号都可以用这种方式去处理,即内核收到此信号时,对进程不做任何处理,直接忽略。但是SIGKILL和SIGSTOP这两个信号不能被忽略,因为它们向超级用户提供了使进程终止或停止的可靠方法。
  捕捉信号。即我们向内核注册一个信号处理函数,当内核收到某个信号时,去调用注册的信号处理函数对信号进行处理。比如我们经常使用的命令kill默认发的是SIGTERM终止信号。注意,不能捕捉SIGKILL和SIGSTOP信号。
  执行默认动作。每个系统都有一套自己默认的信号处理函数,即如果我们不显式的去捕捉信号,那内核收到信号时,要么忽略此信号,要么执行默认的操作。可以理解为操作系统有自己默认的信号处理函数。
  Linux信号有很多,这里我们列举出默认动作中可能产生core文件的信号(摘自《UNIX环境高级编程》第二版)

  如果我们没有定义上述信号的信号处理函数,那默认情况下,内核收到这些信号,将终止进程,并产生该进程的core文件(该进程的内存映像以及一些调试信息便保存在该core文件中)。
  3. 如何开启与关闭core文件
  类UNIX操作系统为我们提供了一个可以打开与关闭core文件的开关,因为并非所有场景我们都希望可以生成core文件。类UNIX操作系统为我们提供了一个工具ulimit可以用来设置和查看文件大小的限制,所以我们也可以用这个工具来查看和设置core大小与限制。使用 ulimit -a 可以查看系统上面所有的文件大小的限制,比如下面是我的系统的输出结果:
allan@ubuntu:~$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 7725
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 7725
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
  显示结果分为三部分,比如第一行,第一部分是“core file size”,第二部分是“(blocks, -c)”,第三部分是“0”。这一行的含义是说“core文件的大小限制为0(即关闭core文件/不产生core文件),单位是blocks;使用ulimit -c命令可以改变此值”。这里我们还可以看到系统很多其他文件相关的设置,比如数据段大小无限制,文件大小无限制,多打开的文件数为1024,栈大小为8192KB等等。
  所以很明显,我们可以使用 ulimit -c core_size/unlimited 去设置core文件的大小,注意core_size单位是字节。如果core_size为0,则表示不生成core文件,unlimited表示对core文件大小不做限制。我们可以将该命令现在某个用户的环境变量里面去对不同的用户进行设置,比如写在/home/allan/.bashrc文件里面只对allan用户有效;也可以写在系统的环境变量里面,对所有用户有效,比如/etc/.profile。