`
jubincn
  • 浏览: 233232 次
  • 性别: 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博文“GDB简单教程”中的示例程序,http://blog.csdn.net/jubincn/article/details/6774524

    Linux下简单GDB调试教程

    •file 装入想要调试的可执行文件. •kill 终止正在调试的程序. •list 列出产生执行文件的源代码的一部分. •next 执行一行源代码但不进入函数内部. ...•shell 使你能不离开gdb就执行UNIX shell 命令

    GDB调试简易教程.

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

    linux gdb教程.pdf

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

    linux下GDB调试教程

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

    linux下GDB教程.pdf

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

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

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

    gdb调试解二进制炸弹

    二进制炸弹简单教程及示例。 简述二进制炸弹的构造原理,以及如何在linux环境下使用gdb调试拆弹。

    linux中gdb的入门使用教程

    gdb是linux下非常好用的一个调试工具,虽然它是命令行模式的调试工具,但是它的功能强大到你无法想象,这里简单介绍下gdb的使用方法,需要的朋友们下面来一起看看详细的介绍吧。 断点 在代码的指定位置中断,使程序...

    Demo:ArcEngine简单教程——加载数据

    ArcEngine简单教程——加载数据Demo,包括加载mxd、shp、grid、dat、img等数据 工程文件及测试数据 备份链接:链接:https://pan.baidu.com/s/14GoGMb88fagBGrkJloLpHQ 提取码:qfss 教程博客:...

    Linux开发入门:使用gdb调试C/C++入门教程

    GDB(GNU symbolic debugger)简单地说就是一个调试工具。它是一个受通用公共许可证即GPL保护的自由软件。 像所有的调试器一样,GDB可以让你调试一个程序,包括让程序在你希望的地方停下,此时你可以查看变量、...

    vgdb:适用于C和C ++程序的Visual Studio Code GDB调试适配器

    vGDB | Visual Studio代码GDB调试适配器用于Visual Studio Code的GDB... 假设您的可执行文件名为a.out ,那么入门非常简单: 还有一个附加请求的代码段。配置这些是当前支持的所有设置:启动请求配置选项必需的描述ar

    GCC使用教程.pdf

    3. gdb 使用 4. gcc 常用选项对代码的影响 1. 一般情况 2. -O 编译选项 3. -O2 编译选项 4. -fomit-frame-pointer 编译选项 5. -fomit-frame-pointer && -O2 6. -fPIC 编译选项 7. -static 编译选项 5. AT&T 的汇编...

    嵌入式Linux应用程序开发标准教程(第2版全)

    3.1.1 C语言简单回顾 3.1.2 Linux下C语言编程环境概述 3.2 常用编辑器 3.2.1 进入vi 3.2.2 初探emacs 3.3 gcc编译器 3.3.1 gcc编译流程解析 3.3.2 gcc编译选项分析 3.4 gdb调试器 3.4.1 gdb使用流程 3.4.2 gdb基本...

    Redis开发 保姆级Redis开发教程.zip

    保姆级Redis开发教程.zip 简介 Redis 是完全开源的,遵守 BSD 协议,是一个高性能的 key-value 数据库。(NO-SQL) Tips:特点 Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载...

    经典GCC_使用教程

    3. gdb使用 4. gcc常用选项对代码的影响 1. 一般情况 2. -O 编译选项 3. -O2 编译选项 4. -fomit-frame-pointer 编译选项 5. -fomit-frame-pointer && -O2 6. -fPIC 编译选项 7. -static 编译选项 5. AT&T...

    Linux学习笔记Linux学习资料Linux教程

    【linux学习笔记-1】使用GDB调试简单的用户程序.doc 【linux学习笔记-2】父子进程共享文件描述符.doc 【linux学习笔记-3】文件操作(stat,chmod,umask).doc 【linux学习笔记-4】进程扇和进程链.doc 【linux学习笔记-...

    mini2440国嵌视频教程+课件+工具+软件+镜像+教程源码下载地址

    -国嵌应用班-1-2(GDB程序调试).avi -国嵌应用班-1-3(makefile工程管理).avi -国嵌应用班-1-4(必修实验).avi -第2天(文件时间编程) -国嵌应用班-2-1(系统调用方式访问文件).avi -国嵌应用班-2-2(库函数...

    SkyEye教程

    由于SkyEye建立在GDB基础之上,使用者可以方便地使用GDB提供的各种调试手段对SkyEye仿真系统上的软件进行源码级的调试,还可以进行各种分析,如执行热点分析、程序执行覆盖度分析等。由于SkyEye提供了源代码和相关...

Global site tag (gtag.js) - Google Analytics