为了使读者更快地学习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.2Copyright (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) runStarting program: /home/jubin/Downloads/gdb_sample/mainCreating Node, 1 are in existence right nowCreating Node, 2 are in existence right nowCreating Node, 3 are in existence right nowCreating Node, 4 are in existence right nowThe fully created list is:4321Now removing elements:Creating Node, 5 are in existence right nowDestroying Node, 4 are in existence right now4321Program received signal SIGSEGV, Segmentation fault.0x08048cb4 in Node<int>::next (this=0x0) at main.cc:3030Node<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 0xbffff2c40xbffff2c4: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) runThe program being debugged has been started already.Start it from the beginning? (y or n) yStarting program: /home/jubin/Downloads/gdb_sample/mainCreating Node, 1 are in existence right nowCreating Node, 2 are in existence right nowCreating Node, 3 are in existence right nowCreating Node, 4 are in existence right nowThe fully created list is:4321Now removing elements:Creating Node, 5 are in existence right nowDestroying Node, 4 are in existence right now4321Breakpoint 1, LinkedList<int>::remove (this=0x804c008, item_to_remove=@0xbffff2f4)at main.cc:5454Node<T> *marker = head_;(gdb) step55Node<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:3232const T& value () const { return value_; }(gdb)LinkedList<int>::remove (this=0x804c008, item_to_remove=@0xbffff2f4) at main.cc:7777marker = 0; // reset the marker(gdb)78temp = marker;(gdb)79marker = marker->next();(gdb)Node<int>::next (this=0x0) at main.cc:3030Node<T>* next () const { return next_; }(gdb)Program received signal SIGSEGV, Segmentation fault.0x08048cb4 in Node<int>::next (this=0x0) at main.cc:3030Node<T>* next () const { return next_; }(gdb)离开gdb的命令:quit
分享到:
相关推荐
jubincn博文“GDB简单教程”中的示例程序,http://blog.csdn.net/jubincn/article/details/6774524
•file 装入想要调试的可执行文件. •kill 终止正在调试的程序. •list 列出产生执行文件的源代码的一部分. •next 执行一行源代码但不进入函数内部. ...•shell 使你能不离开gdb就执行UNIX shell 命令
linux环境下,代码调试,多线程调试,常用调试方式快速定位问题
GGDDBB教程 GDB是一个强大的命令行调试工具。大家知道命令行的强大就是在于,其可以形成执行 序列,形成脚本。UNIX下的软件全是命令行的,这给程序开发提供了极大的便利,命令行 软件的优势在于,他们可以非常...
这是中文版的,GDB 是一个强大的命令行调试工具。大家知道命令行的强大就是在于,其可以形成执行 序列,形成脚本。 UNIX 下的软件全是命令行的,这给程序开发提供了极大的便利,命令 行 软件的优势在于,他们可以...
GDB 是一个强大的命令行调试工具。大家知道命令行的强大就是在于,其可以形成执行序列,形成脚本。UNIX 下的软件全是命令行的,这给程序开发提供了极大的便利,命令行软件的优势在于,他们可以非常容易的集成在一起...
本文所述主要是Linux调试工具GDB的使用教程,具体如下。 声明:本博客内容是由本人经过实验楼教程整理得来。 GDB的相关概念 GDB, 是 The GNU Project Debugger 的缩写, 是 Linux 下功能全面的调试工具。GDB 支持断点...
二进制炸弹简单教程及示例。 简述二进制炸弹的构造原理,以及如何在linux环境下使用gdb调试拆弹。
gdb是linux下非常好用的一个调试工具,虽然它是命令行模式的调试工具,但是它的功能强大到你无法想象,这里简单介绍下gdb的使用方法,需要的朋友们下面来一起看看详细的介绍吧。 断点 在代码的指定位置中断,使程序...
ArcEngine简单教程——加载数据Demo,包括加载mxd、shp、grid、dat、img等数据 工程文件及测试数据 备份链接:链接:https://pan.baidu.com/s/14GoGMb88fagBGrkJloLpHQ 提取码:qfss 教程博客:...
GDB(GNU symbolic debugger)简单地说就是一个调试工具。它是一个受通用公共许可证即GPL保护的自由软件。 像所有的调试器一样,GDB可以让你调试一个程序,包括让程序在你希望的地方停下,此时你可以查看变量、...
vGDB | Visual Studio代码GDB调试适配器用于Visual Studio Code的GDB... 假设您的可执行文件名为a.out ,那么入门非常简单: 还有一个附加请求的代码段。配置这些是当前支持的所有设置:启动请求配置选项必需的描述ar
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 的汇编...
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开发教程.zip 简介 Redis 是完全开源的,遵守 BSD 协议,是一个高性能的 key-value 数据库。(NO-SQL) Tips:特点 Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载...
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学习笔记-1】使用GDB调试简单的用户程序.doc 【linux学习笔记-2】父子进程共享文件描述符.doc 【linux学习笔记-3】文件操作(stat,chmod,umask).doc 【linux学习笔记-4】进程扇和进程链.doc 【linux学习笔记-...
-国嵌应用班-1-2(GDB程序调试).avi -国嵌应用班-1-3(makefile工程管理).avi -国嵌应用班-1-4(必修实验).avi -第2天(文件时间编程) -国嵌应用班-2-1(系统调用方式访问文件).avi -国嵌应用班-2-2(库函数...
由于SkyEye建立在GDB基础之上,使用者可以方便地使用GDB提供的各种调试手段对SkyEye仿真系统上的软件进行源码级的调试,还可以进行各种分析,如执行热点分析、程序执行覆盖度分析等。由于SkyEye提供了源代码和相关...