core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump. (linux中如果内存越界会收到SIGSEGV信号,然后就会core dump)

在程序运行的过程中,有的时候我们会遇到Segment fault(段错误)这样的错误。这种看起来比较困难,因为没有任何的栈、trace信息输出。该种类型的错误往往与指针操作相关。往往可以通过这样的方式进行定位。

一 造成segment fault,产生core dump的可能原因

1.内存访问越界

a) 由于使用错误的下标,导致数组访问越界

b) 搜索字符串时,依靠字符串结束符来判断字符串是否结束,但是字符串没有正常的使用结束符

c) 使用strcpy, strcat, sprintf, strcmp, strcasecmp等字符串操作函数,将目标字符串读/写爆。应该使用strncpy, strlcpy, strncat, strlcat, snprintf, strncmp, strncasecmp等函数防止读写越界。

2 多线程程序使用了线程不安全的函数。

3 多线程读写的数据未加锁保护。对于会被多个线程同时访问的全局数据,应该注意加锁保护,否则很容易造成core dump

4 非法指针

a) 使用空指针

b) 随意使用指针转换。一个指向一段内存的指针,除非确定这段内存原先就分配为某种结构或类型,或者这种结构或类型的数组,否则不要将它转换为这种结构或类型的指针,而应该将这段内存拷贝到一个这种结构或类型中,再访问这个结构或类型。这是因为如果这段内存的开始地址不是按照这种结构或类型对齐的,那么访问它时就很容易因为bus error而core dump.

5 堆栈溢出.不要使用大的局部变量(因为局部变量都分配在栈上),这样容易造成堆栈溢出,破坏系统的栈和堆结构,导致出现莫名其妙的错误。

二 配置操作系统使其产生core文件

首先通过ulimit命令查看一下系统是否配置支持了dump core的功能。通过ulimit -c或ulimit -a,可以查看core file大小的配置情况,如果为0,则表示系统关闭了dump core。可以通过ulimit -c unlimited来打开。若发生了段错误,但没有core dump,是由于系统禁止core文件的生成。

解决方法:
$ulimit -c unlimited  (只对当前shell进程有效)
或在~/.bashrc 的最后加入: ulimit -c unlimited (一劳永逸)

# ulimit -c

0

$ ulimit -a

core file size          (blocks, -c) 0

data seg size           (kbytes, -d) unlimited

file size               (blocks, -f) unlimited

三 用gdb查看core文件

发生core dump之后, 用gdb进行查看core文件的内容, 以定位文件中引发core dump的行.

gdb [exec file] [core file]

如: gdb ./test test.core

使用gdb 调试方法,首先要在gcc编译时加入-g选项。

调试core文件,在Linux命令行下:gdb pname corefile。

例如,程序名为controller_tester,core文件为core.3421,则为:gdb controller_tester core.3421。

这样进入了gdb core调试模式。

追踪产生segmenttation fault的位置及代码函数调用情况:

gdb>bt

这样,一般就可以看到出错的代码是哪一句了,还可以打印出相应变量的数值,进行进一步分析。

gdb>print 变量名

之后,就全看各位自己的编程功力与经验了,gdb已经做了很多了。

2. 对于结构复杂的程序,如涉及模板类及复杂的调用,gdb得出了出错位置,似乎这还不够,这时候要使用更为专业的工具——valgrind。

valgrind是一款专门用作内存调试,内存泄露检测的开源工具软件,valgrind这个名字取自北欧神话英灵殿的入口,不过,不能不承认,它确实是Linux下做内存调用分析的神器。一般Linux系统上应该没有自带valgrind,需要自行进行下载安装。

下载地址:http://valgrind.org/downloads/current.html

进入下载文件夹,分别执行(需要root权限,且必须按默认路径安装,否则有加载错误):

./configure

make

make install

安装成功后,使用类似如下命令启动程序:

valgrind --tool=memcheck --leak-check=full --track-origins=yes --leak-resolution=high --show-reachable=yes --log-file=memchecklog ./controller_test

其中,–log-file=memchecklog指记录日志文件,名字为memchecklog;–tool=memcheck和–leak-check=full用于内存检测。

可以得到类似的记录:

==23735==
==23735== Thread 1:
==23735== Invalid read of size 4
==23735== at 0x804F327: ResourceHandler<HBMessage>::~ResourceHandler() (ResourceHandler.cpp:48)
==23735== by 0x804FDBE: ConnectionManager<HBMessage>::~ConnectionManager() (ConnectionManager.cpp:74)
==23735== by 0×8057288: MainThread::~MainThread() (MainThread.cpp:73)
==23735== by 0x8077B2F: main (Main.cpp:177)
==23735== Address 0×0 is not stack’d, malloc’d or (recently) free’d
==23735==

可以看到说明为无法访问Address 0x0,明显为一处错误。

这样valgrind直接给出了出错原因以及程序中所有的内存调用、释放记录,非常智能,在得知错误原因的情况下,找出错误就效率高多了。

再说一句,valgrind同时给出了程序的Memory Leak情况的报告,给出了new-delete对应情况,所有泄漏点位置给出,这一点在其他工具很难做到,十分好用。

http://blog.csdn.net/sunlylorn/article/details/7836832#t6

http://blog.csdn.net/sunlylorn/article/details/7836953

core dump gdb调试的更多相关文章

  1. 用core dump来调试程序段错误

    有的程序可以通过编译, 但在运行时会出现Segment fault(段错误). 这通常都是指针错误引起的.但这不像编译错误一样会提示到文件->行, 而是没有任何信息, 使得我们的调试变得困难起来 ...

  2. CORE DUMP生成调试

    之前我调试嵌入式linux程序,一般是借助ucontext库,在发生段错误时,直接将错误函数打印出来.有同事建议我使用core dump,于是我今天在嵌入式板卡尝试了core文件的生成,但是也是几经波 ...

  3. linux (core dump)调试

    转自 http://www.cnblogs.com/hazir/p/linxu_core_dump.html Linux Core Dump 当程序运行的过程中异常终止或崩溃,操作系统会将程序当时的内 ...

  4. 在Linux上利用core dump和GDB调试segfault

    时常会遇到段错误(segfault),调试非常费劲,除了单元测试和基本测试外,有些时候是在在线环境下,没有基本开发和测试工具,这就需要调试的技能.以前介绍过使用strace进行系统调试和追踪<l ...

  5. linux core dump 文件 gdb分析

    core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump. (linux中如果内存越界会收到SIG ...

  6. 什么是core dump?(转)

    什么是Core Dump? 今天调试一个程序, 用到了core dump, 于是写出来, 记于此.什么是Core Dump?Core的意思是内存, Dump的意思是扔出来, 堆出来.开 发和使用Uni ...

  7. 关于内核转储(core dump)的设置方法

    原作者:http://blog.csdn.net/wj_j2ee/article/details/7161586 1. 内核转储作用 (1) 内核转储的最大好处是能够保存问题发生时的状态. (2) 只 ...

  8. core dump 配置

    引用:http://www.cnblogs.com/secondtonone1/p/5732938.html Windows环境崩溃问题可根据vs调试工具查看,Linux同样可以查看调用堆栈的信息,只 ...

  9. Linux环境崩溃生成core文件以及调试

    Linux环境崩环境溃生成core文件以及调试 gdb结合coredump定位崩溃进程 Linux 使用core file文件快速定位程序崩溃代码行 http://www.cnblogs.com/ha ...

随机推荐

  1. SVN和git的使用(附github的简单玩法)

    今天简单的总结了下SVN和git的使用,也尝试了下github,应该好好提高下自己的英文水平了,梦想有一天不再使用任何翻译软件. [svn]:集中式的代码管理工具(版本控制工具--版本记录) 1> ...

  2. ArcGIS实现在线与线交叉处打断线(批量)

    from:http://he1989.blog.163.com/blog/static/2052041092012631112459704/ 打开ArcgisDesktop中的ArcToolBox 找 ...

  3. 【WPF】WPF通过RelativeSource绑定父控件的属性

    1.后台代码实现绑定父控件的属性 RelativeSource rs = new RelativeSource(RelativeSourceMode.FindAncestor); //设定为离自己控件 ...

  4. 【C#】【Thread】上下文同步域SynchronizationAttribute

    上下文同步:使用SynchronizationAttribute为ContextBoundObject对象创建一个简单的自动的同步. 这种同步方式仅用于实例化的方法和域的同步.所有在同一个上下文域的对 ...

  5. [Elixir007] on_definition规范函数定义时的各种潜规则

    1.需求 写一个基于memcache的cache模块, 需要在key前面加上特定的前缀, 所以user cache的原始的store函数应该写成 # user.exdef store(user_id, ...

  6. swift 判断输入的字符串是否为数字

    // 判断输入的字符串是否为数字,不含其它字符 func isPurnInt(string: String) -> Bool { let scan: Scanner = Scanner(stri ...

  7. c语言 数组名是常量指针

    //数组名是常量指针 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include ...

  8. WebAPI使用多个xml文件生成帮助文档(转)

    http://www.cnblogs.com/idoudou/p/xmldocumentation-for-web-api-include-documentation-from-beyond-the- ...

  9. matlab中findstr,strfind,strcmp,strncmp区别与联系

    在Matlab中,这几个函数区分如下: (以下默认S1和S2是字符串,同样也适用于cell细胞类型数据,也就是循环对cell中每个元素分别判断即可.) findstr(S1,S2):寻找是否有S1和S ...

  10. Ubuntu下eclipse安装svn插件

    好记性不如烂笔头,碰见一个不大不小的问题,记录下. 系统:Ubuntu 12.04 Eclipse:eclipse-jee-kepler-R-linux-gtk.tar.gz subclipse:1. ...