浏览关于coredump的文章时,下面两篇文章说的清晰易懂,转发下:

https://blog.csdn.net/asdfghjkl0606/article/details/52841678

https://blog.csdn.net/stpeace/article/details/119699330

http://wjhsh.net/zhchoutai-p-6717780.html

第一篇:简单介绍coredump基本概念和操作

引言:程序在Linux系统中运行时出错的时间并不能预测,也许在三分钟之内程序就崩溃了,也许运行一个月之后才发生错误。

如果前一节课学到的GDB调试,显然调试上十天半个月是不可能的。这里我们用core dump来解决。

一、Core Dump:信息转存、核心转存。

core dump是一个过程,即Linux会把程序运行过程中发生异常的内存内容转存到core文件。

core dump主要解决段错误(Segment fault)。

 


二、发生段错误的基本原因有:

1、数组访问越界;

2、对空指针操作;

3、栈溢出;

4、修改只读内存的内容。

三、启用/关闭 Core Dump:

 

打开:ulimit -c unlimited

关闭:ulimit -c 0

(在Linux系统中默认关闭该功能)

 

四、Core文件分析:

 在发生core dump之后会在该程序所在路径下生成一个core文件。

注意:在编译程序时需要用-g来加入调试信息,否则将让错误逃之夭夭。

> gdb  ./test  core.13140

#include <stdio.h>
#include <stdlib.h>
 
void main()
{
    int *ptr = NULL;
    
    *ptr = 3;
}

 

 

第二篇:告诉你一般定位这类问题的思路


core的最原始含义是磁芯,是一种存储设备,dump的意思是倒出,那么core dump的含义就是:当进程发生异常时,会把当时的内存信息倾倒出来,形成core文件。

每个做linux C++开发的人,必然会遇到过core dump问题。在C++相关的面试中,core dump的调试,几乎是一个必考的考点,旨在检验应聘者的实战调试经验。

我知道的一个真实案例是:面试官让应聘者现场写出一个core dump程序,结果应聘者很懵圈,不知道怎么写。这说明,应聘者没有相关的调试经历,何谈通过面试?

接下来,我们以一个简单的core dump程序为例,来说说调试core dump的六种经验和方法,希望能对大家的开发实战有所帮助,顺便地,横扫那些简单的面试题。

 

 

方法一: 代码review

代码review,是一种比较原始的笨方法。对于简单的代码而言,还可以进行review, 但是,一旦代码达到数万行,出现core dump后,便无从看起。所以,这种方法很鸡肋,几乎没什么用。

方法二: 打印log夹逼

打印log来夹逼,也是一种很简单的方法,在很多场景下,非常奏效。许多大学生和职场新手,容易出现core dump问题,那么, 我建议直接用log夹逼。有点类似二分查找,且看具体的姿势:其实很多老鸟也是这么做的。

 

 

 

 方法三: dmesg + addr2line

有时候,如果core dump的开关没有打开,无法生成core文件,那怎么办呢?也是有办法的!用dmesg和addr2line吧。关于这两个命令的介绍,直接man一下即可。且看具体调试:​​​​​​​

 

 以前确实没用过dmesg。按照上面的操作没出现相关的段错误。在(Ubuntu 9.4.0-1上面测试不会出现。

在centos上操作确实出现。出现的IP就可以直接拿来使用,对应的就是出问题的代码行。

 

  

方法四: strace + addr2line

接下来,我们介绍一个重要的linux命令,即strace, 直接man一下就知道,它是用查看系统调用的,我们不过多赘述。来看具体的调试过程:​​​​​​​

 

 

 

 

 后面跟的那串数字是什么含义?地址?通过这个地址可以对应到具体的代码行。

实际操作的时候可以看到段错误。但是addr2line 后面那个a.out没有对应的。对应的就是main. 在centos上可以看到。

 

 

方法五: valgrind

之前,在调试内存泄漏时,介绍过valgrind,其实valgrind能查其他更多内存问题,非常强大。下面,我们来看看valgrind查core dump问题,如下:

 valgrind 是 Linux 业内流行且十分强劲的内存泄漏查验专用工具。在其官方网站详细介绍中,运行内存查验(memcheck)仅仅其在其中一个作用。因为仅用过其内存泄漏的查验,也不扩展共享 valgrind 别的作用了。

没有使用过。暂不描述。

 

方法六: gdb

gdb调试,是本文的重头戏,也几乎是笔试面试的必考内容。话不多说,直接来看姿势。使用gdb a.out core(不会重新拉取a.out进程)或者gdb a.out(会重新拉起a.out进程)都可以,如下:​​​​​​​

 

 

 第三篇:linux程序调试命令addr2line之入门简单介绍

addr2line有什么作用呢? 可别小瞧它, 它能够定位到代码出错的位置。

以下, 我们来看看这个简单的代码:

 #include <stdio.h>

int main()
{
        int *p = NULL;
        *p = 0;

        printf("bad");
        return 0;
}

       这个程序非常小, 我们能够一眼就看出程序在执行期出错。 可是, 假设是大程序, 在执行期出错。 我们该怎样定位呢?  那就必须依赖于工具。 而不是你我的肉眼。

我们以上述小程序为例, 进行例如以下操作:

 

[taoge@localhost learn_c]$ gcc -o taogeSeg -g taogeSeg.c 
[taoge@localhost learn_c]$ ./taogeSeg 
Segmentation fault (core dumped)
[taoge@localhost learn_c]$ dmesg | grep taogeSeg
taogeSeg[4941]: segfault at 0 ip 080483c9 sp bfb92410 error 6 in taogeSeg[8048000+1000]
[taoge@localhost learn_c]$ addr2line -e taogeSeg 080483c9
/home/taoge/Desktop/learn_c/taogeSeg.c:6
[taoge@localhost learn_c]$ cat -n taogeSeg.c
     1	#include <stdio.h>
     2	
     3	int main()
     4	{
     5		int *p = NULL;
     6		*p = 0;
     7	
     8		printf("bad
");
     9		return 0;
    10	}
[taoge@localhost learn_c]$ 
但是我在实际操作过程中,发现dmesg没有任何相关的linux core信息出来。不清楚是不是linux版本问题。
 我来解释一下:
       1. gcc -o taogeSeg -g taogeSeg.c :生成带有调试信息的可运行文件taogeSeg
       2. dmesg | grep taogeSeg :获得运行taogeSeg后的出错信息, 你能够将结果理解为日志, 当中的080483c9是一个地址, 正是这个地址出错了
       3. addr2line -e taogeSeg 080483c9 :将出错地址转换成源码相应的行, 结果为6, 也就是说源码第6行有问题。 一看, 果然是,万恶的*p=0;被揪出来了。

       当然。 针对这个样例, 会gdb调试的朋友肯定也能调试出来,并且也确实能找到代码出错的地址和源码行, 从这个意义上来讲。 gdb内部也携带了类addr2line的功能。这是不是说gdb就能够替代addr2line呢? 不是的。

 

假设某bug低概率发生。 如今仅仅有一份crash log, 那就要用addr2line了, 由于你用gdb时。 该bug不一定发生啊。

 


    
       实际上, 在非常多linux大型软件开发中, 常常出现段错误, 造成进程挂掉, 系统崩溃等问题, 此时, 用addr2line是比較好的方法。

 

在后面的博文中, 我们会继续了解与addr2line有关的调试方法, 毕竟, 代码调试太重要了。事实上呢, 假设不熟悉addr2line的使用, 或者干脆没有听说过这个命令, 那最好不要说自己搞linux开发。 免得被人歧视啊。 



       OK, 本文仅仅是一个引子, 能在实战中熟练使用addr2line才见真功夫。

 

如能熟练掌握addr2line的使用。 以后听到什么段错误, 系统崩溃。 就没那么毛骨悚然了。

posted on 2022-12-07 17:07  shiyuan310  阅读(975)  评论(0编辑  收藏  举报