用GDB调试Segmentation 段错误【转】

本文转载自:http://blog.csdn.net/learnhard/article/details/4879834

调试Linux程序的时候,出现Segmentation Fault是最郁闷的事情了,程序代码量很大的时候,可能花很多时间都找不到出错原因。

这里介绍一种对你调试Segmentation Fault很有帮助的方法,可能能迅速帮助你找到出错的代码行。

这种方法需要用到Linux提供的core dump机制:当程序中出现内存操作错误时,会发生崩溃并产生核心文件(core文件)。使用GDB可以对产生的核心文件进行分析,找出程序是在什么时候崩溃的和在崩溃之前程序都做了些什么。

首先,你的Segmentation Fault错误必须要能重现(废话…)。

然后,依参照下面的步骤来操作:

(1)无论你是用Makefile来编译,还是直接在命令行手工输入命令来编译,都应该加上 -g 选项。

(2)一般来说,在默认情况下,在程序崩溃时,core文件是不生成的(很多Linux发行版在默认时禁止生成核心文件)。所以,你必须修改这个默认选项,在命令行执行:

ulimit -c unlimited

表示不限制生成的core文件的大小。

(3)运行你的程序,不管用什么方法,使之重现Segmentation Fault错误。

(4)这时,你会发现在你程序同一目录下,生成了一个文件名为 core.*** 的文件,即核心文件。例如,“core.15667”这样的文件。

(5)用GDB调试它。假设你的可执行程序名为test,则在命令行执行:

gdb test core.15667

然后可能会显示出一堆信息:

GNU gdb Fedora (6.8-27.el5)

Copyright (C) 2008 Free Software Foundation, Inc.

License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software: you are free to change and redistribute it.

There is NO WARRANTY, to the extent permitted by law.  Type "show copying"

and "show warranty" for details.

This GDB was configured as "i386-redhat-linux-gnu"...

warning: Can‘t read pathname for load map: Input/output error.

…………………(中间还有很多内容,此处省略)……………………………

Loaded symbols for /usr/lib/libgpg-error.so.0

Core was generated by `./test‘.

Program terminated with signal 11, Segmentation fault.

[New process 15668]

#0  0x0804c760 in thread _handler () at test.cpp:707

707                             CDev* cur_dev = *it_d;

然后我们输入并执行命令 bt 

(gdb) bt

就会得到类似于下面的信息:

#0  0x0804c760 in thread _handler () at test.cpp:707

#1  0x006b149b in start_thread () from /lib/libpthread.so.0

#2  0x0060842e in clone () from /lib/libc.so.6

于是,我们一眼就看出来了:程序是在第707行使用指针时出的问题。

怎么样,方便吧?

时间: 2024-10-12 20:12:10

用GDB调试Segmentation 段错误【转】的相关文章

通过gdb快速定位“段错误”的位置

有些时候我们在一段 C/C++ 代码的时候,由于对一个非法内存进行了操作,在程序运行的过程中,出现了"Segmentation fault (core dumped)"--段错误. 呵呵,这种问题我想很多人会经常遇到.遇到这种问题是非常无语的,只是提示了"段错误",接着什么都没有,如果我们一味的去看代码找太疼苦了,因为我们都相信自己写的代码没问题,现实就是现实.接着,我们可能通过打印来定位到段错误的位置,这样会有个问题,如果代码量大,我们需要打印很多信息才能找到&q

什么是core dump linux下用core和gdb查询出现&quot;段错误&quot;的地方

什么是core dump   linux下用core和gdb查询出现"段错误"的地方 http://blog.chinaunix.net/uid-26833883-id-3193279.html 有些时候我们在一段C代码的时候,由于对一个非法内存进行了操作,在程序运行的过程中,出现了"段错误". 呵呵,这种问题我想很多人会经常遇到.遇到这种问题是非常无语的,只是提示了"段错误",接着什么都没 有,如果我们一味的去看代码找太疼苦了,因为我们都相信自

eclipse+CDT调试segmentation fault错误

先来看两段代码-- 错误代码: #include "string.h" #include <stdlib.h> #include <stdio.h> void test(char ** dest, char * src, int n) { (*dest) = (char*) malloc(sizeof(char) * n); strcpy(*dest, src); } int main(int argc, char** args) { char ** p = N

Linux 下的段错误(Segmentation fault)调试方法

我们在用C/C++语言写程序的时侯,内存管理的绝大部分工作都是需要我们来做的.实际上,内存管理是一个比较繁琐的工作,无论你多高明,经验多丰富,难免会在此处犯些小错误,而通常这些错误又是那么的浅显而易于消除.但是手工“除虫”(debug),往往是效率低下且让人厌烦的,本文将就"段错误"这个内存访问越界的错误谈谈如何快速定位这些"段错误"的语句. 下面将就以下的一个存在段错误的程序介绍几种调试方法: 1 dummy_function (void) 2 { 3 unsig

段错误bug的调试

我们在用C/C++语言写程序的时侯,内存管理的绝大部分工作都是需要我们来做的.实际上,内存管理是一个比较繁琐的工作,无论你多高明,经验多丰富,难 免会在此处犯些小错误,而通常这些错误又是那么的浅显而易于消除.但是手工“除虫”(debug),往往是效率低下且让人厌烦的,本文将就"段错误"这个 内存访问越界的错误谈谈如何快速定位这些"段错误"的语句.下面将就以下的一个存在段错误的程序介绍几种调试方法:      1  dummy_function (void)    

C&amp;C++——段错误(Segmentation fault)

C/C++中的段错误(Segmentation fault) Segment fault 之所以能够流行于世,是与Glibc库中基本所有的函数都默认型参指针为非空有着密切关系的.来自:http://oss.lzu.edu.cn/blog/article.php?uid_7/tid_700.html#comment 背景 最近一段时间在linux下用C做一些学习和开发,但是由于经验不足,问题多多.而段错误就是让我非常头痛的一个问题.不过,目前写一个一千行左右的代码,也很少出现段错误,或者是即使出现

gdb、core 以及段错误

查看系统是否允许生成core文件 #ulimit -a core file size          (blocks, -c) 0 core文件大小限制为0,不能生成core文件 使用如下命令取消限制,使系统能生成core文件 ulimit -c unlimited 一般linux操作系统默认core文件的大小都是0,需要手动设置一下. 调试core文件 core文件是个二进制文件,需要用相应的工具来分析程序崩溃时的内存映像. 用gdb查看core文件:下面我们可以在发生运行时信号引起的错误时

段错误以及调试方式

dummy_function(void) { unsigned char * ptr=0x00; *ptr=0x00; } int main() { dummy_function(); return 0; }作为一名熟练的c/c++程序员,以上代码的bug应该是很清楚的,因为它尝试操作地址为0的内存区域,而这个地址区域通常是不可访问的禁区,当然会出错了. 方法1 :利用gdb逐步查找段错误 这种方法也是被大众所熟知并广泛采用的方法,首先我们需要一个带有调试 信息的可执行程序,所以我们加上"-g

段错误以及调试方法

---恢复内容开始--- 常见内存错误 (1)内存分配(malloc, new)未成功,却使用了它. 解决方法:在使用内存之前检查指针是否为NULL (2)内存分配成功,但是没有初始化.在定义数组时养成赋0值的习惯. (3)内存分配成功,也初始化了,操作越过了内存的边界. (4)忘记释放内存,造成内存泄漏 (5)释放了内存后继续使用,有三种情况: 程序中的对象调用过于复杂,比如: int *a = new int[10]; int *b = a; delete b;//已经将a所指向的内存释放