`
jubincn
  • 浏览: 242398 次
  • 性别: Icon_minigender_1
  • 来自: 宁波
文章分类
社区版块
存档分类
最新评论

GDB简单教程

 
阅读更多

本文的内容基本来自http://www.cs.cmu.edu/~gilpin/tutorial/这篇教程,我在使用里面的示例程序时遇到了”<iostream.h> is not a file or directory” 的错误,因此修改了一下原来到源程序。

源代码:

为了使读者更快地学习gdb,本文提供了一个带有bug的示例程序,以及一个简单的makefile,我把他们打包上传到这里,不需积分即可下载。在学习本文到过程中,读者可以通过调试这个示例程序来获得更好的体验。
这个示例程序很简单,包含两个类:Node和LinkedList。为了方便调试,我们将这两个类放到一个文件中。

前期准备

环境设置

首先检查是否安装gdb。如果您的系统中有g++,那么gdb就已经安装了。可以通过在命令行中输入gdb -v来检查是否安装gdb。

Debugging Symbols

gdb只能使用g++产生的symbol进行调试。如果读者使用Sun Cc编译器,那么可以使用一个和gdb很类似到调试工具:dbx
在调试带有debugging symbol的程序时,gdb才能如鱼得水。使用g++的-g选项,即可编译出带有gdb的debugging symbol的程序。除-g选项外,还可以使用-ggdb选项,本文的makefile里面即使用了-ggdb选项。

使用GDB调试

编译程序

首先,切换到含有前面下载的两个文件的目录,然后使用make命令进行编译。
make -f makefile
编译完成后,会生成一个名为main的可执行文件。

加载程序

使用gdb main命令即可将main可执行文件加载到gdb中。在我的终端,使用这个命令的结果如下:
GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2
Copyright (C) 2010 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 "i686-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/jubin/Downloads/gdb_sample/main...done.
(gdb)
(注:在emacs中,您可以使用M-x gdb来在emacs中使用gdb。Emacs将分成两个窗口,第二个窗口将显示代码,并有个箭头指向正在执行的指令所在的代码行。)

gdb启动后,此时正在等待用户输入下一个指令。因为需要查看程序错在哪里,所以首先需要运行这个程序,输入run命令:
(gdb) run
Starting program: /home/jubin/Downloads/gdb_sample/main
Creating Node, 1 are in existence right now
Creating Node, 2 are in existence right now
Creating Node, 3 are in existence right now
Creating Node, 4 are in existence right now
The fully created list is:
4
3
2
1
Now removing elements:
Creating Node, 5 are in existence right now
Destroying Node, 4 are in existence right now
4
3
2
1
Program received signal SIGSEGV, Segmentation fault.
0x08048cb4 in Node<int>::next (this=0x0) at main.cc:30
30Node<T>* next () const { return next_; }
(gdb)
显然,这段程序出错了,下面我们来分析下错误出在什么地方。

检查出错信息

从上面的出错信息可以看出在main.cc的第30行,this指针指向了0。但同时我们还想知道谁调用了第30行,以及调用程序的当时状态。在gdb提示符中输入:backtrace
(gdb) backtrace
#0 0x08048cb4 in Node<int>::next (this=0x0) at main.cc:30
#1 0x08048bea in LinkedList<int>::remove (this=0x804c008, item_to_remove=@0xbffff2c4)at main.cc:79
#2 0x080488d6 in main (argc=1, argv=0xbffff3a4) at main.cc:122
(gdb)
从上面的信息不仅可以看到出错的方法和局部变量,还可以找到调用第30行的程序以及调用时使用的参数item_to_remove的存储地址。x命令可以使我们根据item_to_remove的地址获得item_to_remove的值:
(gdb) x 0xbffff2c4
0xbffff2c4:0x00000001
(gdb)

从上面的信息可以看出,当使用参数“1”调用LinkedList<int>::remove时,程序出错。

条件断点

现在我们知道哪里出错了,下一步要做的是查看在出错前程序的状态。一种方法是步进,直到快出错的那个位置,另一种就是设置断点,在gdb中这样实现:

(gdb) break LinkedList<int>::remove

Breakpoint 1 at 0x8048ab3: file main.cc, line 54.

(gdb)

这样位于 LinkedList<int>::remove的断点“1”就设置好了。如果我们只想查看item_to_remove==1时的状态,那么需要使用条件断点,在gdb中输入:


(gdb) condition 1 item_to_remove == 1
(gdb)
这个命令的意思是只有在“item_to_remove == 1”的情况下,断点“1”才会生效。

步进

gdb中步进的命令是step。gdb有一个很好的特性,当用户只输入回车时默认执行上一个命令,因此步进时只需在第一步输入step,后面直接敲击回车就可以了。
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/jubin/Downloads/gdb_sample/main
Creating Node, 1 are in existence right now
Creating Node, 2 are in existence right now
Creating Node, 3 are in existence right now
Creating Node, 4 are in existence right now
The fully created list is:
4
3
2
1

Now removing elements:
Creating Node, 5 are in existence right now
Destroying Node, 4 are in existence right now
4
3
2
1


Breakpoint 1, LinkedList<int>::remove (this=0x804c008, item_to_remove=@0xbffff2f4)
at main.cc:54
54Node<T> *marker = head_;
(gdb) step
55Node<T> *temp = 0; // temp points to one behind as we iterate
(gdb)
57while (marker != 0) {
(gdb)
58if (marker->value() == item_to_remove) {
(gdb)
Node<int>::value (this=0x804c058) at main.cc:32
32const T& value () const { return value_; }
(gdb)
LinkedList<int>::remove (this=0x804c008, item_to_remove=@0xbffff2f4) at main.cc:77
77marker = 0; // reset the marker
(gdb)
78temp = marker;
(gdb)
79marker = marker->next();
(gdb)
Node<int>::next (this=0x0) at main.cc:30
30Node<T>* next () const { return next_; }
(gdb)
Program received signal SIGSEGV, Segmentation fault.
0x08048cb4 in Node<int>::next (this=0x0) at main.cc:30
30Node<T>* next () const { return next_; }
(gdb)
离开gdb的命令:quit
分享到:
评论

相关推荐

    jubincn博文“GDB简单教程”中的示例程序

    本教程将基于jubincn在其CSDN博客文章“GDB简单教程”中提供的示例程序进行深入讲解。通过学习GDB,开发者可以更好地理解代码运行时的状态,定位并修复程序错误。 首先,让我们来看看核心文件`main.cc`,它是示例...

    Linux下简单GDB调试教程

    ### Linux下简单GDB调试教程 #### GDB简介与调试基础 GDB(GNU调试器)是一款强大的开源调试工具,广泛应用于Linux环境下的程序调试。它可以帮助开发者在开发过程中识别和修复程序中的错误,提高软件质量。GDB支持...

    linux下GDB调试教程

    ### Linux下GDB调试教程详解 #### 一、GDB简介 GDB(GNU Debugger)是一款强大且功能全面的命令行调试工具,适用于多种UNIX-like系统,包括Linux。与图形界面调试工具相比,GDB提供了更为灵活和深入的调试能力。在...

    GDB调试简易教程.

    linux环境下,代码调试,多线程调试,常用调试方式快速定位问题

    Linux下GDB命令经典教程

    ### GDB在Linux下的经典应用教程 #### 一、引言 GDB(GNU调试器)是GNU项目的一部分,是一款非常强大的开源调试工具,广泛应用于Linux等类Unix系统上。对于程序员来说,掌握GDB的基本操作是十分必要的,因为无论是...

    GDB教程pdf格式

    ### GDB教程知识点详解 #### 一、GDB简介与特点 GDB(GNU Debugger)是一款功能强大的开源调试工具,适用于UNIX系统。它允许开发者在命令行环境下对C/C++等编程语言编写的程序进行调试。相较于图形界面的调试工具...

    linux下GDB教程

    Linux下的GDB教程主要介绍了GDB这一强大的命令行调试工具,旨在帮助用户从初学者成长为高级用户。GDB,即GNU调试器,是由GNU开源组织发布,用于UNIX平台下软件的调试。它是命令行工具,具有高度的集成性和可扩展性,...

    LINUX下GDB教程

    由于命令行工具的可扩展性,使用一些简单的命令就可以组合出强大的功能,而且UNIX下的软件通常全都是命令行的,这使得在UNIX平台下的软件开发和调试更为便捷。而Windows平台的图形化软件通常各自独立,难以集成使用...

    GDB调试开发教程

    在上述示例中,我们看到一个简单的C程序`test.c`,其中包含一个计算前n个自然数之和的函数`func`。通过`gcc -g`编译选项,我们生成了包含调试信息的可执行文件`test`。接着,我们启动GDB并加载这个程序。`list`命令...

    linux下GDB教程.pdf

    GDB 是一个强大的命令行调试工具。大家知道命令行的强大就是在于,其可以形成执行序列,形成脚本。UNIX 下的软件全是命令行的,这给程序开发提供了极大的便利,命令行软件的优势在于,他们可以非常容易的集成在一起...

    debugging_with_gdb(中文版pdf)

    通过上述分析可以看出,“debugging_with_gdb(中文版pdf)”不仅是一份简单的手册,更是一个全面的教程,旨在帮助用户深入了解和高效使用 GDB 调试器。无论是初学者还是有一定经验的开发者,都可以从中获得有价值的...

    arcpy读取MDB数据库&创建GDB数据库&MDB转换GDB.zip

    总结,这个压缩包的资源可能包含示例脚本或教程,教你如何使用arcpy模块处理MDB数据库,创建GDB数据库,并将MDB数据转换到GDB格式。这些操作对于GIS专业人士来说是日常工作中常见的任务,特别是在迁移旧数据或整合...

    利用ArcGis API解析FileGDB

    本教程将深入探讨如何利用ArcGIS API来解析FileGDB,帮助你理解和应用这一关键技能。 **1. ArcGIS API介绍** ArcGIS API是一种基于JavaScript的编程接口,它允许开发者在Web环境中创建地图应用程序和进行空间数据...

    GO语言的gdb64

    3. **示例项目**:包含一个简单的Go语言程序,用于演示如何使用gdb64进行调试。 4. **命令参考**:列出gdb64的常用命令和选项,帮助用户熟悉其操作。 5. **故障排除**:提供常见问题和解决方案,帮助用户解决调试...

    GDB调试学习手册 简单实用

    《GDB调试学习手册》是一本专为程序员和软件开发者设计的实用教程,旨在帮助读者掌握GDB(GNU调试器)的基本操作和高级技巧。GDB是开源社区GNU开发的一款强大的程序调试工具,广泛应用于C、C++等语言的调试工作。...

    Linux调试工具GDB使用简易教程

    本文所述主要是Linux调试工具GDB的使用教程,具体如下。 声明:本博客内容是由本人经过实验楼教程整理得来。 GDB的相关概念 GDB, 是 The GNU Project Debugger 的缩写, 是 Linux 下功能全面的调试工具。GDB 支持断点...

    debugging with gdb

    下面通过一个简单的示例来展示这些基本操作。 #### 启动GDB GDB可以通过命令行启动。例如: ``` gdb my_program ``` 其中`my_program`是要调试的程序名称。 #### 设置断点 设置断点可以让程序暂停执行,以便于...

    打包GDB&GCC&G++&AUTOMAKE&MAKEFILE教程

    这个“打包GDB&GCC&G++&AUTOMAKE&MAKEFILE教程”提供了全面的学习资源,帮助开发者一站式掌握这些核心技术。 1. **GDB**(GNU Debugger): GDB是一个强大的源代码级调试器,适用于多种编程语言,包括C、C++、...

Global site tag (gtag.js) - Google Analytics