centos7开启coredump

发布时间 2023-07-09 15:27:54作者: 老铁来了啊

生成coredump

核心转储基本上是程序崩溃时内存的快照。

它基本上是使用中的进程地址空间(来自包含所有虚拟内存区域的mm_struct结构),以及崩溃时的任何其他支持信息。

当操作系统由于程序中的故障而终止进程时,进程会转储核心。发生这种情况的最典型原因是程序访问了无效的指针值。例如,当我们试图取消引用NULL指针时,在退出之前,我们会收到一个SEGV信号。作为这个过程的一部分,操作系统试图将我们的信息写入一个文件,以便稍后进行事后分析。

我们可以使用核心转储来诊断和调试我们的计算机程序,方法是将核心文件与可执行文件一起加载到调试器中(用于符号和其他调试信息)。由于核心转储可以占用大量的磁盘空间,因此它们的大小有一个可配置的限制

让我们来看一下:

[root@localhost ~]# ulimit -c
0

修改成无限制:

[root@localhost ~]# ulimit -a -H
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 7183
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 4096
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) unlimited
cpu time               (seconds, -t) unlimited
max user processes              (-u) 7183
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
[root@localhost ~]# ulimit -c
unlimited

以下是示例代码:

/* t.c */
#include <stdio.h>
void foo()
{
    int *ptr = 0;
    *ptr = 7;
}

int main()
{
    foo();
    return 0;
}

如果我们运行代码,我们会得到以下运行时错误:

Segmentation fault (core dumped)

但它不在当前目录中。它在哪里?

让我们转到/proc/sys/kernel目录。

$ ls -la core*
-rw-r--r--. 1 root root 0 Aug 28 23:53 core_pattern
-rw-r--r--. 1 root root 0 Aug 28 16:12 core_pipe_limit
-rw-r--r--. 1 root root 0 Aug 28 23:53 core_uses_pid

core_pattern中有什么?

$ cat core_pattern 
|/usr/libexec/abrt-hook-ccpp %s %c %p %u %g %t e

请注意,模式的第一个字符是“|”,内核将把模式的其余部分视为要运行的命令。核心转储将被写入该程序的标准输入,而不是文件。

因此,我的Fedora被配置为将其发送到自动错误报告工具(ABRT)。我们需要将core_pattern的行更改为“core”。

$ sudo bash -c 'echo core.%e.%p > /proc/sys/kernel/core_pattern'
$ cat /proc/sys/kernel/core_pattern
core.%e.%p

在设置中,%e表示可执行文件名,%p表示pid。

在设置了核心文件的大小(以512字节块为单位)后,我们再次运行代码:

$ ulimit -c unlimited
$ ./t
Segmentation fault (core dumped)
$ ls
core.t.3209 t t.c

核心转储文件格式
然而,核心文件过去只是一个二进制文件,因为在现代操作系统中,进程的地址空间可能不是顺序的,并且进程可能与其他进程共享页面,所以核心文件应该能够表示更多信息以及转储时程序的状态。在linux系统上,正在使用ELF(可执行和可链接格式)文件格式

分析核心文件:

我们可以将核心文件与gdb一起使用:

gdb executable core-file

在我们的案例中:

$ gdb ./t core.t.3529
GNU gdb (GDB) Fedora (7.5.0.20120926-25.fc18)
...
Reading symbols from /home/khong/TEST/DMP/t...done.
[New LWP 3529]
Core was generated by `./t'.
Program terminated with signal 11, Segmentation fault.
#0  0x00000000004004fc in foo () at t.c:6
6	    *ptr = 7;

这表示第6行有问题。我们知道我们正在延迟这一行的NULL指针。

我们可以使用回溯来列出程序崩溃时进行的调用堆栈:

(gdb) backtrace
#0  0x00000000004004fc in foo () at t.c:6
#1  0x0000000000400512 in main () at t.c:11

要上下移动调用堆栈:

(gdb) up
#1  0x0000000000400512 in main () at t.c:11
11	    foo();
(gdb) down
#0  0x00000000004004fc in foo () at t.c:6
6	    *ptr = 7;