centos7开启coredump

生成coredump

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

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

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

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

让我们来看一下:

[root@localhost ~]# ulimit -c
0

修改成无限制:

[root@localhost ~]# ulimit -S -c 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

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

默认情况下,核心转储文件称为core

您可以更改名称和目标模式,以便轻松识别核心转储。

命令如下:

sudo sysctl -w kernel.core_pattern=core-%u-%g-%p

-%u将在核心转储名称中包括用户ID。-%g将包括组ID和%p PID。

或者使用以下命令更改,将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。

您可以使用其他值来定义堆芯转储模式。你可以在下面的列表中找到它们。

VALUE Function
% ‘%’ is dropped
%% output one ‘%’
%p Includes PID
%P Includes Global PID
%i Shows Thread ID
%I Global Thread ID
%u User ID
%g Group ID
%d Dump mode
%s Signal number
%t UNIX time of dump
%h Hostname
%e Executable file
%E Executable file path

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

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

要永久启用核心转储,您需要编辑文件/etc/security/limits.conf,在文件末尾新增。

# End of file
*        soft        core          unlimited
*        hard        core          unlimited

核心转储文件格式
然而,核心文件过去只是一个二进制文件,因为在现代操作系统中,进程的地址空间可能不是顺序的,并且进程可能与其他进程共享页面,所以核心文件应该能够表示更多信息以及转储时程序的状态。在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;

作者:chacebai

出处:https://www.cnblogs.com/chacebai/p/17538786.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   这个世界太乱  阅读(133)  评论(0编辑  收藏  举报
努力加载评论中...
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示