GDB中应该知道的几个调试方法

七、八年前写过一篇《用GDB调试程序》, 于是,从那以后,很多朋友在MSN上以及给我发邮件询问我关于GDB的问题,一直到今天,还有人在问GDB的相关问题。这么多年来,有一些问题是大家反复 在问的,一方面,我觉得我以前的文章可能没有说清楚,另一方面,我觉得大家常问的问题正是最有用的,所以,在这里罗列出来。希望大家补充。

一、多线程调试

多线程调试可能是问得最多的。其实,重要就是下面几个命令:

  • info thread 查看当前进程的线程。
  • thread <ID> 切换调试的线程为指定ID的线程。
  • break file.c:100 thread all  在file.c文件第100行处为所有经过这里的线程设置断点。
  • set scheduler-locking off|on|step,这个是问得最多的。在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。
    • off 不锁定任何线程,也就是所有线程都执行,这是默认值。
    • on 只有当前被调试程序会执行。
    • step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。

二、调试宏

这个问题超多。在GDB下,我们无法print宏定义,因为宏是预编译的。但是我们还是有办法来调试宏,这个需要GCC的配合。

在GCC编译程序的时候,加上-ggdb3参数,这样,你就可以调试宏了。

另外,你可以使用下述的GDB的宏调试命令 来查看相关的宏。

  • info macro – 你可以查看这个宏在哪些文件里被引用了,以及宏定义是什么样的。
  • macro – 你可以查看宏展开的样子。

三、源文件

这个问题问的也是很多的,太多的朋友都说找不到源文件。在这里我想提醒大家做下面的检查:

  1. 编译程序员是否加上了-g参数以包含debug信息。
  2. 路径是否设置正确了。使用GDB的directory命令来设置源文件的目录。

下面给一个调试/bin/ls的示例(ubuntu下)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ apt-get source coreutils
$ sudo apt-get install coreutils-dbgsym
$ gdb /bin/ls
GNU gdb (GDB) 7.1-ubuntu
(gdb) list main
1192    ls.c: No such file or directory.
in ls.c
(gdb) directory ~/src/coreutils-7.4/src/
Source directories searched: /home/hchen/src/coreutils-7.4:$cdir:$cwd
(gdb) list main
1192        }
1193    }
1194
1195    int
1196    main (int argc, char **argv)
1197    {
1198      int i;
1199      struct pending *thispend;
1200      int n_files;
1201

四、条件断点

条件断点是语法是:break  [where] if [condition],这种断点真是非常管用。尤其是在一个循环或递归中,或是要监视某个变量。注意,这个设置是在GDB中的,只不过每经过那个断点时GDB会帮你检查一下条件是否满足。

五、命令行参数

有时候,我们需要调试的程序需要有命令行参数,很多朋友都不知道怎么设置调试的程序的命令行参数。其实,有两种方法:

  1. gdb命令行的 –args 参数
  2. gdb环境中 set args命令。

六、gdb的变量

有时候,在调试程序时,我们不单单只是查看运行时的变量,我们还可以直接设置程序中的变量,以模拟一些很难在测试中出现的情况,比较一些出错,或是switch的分支语句。使用set命令可以修改程序中的变量。

另外,你知道gdb中也可以有变量吗?就像shell一样,gdb中的变量以$开头,比如你想打印一个数组中的个个元素,你可以这样:

1
2
3
4
5
(gdb) set $i = 0
 
(gdb) p a[$i++]
 
...  #然后就一路回车下去了

当然,这里只是给一个示例,表示程序的变量和gdb的变量是可以交互的。

七、x命令

也许,你很喜欢用p命令。所以,当你不知道变量名的时候,你可能会手足无措,因为p命令总是需要一个变量名的。x命令是用来查看内存的,在gdb中 “help x” 你可以查看其帮助。

  • x/x 以十六进制输出
  • x/d 以十进制输出
  • x/c 以单字符输出
  • x/i  反汇编 – 通常,我们会使用 x/10i $ip-20 来查看当前的汇编($ip是指令寄存器)
  • x/s 以字符串输出

八、command命令

有一些朋友问我如何自动化调试。这里向大家介绍command命令,简单的理解一下,其就是把一组gdb的命令打包,有点像字处理软件的“宏”。下面是一个示例:

1
2
3
4
5
6
7
8
9
10
(gdb) break func
Breakpoint 1 at 0x3475678: file test.c, line 12.
(gdb) command 1
Type commands for when breakpoint 1 is hit, one per line.
End with a line saying just "end".
>print arg1
>print arg2
>print arg3
>end
(gdb)

当我们的断点到达时,自动执行command中的三个命令,把func的三个参数值打出来。

(全文完)

GDB调试增强篇的更多相关文章

  1. 《gdb调试之基础篇》

    <gdb调试之基础篇> http://blog.csdn.net/miss_acha/article/details/42346543

  2. gdb调试coredump(使用篇)

    gdb调试coredump(使用篇) 看到一个非常好的介绍coredump的文章,做个记录, 参考链接: https://blog.csdn.net/sunxiaopengsun/article/de ...

  3. GDB调试技巧:总结篇

    目录 一 写在开头 1.1 本文内容 二 学习资料 三 常用命令 四 调试技巧 注:原创不易,转载请务必注明原作者和出处,感谢支持! 一 写在开头 1.1 本文内容 总结GDB调试的一些常用命令和调试 ...

  4. 使用GDB调试Go语言

    用Go语言已经有一段时间了,总结一下如何用GDB来调试它! ps:网上有很多文章都有描述,但是都不是很全面,这里将那些方法汇总一下 GDB简介  GDB是GNU开源组织发布的⼀一个强⼤大的UNIX下的 ...

  5. 20145314郑凯杰《信息安全系统设计基础》GDB调试32位汇编堆栈分析

    20145314郑凯杰<信息安全系统设计基础>GDB调试32位汇编堆栈分析 本篇博客将对第五周博客中的GDB调试32位汇编堆栈进行分析 首先放上以前环境配置的图: 图1: 测试代码: #i ...

  6. nginx模块_使用gdb调试nginx源码

    工欲善其事必先利其器,如何使用调试工具gdb一步步调试nginx是了解nginx的重要手段. ps:本文的目标人群是像我这样初接触Unix编程的同学,如果有什么地方错误请指正. 熟悉gdb的使用 这里 ...

  7. 比较全面的gdb调试命令 (转载)

    转自http://blog.csdn.net/dadalan/article/details/3758025 用GDB调试程序 GDB是一个强大的命令行调试工具.大家知道命令行的强大就是在于,其可以形 ...

  8. 使用gdb调试游戏服务器

    前言 谈论gdb重要性 一般来说.提gdb,命令用于调试."命令",用户是几乎相同的复杂话.而事实确实如此,实际的开发调试必须用到gdb. 如今.大多数Linux系统是存在于ser ...

  9. Nginx学习之十四-GDB调试Nginx初试

    本文的测试环境: Win7+虚拟机VMWareVMware-workstation-full-7.1.4-385536+Ubuntu12.04 Nginx-1.4.0 要想有效的研究Nginx源码,必 ...

随机推荐

  1. [hdu6316]Odd shops

    记$m=10$,即商品的种类 记$g(x)=1+\sum_{i=1}^{m}a_{i}x_{i}$,问题即求$f_{n}(x)=g^{n}(x)$非0项数(模2意义下) 注意到$f^{2}(x)\eq ...

  2. [atAGC106E]Medals

    暴力二分答案+网络流,点数为$o(nk)$,无法通过 考虑Hall定理,即有完美匹配当且仅当$\forall S\subseteq V_{left}$,令$S'=\{x|\exists y\in V_ ...

  3. [bzoj1691]挑剔的美食家

    考虑将奶牛和牧草放在一起,根据鲜嫩程度排序,那么显然就可以发现一个贪心策略:每一头奶牛一定选择当前剩余的最便宜且符合条件的牧草,然后用一个set维护价格即可 1 #include<bits/st ...

  4. java 适配器模式实现代码

    目录 1.适配器模式 1.1.类适配器 1.2.对象适配器 2.适配器模式实例 1.适配器模式 适配器模式可以分为类适配器和对象适配器. 1.1.类适配器 //目标接口 interface Targe ...

  5. 洛谷 P5299 - [PKUWC2018]Slay the Spire(组合数学+dp)

    题面传送门 hot tea 啊--这种风格及难度的题放在省选 D2T1 左右还是挺喜闻乐见的罢 首先考虑对于固定的 \(m\) 张牌怎样求出最优的打牌策略,假设我们抽到了 \(p\) 张强化牌,攻击力 ...

  6. PDO的好处

    产生原因 普通的SQL执行语句,由于研发人员对前端请求参数过滤不严谨,导致SQL被注入,从而影响数据库,带来风险 使用PDO后形成的语句 SELECT * FROM test WHERE id in ...

  7. 33、搜索旋转排序数组 | 算法(leetode,附思维导图 + 全部解法)300题

    零 标题:算法(leetode,附思维导图 + 全部解法)300题之(33)搜索旋转排序数组 一 题目描述! 题目描述 二 解法总览(思维导图) 三 全部解法 1 方案1 1)代码: // 方案1 & ...

  8. Echart显示后端mysql数据

    一.基本思想 1.将数据存储在mysql数据库中 2.后端链接数据库,将数据库中的数据保存为json格式 3.将json格式数据使用ajax传到前端JSP页面中的Echarts 二.实现的关键点 1. ...

  9. Shell 指定行处理head、tail、sed

    目录 Shell 指定行处理 head.tail.sed head 前几行 tail sed 删除.替换.新增.选取 案例 删除行 插入行 查看某行 替换某行 部分数据的查找并替换 读写操作 Shel ...

  10. Swift-技巧(十一)重写运算符

    摘要 基础数据的运算可以直接使用四则运算符.在 Swift 中也可以通过重写四则运算符的方式,让 struct 或者 class 创建的结构体或者对象也能像基础数据那样直接使用四则运算符. Swift ...