原文:http://xmodulo.com/gdb-command-line-debugger.html作者:
Adrien Brochard


没有调试器的情况下编写程序时最糟糕的状况是什么?编译时跪着祈祷不要出错?用血祭召唤恶魔帮你运行程序?或者在每一行代码间添加printf("test")语句来定位错误点?如你所知,编写程序时不使用调试器的话是不方便的。幸好,linux下调试还是很方便的。大多数人使用的IDE都集成了调试器,但 linux 最著名的调试器是命令行形式的C/C++调试器GDB。然而,与其他命令行工具一致,DGB需要一定的练习才能完全掌握。这里,我会告诉你GDB的基本情况及使用方法。

安装GDB

大多数的发行版仓库中都有GDB

Debian 或 Ubuntu

  1. $ sudo apt-get install gdb

Arch Linux

  1. $ sudo pacman -S gdb

Fedora,CentOS 或 RHEL:

  1. $sudo yum install gdb

如果在仓库中找不到的话,可以从官网中下载

示例代码

当学习GDB时,最好有一份代码,动手试验。下列代码是我编写的简单例子,它可以很好的体现GDB的特性。将它拷贝下来并且进行实验——这是最好的方法。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main(int argc, char **argv)
  4. {
  5. int i;
  6. int a=0, b=0, c=0;
  7. double d;
  8. for (i=0; i<100; i++)
  9. {
  10. a++;
  11. if (i>97)
  12. d = i / 2.0;
  13. b++;
  14. }
  15. return 0;
  16. }

GDB的使用

首先最重要的,你需要使用编译器的 “-g“选项来编译程序,这样可执行程序才能通过GDB来运行。通过下列语句开始调试:

  1. $ gdb -tui [可执行程序名]

使用”-tui“选项可以将代码显示在一个漂亮的交互式窗口内(所以被称为“文本用户界面 TUI”),在这个窗口内可以使用光标来操控,同时在下面的GDB shell中输入命令。

现在我们可以在程序的任何地方设置断点。你可以通过下列命令来为当前源文件的某一行设置断点。

  1. break [行号]

或者为一个特定的函数设置断点:

  1. break [函数名]

甚至可以设置条件断点

  1. break [行号] if [条件]

例如,在我们的示例代码中,可以设置如下:

  1. break 11 if i > 97

这样,程序循环97次之后停留在“a++”语句上。这样是非常方便的,避免了我们需要手动循环97次。

最后但也是很重要的是,我们可以设置一个“观察断点”,当这个被观察的变量发生变化时,程序会被停止。

  1. watch [变量]

这里我们可以设置如下:

  1. watch d

当d的值发生变化时程序会停止运行(例如,当i>97为真时)。

当设置断点后,使用"run"命令开始运行程序,或按如下所示:

  1. r [程序的输入参数(如果有的话)]

gdb中,大多数的命令单词都可以简写为一个字母。

不出意外,程序会停留在11行。这里,我们可以做些有趣的事情。下列命令:

  1. bt

回溯功能(backtrace)可以让我们知道程序如何到达这条语句的。

  1. info locals

这条语句会显示所有的局部变量以及它们的值(你可以看到,我没有为d设置初始值,所以它现在的值是任意值)。

当然:

  1. p [变量]

这个命令可以显示特定变量的值,而更进一步:

  1. ptype [变量]

可以显示变量的类型。所以这里可以确定d是double型。

既然已经到这一步了,我么不妨这么做:

  1. set var [变量] = [新的值]

这样会覆盖变量的值。不过需要注意,你不能创建一个新的变量或改变变量的类型。我们可以这样做:

  1. set var a = 0

如其他优秀的调试器一样,我们可以单步调试:

  1. step

使用如上命令,运行到下一条语句,有可能进入到一个函数里面。或者使用:

  1. next

这可以直接运行下一条语句,而不进入子函数内部。

结束测试后,删除断点:

  1. delete [行号]

从当前断点继续运行程序:

  1. continue

退出GDB:

  1. quit

总之,有了GDB,编译时不用祈祷上帝了,运行时不用血祭了,再也不用printf(“test“)了。当然,这里所讲的并不完整,而且GDB的功能远远不止于此。所以我强烈建议你自己更加深入的学习它。我现在感兴趣的是将GDB整合到Vim中。同时,这里有一个备忘录记录了GDB所有的命令行,以供查阅。

你对GDB有什么看法?你会将它与图形调试器对比吗,它有什么优势呢?对于将GDB集成到Vim有什么看法呢?将你的想法写到评论里。


via: http://xmodulo.com/gdb-command-line-debugger.html

使用GDB命令行调试器调试C/C++程序的更多相关文章

  1. VS2013中带命令行参数的调试方法---C++

    今天先记录一下(也是传说中大神喜欢装逼的comment line)c++中向主函数int main(int argc,char** argv )传递4中方法,欢迎添加新方法, 然后可以参考别人写的很好 ...

  2. vscode带命令行参数进行调试

    vscode带命令行参数进行调试 2.输入代码 { // 使用 IntelliSense 了解相关属性. // 悬停以查看现有属性的描述. // 欲了解更多信息,请访问: https://go.mic ...

  3. C#比较两个对象是否为同一个对象。 Visual Studio调试器指南---多线程应用程序调试(一)

    两个对象是否为同一个对象:是看两个对象是否指向堆中的同一块内存. 1.使用object.ReferenceEquals() class Program { static void Main(strin ...

  4. MellPlayer, 基于网易云歌单的命令行播放器

    MellPlayer 前言 我写代码时非常喜欢听音乐,最近在网易云歌单中听到了许多入耳惊艳的歌,觉得非常不错.但是歌单的随机播放以及快速切换是个软肋,于是开发了MellPlayer,可以按照分类随机听 ...

  5. ubuntu 下命令行播放器mplayer 使用详解

    ubuntu 下命令行播放器mplayer 使用详解 2011-01-02 21:00:42|  分类: Linux/Unix |  标签: |字号大中小 订阅 使用 MPlayer 播放媒体文件最简 ...

  6. 使用GDB命令行调试器调试C/C++程序【转】

    转自:https://linux.cn/article-4302-1.html 编译自:http://xmodulo.com/gdb-command-line-debugger.html作者: Adr ...

  7. VS2013 带命令行参数的调试问题 解决方案

    int main(int argc,char* argv[]) argc是命令行总的参数个数,argv[]是argc个参数,其中第0个参数是程序的全名,以后的参数命令行后面跟的用户输入的参数 比如:  ...

  8. 屹今为止最好用的HTTP客户端命令行工具-接口调试神器HTTPie

    一.思考❓❔ 1.你用过哪些http客户端调试工具? Postman 不够灵活 需要打开客户端, 麻烦 学习成本高 Jmeter 臃肿 麻烦 学习成本高 curl 参数多, 记不住 不够灵活 主要在L ...

  9. GDB命令行最基本操作

    程序启动: A.冷启动 gdb program              e.g., gdb ./cs gdb –p pid                 e.g., gdb –p `pidof c ...

随机推荐

  1. TeamView 无法捕捉画面问题的解决办法

    teamview是个非常不错的远程协助软件,你要是在项目中还搞个QQ远程协助啥的就显的非常不专业了. 在teamview连接远程后,看到的是一片漆黑,中间框提示"现在无法捕捉画面.这可能是由 ...

  2. activiti实战系列 排他网关(ExclusiveGateWay)

    流程图 12.2:部署流程定义+启动流程实例 12.3:查询我的个人任务 12.4:完成我的个人任务 说明: 1)     一个排他网关对应一个以上的顺序流 2)     由排他网关流出的顺序流都有个 ...

  3. 全文检索 Lucene(4)

    经过了前面几篇文章的学习,我们基本上可以适用Lucene来开发我们的站内搜索应用了.但是观察一下目前的主流的搜索引擎,我们会发现查询结果会有高亮的显示效果.所以,今天我们就来学习一下,给Lucene添 ...

  4. Struts 2 之拦截器

    拦截器概述 Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP(Aspect Oriented Progr ...

  5. gitlab的搭建及问题的解决

    gitlab则是类似于github的一个工具,github无法免费建立私有仓库,并且为了代码安全,于是在内网安装了一个自己实验室的一个git服务器,gitlab有很多依赖,而bitnami制作了一键安 ...

  6. 04 Spinner 列表选中

    <span style="font-size:18px;"> <?xml version="1.0" encoding="utf-8 ...

  7. Java-IO之CharArrayWriter(字符数组输出流)

    CharArrayWriter用于写数据,数据单位是字符. (1) 通过CharArrayWriter()创建的CharArrayWriter对应的字符数组大小是32. (2) 通过CharArray ...

  8. Andriod的国际化-android学习之旅(五十八)

    android资源国际化

  9. HBase作为存储方案

    HBase存储特点 * Client 1. 包含访问HBase的接口,并维护cache来加快对HBase的访问,比如region的位置信息. * Zookeeper: 1. 选举集群中的Master, ...

  10. Maven项目中获取classpath和资源文件的路径

     假设资源文件放在maven工程的 src/main/resources 资源文件夹下,源码文件放在 src/main/java/下, 那么java文件夹和resources文件夹在运行时就是cl ...