关于Linux的core dump那些事

什么是core? 在linux中,程序运行时出现异常崩溃,操作系统会将程序当时的内存状态、调用堆栈等信息保存在core文件中。这种行为就是core dump(核心转储)。core文件中一般会保存寄存器信息(包括程序指针、栈指针等)、内存管理信息、CPU和操作系统状态和以及函数调用堆栈等信息。所以,core文件对于开发人员是非常重要的,很多时候我们都需要依赖对core文件的分析结合日志来定位和解决崩溃的问题。
core dump相关设置 在linux中,core dump的一些相关设置方法:

  • 查询:ulimit -c,查询结果为0则表示关闭core dump功能,系统默认是关闭的。
  • 关闭:ulimit -c 0。
  • 打开:ulimit -c unlimited,不限制core文件大小,也可以限制指定大小,单位是blocks(一般为kB),如ulimit -c 100表示限制core文件大小为100k。
  • 修改core文件名生成规则:通过执行命令echo 1 > /proc/sys/kernel/core_uses_pid,可以将生成core文件的文件名改为core.pid。默认情况下,core dump生成的文件名为core,文件生成在程序当前目录下。且新的core会覆盖已存在的core。
  • 修改生成路径和文件名:通过修改/proc/sys/kernel/core_pattern可以控制core文件保存位置和文件格式。例如,通过命令echo "/tmp/corefile/core-%e-%p-%t" > /proc/sys/kernel/core_pattern将core文件保存在/tmp/corefile/目录下,文件名的格式为core-命令名-pid-时间戳.
  • 【关于Linux的core dump那些事】core_pattern的命名参数如下:
    %e dump的命令名 %p dump的进程PID %t dump时间戳(由1970年1月1日起计的秒数) %s 导致本次core dump的信号 %c 转储文件的大小上限 %g dump的进程的实际组ID %u dump进程的实际用户ID %h 主机名

产生core文件的必备条件
  • 环境变量的设置:通过前面介绍的ulimit –c等环境变量的设置打开core文件的生成限制。
  • 程序编译选项的设置:要产生 core 文件,编译器必须支持把当前进程的镜像以某种格式 dump 到一个文件中,常见的比如 gcc/g++ 的 -g 选项。
  • 崩溃时的特殊信号:Linux内核会根据进程退出时的信号的类型来决定是否要产生 core 文件。例如SIGSEGV、SIGABRT等信号会产生core,而SIGALRM、SIGPIPE等信号不会产生core。
GDB调试core文件 当程序core dump之后,使用命令gdb program core来查看 core 文件,其中 program 为可执行程序名,core 为生成的 core 文件名。然后执行bt(backtrace)命令查看函数的调用堆栈,定位崩溃产生的位置。其他gdb调试技巧在此不赘述。
core文件的缺点
  • 因为 core 文件是对当时进程地址空间的镜像,所以 core 文件大小一般都会比较大,这样很占用磁盘空间,而且如果要将文件从服务器上下载到本地分析也会比较耗时。
  • 对于缓冲区溢出导致的 coredump ,进程的调用堆栈已经被覆盖破坏了, core 文件显示的堆栈信息往往错误。
  • 程序因SIGALRM、SIGPIPE等信号崩溃,则不会产生 core 文件。

    推荐阅读