2017-10-13 14:06:54 pwl999 阅读数 397

1、Core dump概念

linux下一个用户态程序出错通常会报出“Segmentation fault”并退出。如果系统使能了“core dump”功能,系统会给崩溃的进程拍一个临终快照存储到一个core文件当中,快照中包括进程所有的内存、cpu寄存器、os状态标志等等。程序出故障以后,可以使用gdb来调试快照文件,定位程序当时出现了什么故障。

Core dump的说明:

A core dump is the recorded state of the working memory of a computer program at a specific time, generally when the program has terminated abnormally (crashed). In practice, other key pieces of program state are usually dumped at the same time, including the processor registers, which may include the program counter and stack pointer, memory management information, and other processor and operating system flags and information. The name comes from the once-standard memory technology core memory. Core dumps are often used to diagnose or debug errors in computer programs.

On many operating systems, a fatal error in a program automatically triggers a core dump, and by extension the phrase “to dump core” has come to mean, in many cases, any fatal error, regardless of whether a record of the program memory is created.

快照文件是一个core类型的elf文件,elf专门为这种类型的文件定义了一种类型:

1
2

2、Core dump的使能

使用“ulimit -a”查看本系统coredump的配置情况:

3

“Core file size”这一行指定了core dump文件的最大大小。使用“ulimit –c xxx”指定core dump文件的大小限制,“ulimit –c unlimited”配置为无限大。

Core dump文件生成的路径和格式在“/proc/sys/kernel/core_pattern”文件中指定:

4

3、Core dump的使用

  • 第一步、编写一个会出错的用户程序,并编译出带调试信息的可执行文件。

    5

  • 第二步、运行会出错的可执行文件,生成core dump文件。

6

运行出错提示“Segmentation fault (core dumped)”,在“/proc/sys/kernel/core_pattern”定义的路径“/usr/local/cdp/core-%e-%p-%t”下面可以看到新生成的core文件“core-test_coredump-22614-1353319306”

  • 第三步、使用gdb调试core文件。

把源代码c文件、带调试信息的可执行文件、core文件拷贝到同一目录中,使用“gdb xxxexe xxxcore”命令,就可以调试出错当时的场景。

7

2016-01-25 11:43:48 u013010310 阅读数 3177

最近本人负责项目中的流媒体转发模块,查了很多资料后选择了EasyDarwin作为转发服务器。编译源码之后服务器稳定运行了半个月,但是今天突然不能正常转发了。由于本人Linux新手,所以没有在Linux下调试代码的经验,在群主的指导下知道可以设置core文件来调试代码,于是几经周折完成了core文件的设置,特将过程记录下来。

什么是coredump

当程序运行的过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中,这种行为就叫做Core Dump(中文有的翻译成“核心转储”)。我们可以认为 core dump 是“内存快照”,但实际上,除了内存信息之外,还有些关键的程序运行状态也会同时 dump 下来,例如寄存器信息(包括程序指针、栈指针等)、内存管理信息、其他处理器和操作系统状态和信息。core dump 对于编程人员诊断和调试程序是非常有帮助的,因为对于有些程序错误是很难重现的,例如指针异常,而 core dump 文件可以再现程序出错时的情景。

Linux下打开coredump

本人使用的Linux发行版是Ubantu 14.04,设置生成coredump文件的方法如下:

  • 打开core dump功能
    在终端中输入命令ulimit -c(也可以通过ulimit -a查看) 输出的结果为 0,说明默认是关闭 core dump 的,即当程序异常终止时,也不会生成 core dump 文件。
    这里写图片描述
    我们可以使用命令 ulimit -c unlimited 来开启 core dump 功能,并且不限制 core dump 文件的大小; 如果需要限制文件的大小,将 unlimited 改成你想生成 core 文件最大的大小,注意单位为 blocks(KB)。
    用上面命令只会对当前的终端环境有效,如果想需要永久生效,可以修改文件/etc/bash.bashrc文件,添加一行ulimit -c unlimited,然后执行命令source /etc/bash.bashrc生效。此时通过ulimit -a查看:
    这里写图片描述
    (有网友的资料是直接修改/etc/security/limits.conf文件,但是我测试了没有效果。)
  • 设置core文件保存路径
    默认生成的 core 文件保存在可执行文件所在的目录下,文件名就为 core,修改此文件名方法有两种:
    1、通过修改/proc/sys/kernel/core_uses_pid文件可以让生成 core 文件名是否自动加上 pid 号。命令如下:echo 1 > /proc/sys/kernel/core_uses_pid生成的 core 文件名将会变成 core.pid,其中 pid 表示该进程的 PID。

    2、还可以通过修改/proc/sys/kernel/core_pattern 来控制生成 core 文件保存的位置以及文件名格式。命令可以用 echo "/EasyDarwin/corefile-%e-%p-%t" > /proc/sys/kernel/core_pattern 设置生成的 core 文件保存在 /EasyDarwin/ 目录下,文件名格式为 “core-命令名-pid-时间戳”。其中:
    其中:

    • %c 转储文件的大小上限
    • %e 所dump的文件名
    • %g 所dump的进程的实际组ID
    • %h 主机名
    • %p 所dump的进程PID
    • %s 导致本次coredump的信号
    • %t 转储时刻(由1970年1月1日起计的秒数)
    • %u 所dump进程的实际用户ID

gdb调试core文件

产生了 core 文件,我们该如何使用该 Core 文件进行调试呢?Linux 中可以使用 GDB 来调试 core 文件,步骤如下:

  • 首先,写段错误代码,这个对程序猿来说很简单,使用 gcc 编译源文件,加上 -g 以增加调试信息;
#include<stdio.h>

int main()
{
    int *p = NULL;
    *p = 2;
    printf("%d",*p);
    return 0;
}

编译:

gcc -g -o test test.c
  • 运行程序,以使程序异常终止时能生成 core 文件;
./test
  • 当core dump 之后,使用命令 gdb program core 来查看 core 文件,其中 program为可执行程序名,core 为生成的 core 文件名。
gdb test core

这里写图片描述

可以看到gdb直接定位到了程序中出错的具体行。至于具体gdb的使用方法本人也还在摸索之中。需要说明的是,要是EasyDarwin能在错误时产生core文件,需要使用./Built debug命令来编译源程序。最后感谢EasyDarwin群主的热心帮助。

2019-12-10 15:27:10 zhang355 阅读数 3

1, Core Dump 是什么

Core Dump一般我们说是核心转储,在进程异常时的一个快照,保存了异常时的内存、寄存器、堆栈等数据。这些数据存储成一个文件

2,开启 Core Dump 功能

Linux Core Dump 记录功能系统默认是未开启的状态

查看是否开启了 Core Dump 功能:

ulimit -c

如果返回 0, 则未开启该功能

临时开启:

ulimit -c unlimited

永久开启需要修改 /etc/security/limits.config 文件,增加如下图配置项即可

修改 Core Dump 文件地址, 需要修改 /proc/sys/kernel/core_pattern 配置文件

echo "/tmp/corefile-%e-%p-%t" > /proc/sys/kernel/core_pattern

写入 /tmp/corefile-%e-%p-%t 配置到文件,格式名为 core-命令名称-pid-时间戳,可以自己定义

3, 查看 Core Dump

查看 Core Dump 文件需要使用到  gdb 工具,格式为  gdb coredump 文件

gdb 工具系统默认是没有安装的, 使用 yum 安装即可

yum install gdb

gdb 调试

gdb 程序名 coredump文件

 

2015-11-12 18:38:42 frogoscar 阅读数 556



内容简介

【调试】Core Dump是什么?Linux下如何正确永久开启?



Core Dump是什么?Linux下如何正确永久开启?


Core Dump是什么?


Core Dump乍听之下很抽象。


当程序运行的过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中,这种行为就叫做Core Dump(中文有的翻译成“核心转储”)。


我们可以认为Core Dump是“内存快照”,但实际上,除了内存信息之外,还有些关键的程序运行状态也会同时dump下来,例如寄存器信息(包括程序指针、栈指针等)、内存管理信息、其他处理器和操作系统状态和信息。


Core Dump 对于编程人员诊断和调试程序是非常有帮助的,因为对于有些程序错误是很难重现的,例如指针异常,而 Core Dump 文件可以再现程序出错时的情景。


在半导体作为电脑内存材料之前,电脑内存使用的是 磁芯内存(Magnetic Core Memory),Core Dump 中的 Core 沿用了磁芯内存的 Core 表达。图为磁芯内存的一个单元,来自 Wikipedia.




在 APUE (《Unix环境高级编程》)一书中作者有句话这样写的:


Because the file is named core, it shows how long this feature has been part of the Unix System.


这里的Core就是沿用的是早期电脑磁芯内存中的表达,也能看出Unix系统Core Dump机制的悠久历史。


Dump 指的是拷贝一种存储介质中的部分内容到另一个存储介质,或者将内容打印、显示或者其它输出设备。dump 出来的内容是格式化的,可以使用一些工具来解析它。


现代操作系统中,用Core Dump表示当程序异常终止或崩溃时,将进程此时的内存中的内容拷贝到磁盘文件中存储,以方便编程人员调试。


如何开启Core Dump?


临时开启Core Dump,并且设置大小不受限:


命令行输入:


ulimit -c unlimited


要永久打开Core Dump并且使之大小不受限,网上说有两种方法:


1. 打开 core dump 功能

    1. 在终端中输入命令 ulimit -c ,输出的结果为 0,说明默认是关闭 core dump 的,即当程序异常终止时,也不会生成 core dump 文件。

    2. 我们可以使用命令 ulimit -c unlimited 来开启 core dump 功能,并且不限制 core dump 文件的大小; 如果需要限制文件的大小,将 unlimited 改成你想生成 core 文件最大的大小,注意单位为 blocks(KB)。

    3. 用上面命令只会对当前的终端环境有效,如果想需要永久生效,可以修改文件 /etc/security/limits.conf文件。增加一行:


# /etc/security/limits.conf
#
#Each line describes a limit for a user in the form:
#
#<domain>   <type>   <item>   <value>
   *          soft     core   unlimited


2. 在/etc/profile中加入


ulimit  -c unlimited




我试了以上两种方法,但是输入


ulimit -c


输出结果始终是0。


后来自己想了一种方法,在Ubuntu下可以:


编辑 .bashrc 文件:

vi ~/.bashrc


添加:

ulimit -c unlimited


保存,退出。

source ~/.bashrc


source命令使修改立即生效。

2013-10-22 15:06:22 hazir 阅读数 1335
当程序运行的过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中,这种行为就叫做Core Dump(中文有的翻译成“核心转储”)。我们可以认为 core dump 是“内存快照”,但实际上,除了内存信息之外,还有些关键的程序运行状态也会同时 dump 下来,例如寄存器信息(包括程序指针、栈指针等)、内存管理信息、其他处理器和操作系统状态和信息。core dump 对于编程人员诊断和调试程序是非常有帮助的,因为对于有些程序错误是很难重现的,例如指针异常,而 core dump 文件可以再现程序出错时的情景。

Core Dump 名词解释

在半导体作为电脑内存材料之前,电脑内存使用的是 磁芯内存(Magnetic Core Memory),Core Dump 中的 Core 沿用了磁芯内存的 Core 表达。图为磁芯内存的一个单元,来自 Wikipedia.

在 APUE 一书中作者有句话这样写的:

Because the file is named core, it shows how long this feature has been part of the Unix System.

这里的 core 就是沿用的是早期电脑磁芯内存中的表达,也能看出 Unix 系统 Core Dump 机制的悠久历史。由此我们也能知道其实将"core dump"翻译称"核心转储"并不太准备, 翻译成"内存转储"更恰当一些.

Dump 指的是拷贝一种存储介质中的部分内容到另一个存储介质,或者将内容打印、显示或者其它输出设备。dump 出来的内容是格式化的,可以使用一些工具来解析它。

现代操作系统中,用 Core Dump 表示当程序异常终止或崩溃时,将进程此时的内存中的内容拷贝到磁盘文件中存储,以方便编程人员调试。

Core Dump 如何产生

上面说当程序运行过程中异常终止崩溃时会发生 core dump,但还没说到什么具体的情景程序会发生异常终止或崩溃,例如我们使用 kill -9 命令杀死一个进程会发生 core dump 吗?实验证明是不能的,那么什么情况会产生呢?

Linux 中信号是一种异步事件处理的机制,每种信号对应有其默认的操作,你可以在 这里 查看 Linux 系统提供的信号以及默认处理。默认操作主要包括忽略该信号(Ingore)、暂停进程(Stop)、终止进程(Terminate)、终止并发生core dump(core)等。如果我们信号均是采用默认操作,那么,以下列出几种信号,它们在发生时会产生 core dump:

Signal Action Comment
SIGQUIT Core Quit from keyboard
SIGILL Core Illegal Instruction
SIGABRT Core Abort signal from abort
SIGSEGV Core Invalid memory reference
SIGTRAP Core Trace/breakpoint trap

当然不仅限于上面的几种信号。这就是为什么我们使用 Ctrl+z 来挂起一个进程或者 Ctrl+C 结束一个进程均不会产生 core dump,因为前者会向进程发出 SIGTSTP 信号,该信号的默认操作为暂停进程(Stop Process);后者会向进程发出SIGINT 信号,该信号默认操作为终止进程(Terminate Process)。同样上面提到的 kill -9 命令会发出 SIGKILL 命令,该命令默认为终止进程。而如果我们使用 Ctrl+\ 来终止一个进程,会向进程发出 SIGQUIT 信号,默认是会产生 core dump 的。还有其它情景会产生 core dump, 如:程序调用 abort() 函数、访存错误、非法指令等等。

下面举两个例子来说明:

  • 终端下比较 Ctrl+C 和 Ctrl+\

    guohailin@guohailin:~$ sleep 10        #使用sleep命令休眠 10 s
    ^C                           #使用 Ctrl+C 终止该程序,不会产生 core dump
    guohailin@guohailin:~$ sleep 10
    ^\Quit (core dumped)                #使用 Ctrl+\ 退出程序, 会产生 core dump
    guohailin@guohailin:~$ ls         #多出下面一个 core 文件
    -rw-------  1 guohailin guohailin 335872 10月 22 11:31 sleep.core.21990
    
  • 小程序产生 core dump

    #include <stdio.h>
    
    int main()
    {
        int *null_ptr = NULL;
        *null_ptr = 10;            //对空指针指向的内存区域写,会发生段错误
        return 0;
    }
    
    #编译执行
    guohailin@guohailin:~$ ./a.out
    Segmentation fault (core dumped)
    guohailin@guohailin:~$ ls      #多出下面一个 core 文件
    -rw-------  1 guohailin guohailin 200704 10月 22 11:35 a.out.core.22070    
    

Linux 下打开 Core Dump

我使用的 Linux 发行版是 Ubuntu 13.04,设置生成 core dump 文件的方法如下:

  • 打开 core dump 功能

    • 在终端中输入命令 ulimit -c ,输出的结果为 0,说明默认是关闭 core dump 的,即当程序异常终止时,也不会生成 core dump 文件。
    • 我们可以使用命令 ulimit -c unlimited 来开启 core dump 功能,并且不限制 core dump 文件的大小; 如果需要限制文件的大小,将 unlimited 改成你想生成 core 文件最大的大小,注意单位为 blocks(KB)。
    • 用上面命令只会对当前的终端环境有效,如果想需要永久生效,可以修改文件 /etc/security/limits.conf文件,关于此文件的设置参看 这里 。增加一行:
    # /etc/security/limits.conf
    #
    #Each line describes a limit for a user in the form:
    #
    #<domain>   <type>   <item>   <value>
        *          soft     core   unlimited
    
  • 修改 core 文件保存的路径

    • 默认生成的 core 文件保存在可执行文件所在的目录下,文件名就为 core
    • 通过修改 /proc/sys/kernel/core_uses_pid 文件可以让生成 core 文件名是否自动加上 pid 号。
      例如 echo 1 > /proc/sys/kernel/core_uses_pid ,生成的 core 文件名将会变成 core.pid,其中 pid 表示该进程的 PID。
    • 还可以通过修改 /proc/sys/kernel/core_pattern 来控制生成 core 文件保存的位置以及文件名格式。
      例如可以用 echo "/tmp/corefile-%e-%p-%t" > /proc/sys/kernel/core_pattern 设置生成的 core 文件保存在 “/tmp/corefile” 目录下,文件名格式为 “core-命令名-pid-时间戳”。这里 有更多详细的说明!

使用 gdb 调试 Core 文件

产生了 core 文件,我们该如何使用该 Core 文件进行调试呢?Linux 中可以使用 GDB 来调试 core 文件,步骤如下:

  • 首先,使用 gcc 编译源文件,加上 -g 以增加调试信息;
  • 按照上面打开 core dump 以使程序异常终止时能生成 core 文件;
  • 运行程序,当core dump 之后,使用命令 gdb program core 来查看 core 文件,其中 program 为可执行程序名,core 为生成的 core 文件名。

下面用一个简单的例子来说明:

#include <stdio.h>
int func(int *p)
{
    int y = *p;
    return y;
}
int main()
{
    int *p = NULL;
    return func(p);
}

编译加上调试信息, 运行之后core dump, 使用 gdb 查看 core 文件.

guohailin@guohailin:~$ gcc core_demo.c -o core_demo -g
guohailin@guohailin:~$ ./core_demo 
Segmentation fault (core dumped)

guohailin@guohailin:~$ gdb core_demo core_demo.core.24816
...
Core was generated by './core_demo'.
Program terminated with signal 11, Segmentation fault.
#0  0x080483cd in func (p=0x0) at core_demo.c:5
5       int y = *p;
(gdb)  where
#0  0x080483cd in func (p=0x0) at core_demo.c:5
#1  0x080483ef in main () at core_demo.c:12
(gdb) info frame
Stack level 0, frame at 0xffd590a4:
 eip = 0x80483cd in func (core_demo.c:5); saved eip 0x80483ef
 called by frame at 0xffd590c0
 source language c.
 Arglist at 0xffd5909c, args: p=0x0
 Locals at 0xffd5909c, Previous frame's sp is 0xffd590a4
 Saved registers:
  ebp at 0xffd5909c, eip at 0xffd590a0
(gdb) 

从上面可以看出,我们可以还原 core_demo 执行时的场景,并使用 where 可以查看当前程序调用函数栈帧, 还可以使用 gdb 中的命令查看寄存器,变量等信息.

参考资料

没有更多推荐了,返回首页