Linux core dump 文件介绍

发布时间: 更新时间: 总字数:1477 阅读时间:3m 作者: IP上海 分享 网址

Linux core dump(核心转储) 是操作系统在程序运行过程中发生异常(如接受到 SIGSEGVSIGABRT信号量),而异常在进程内部没有被捕获时的一个内存快照(包括进程此刻的内存、寄存器状态、运行堆栈等信息)转储文件。该文件是二进制文件,可以使用gdb、elfdump、objdump 等打开分析。

产生原因

  • 内存访问越界
  • 非法指针
  • 堆栈溢出
  • 多线程读写的数据未加锁保护、调用线程不安全的函数

开启生产 core 文件

以下命令的 0 表示未开启 core dump

$ ulimit -c
0
$ ulimit -a
core file size          (blocks, -c) 0

存储位置

Linux 内核参数 kernel.core_pattern 用于控制 核心转储(core dump) 文件的保存位置和文件格式。核心转储 是进程在某一时刻的运行状态的快照,通常在进程崩溃或发生其他问题时产生。

kernel.core_pattern="/corefile/core-%e-%p-%t"

表示将 核心转储 文件统一生成到 /corefile 目录下,文件名格式为 core-命令名-pid-时间戳

如果 kernel.core_pattern 的第一个字符是 |,则内核会将剩余的部分视为要运行的命令。该情况下,核心转储将写入该程序的标准输入,而不是写入文件,如将其传递给特定的分析工具或脚本进行处理

$ vim /etc/sysctl.conf
kernel.core_pattern=/tmp/core-%e-%p
$ sysctl -p /etc/sysctl.conf
  • 示例
kernel.core_pattern="|xxx /tmp/%E.core.%p %P"
  • | 管道符号,表示将 core dump 文件的内容同时输出到标准输出和指定的文件中
  • xxx 处理程序
  • %E: 进程执行环境,例如 “x86_64”
  • .%p: 进程 ID
  • %P: 父进程 ID

ulimit 开启

ulimit -c unlimited
ulimit -c 1024  # 单位 Kb

此时,core file sizeunlimited

$ ulimit -c
unlimited
$ ulimit -a
core file size          (blocks, -c) unlimited

以上命令仅在当前 tty 中生效,若需要在所有新终端中生效,可以将 ulimit -c unlimited 加入 ~/.bashrc/etc/profile 中。

说明:

  • 产生 core dump 文件时,会提示 core dumped

limits.conf 中配置

core dump 文件也可以通过Linux limits设置

sysctl 开启

在根目录下生产 core dump 文件

echo "kernel.core.pattern = /core-%e-%p-%t" >> /etc/sysctl.conf
sysctl -p

关闭 core dump 的方法

ulimit -c 0

文件格式

core dump 文件一般和执行程序在同一目录,名字固定为 core(见 /proc/sys/kernel/core_pattern),可以通过如下方法将文件名改为 core.<pid> 格式

echo "1" > /proc/sys/kernel/core_uses_pid
  • 指定 core dump 文件格式:core-命令名-pid-时间
echo "/core-%e-%p-%t" > /proc/sys/kernel/core_pattern

参数说明:

  • %e : insert coredumping executable name into filename 添加命令名
  • %p : insert pid into filename 添加pid
  • %u : insert current uid into filename 添加当前uid
  • %g : insert current gid into filename 添加当前gid
  • %s : insert signal that caused the coredump into the filename 添加导致产生core 的信号
  • %t : insert UNIX time that the coredump occurred into filename 添加core文件生成时的unix时间
  • %h : insert hostname where the coredump happened into filename 添加主机名
  • %p 转储过程的PID
  • %E 可执行文件的路径名

使用

生产环境中,若程序出现问题,可以先启用生成 core dump,然后使用 kill -11 <pid> (11代表信号SIGSEGV)产生 core dump 文件,这样就可以快速重启程序,然后慢慢分析 core dump 文件。

示例

通过示例演示 core dump 生成和解析

代码

  • main.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    int pid = getpid();

    printf("pid = %d\n", pid);

    int i = 0;
    i++;

    char *str = "hello world";

    // trigger a segmentation fault
    str[0] = 'H';

    return 0;
}

编译

$ echo "/core-%e-%p-%t" > /proc/sys/kernel/core_pattern
$ gcc -g -o main main.c  # 生产文件名为 main,编译程序时加上 -g 选项 gdb 时才能够获取到具体的信息
$ ./main
pid = 5367
Segmentation fault (core dumped)
$ ls -l / | grep core
-rw-------    1 root root 249856 Jun  22 03:29 core-main-5367-1561192263

使用 readelf 查看 coredump 文件头信息

readelf -h core-main-5367-1561192263

gdb 调试 core 文件

gdb [options] [executable-file [core-file or process-id]]
  • 通过 core dump 调试
$ gdb ./main /core-main-5367-1561192263
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7
Copyright (C) 2013 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-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/main...done.
[New LWP 5367]
Core was generated by `./main'.
Program terminated with signal 11, Segmentation fault.
#0  0x00000000004005bf in main (argc=1, argv=0x7ffceb20a188) at main.c:17
17	    str[0] = 'H';
Missing separate debuginfos, use: debuginfo-install glibc-2.17-325.el7_9.x86_64

说明:main.c:17 产生异常。

  • 直接使用 gdb 运行
$ gdb main
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7
Copyright (C) 2013 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-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/main...done.
(gdb) help generate-core-file
Save a core file with the current state of the debugged process.
Argument is optional filename.  Default filename is 'core.<process_id>'.
(gdb) start
Temporary breakpoint 1 at 0x40058c: file main.c, line 7.
Starting program: /root/main

Temporary breakpoint 1, main (argc=1, argv=0x7fffffffe508) at main.c:7
7	    int pid = getpid();
Missing separate debuginfos, use: debuginfo-install glibc-2.17-325.el7_9.x86_64
(gdb) c
Continuing.
pid = 5383

Program received signal SIGSEGV, Segmentation fault.
0x00000000004005bf in main (argc=1, argv=0x7fffffffe508) at main.c:17
17	    str[0] = 'H';
(gdb) generate-core-file
Saved corefile core.5383
(gdb) quit
A debugging session is active.

	Inferior 1 [process 5383] will be killed.

Quit anyway? (y or n) y

说明:以上代码说明 main.c:17 有问题

Home Archives Categories Tags Statistics
本文总阅读量 次 本站总访问量 次 本站总访客数