前言
介绍:
GDB
是GNU开源组织发布的一个强大的UNIX下的程序调试工具,GDB主要可帮助工程师完成下面4个方面的功能:
- 启动程序,可以按照工程师自定义的要求随心所欲的运行程序。
让被调试的程序在工程师指定的断点处停住,断点可以是条件表达式。 - 当程序被停住时,可以检查此时程序中所发生的事,并追索上文。
- 动态地改变程序的执行环境。
在学习linux系统下简单实用的调试工具gdb之前,我们先引入两个概念便于之后的理解:
Debug版本和Ralease版本
这里针对的文件类型是:源文件生成的目标文件,可执行文件
Debug版本:可调试版本,用于开发人员单步调试
(体积相较于Realease较大,因为还包含一些调试信息)
——————————————主要是开发者
使用
Release版本:发行版本,不可单步执行
——————————————主要是用户
使用
注意:linux下gcc默认生成的是Release版本,要想生成Debug版本,需要加入选项-g
-g选项适用的阶段:
我们都知道一个可执行文件的生成经历了预处理,编译,汇编(编译过程)和链接过程。
如果分步完成编译和链接的这些过程,-g就必须添加到编译阶段、
注意观察Debug版本的可执行文件大小和Release版本的文件大小是有区别的。
————————————————————————————————————————————
接下来正式进入gdb调试工具的学习:
命令
gdb Debug版本的可执行文件(注意这里不是.c文件)
因此根据上面我们对于-g选项的认识,我们应该这样使用gdb:
gdb -o 源文件.c 要生成的可执行文件 -g
下面让我们看看这个命令后跟不同类型的命令会有什么提示?
查看源码
l :默认显示main函数所在文件的源码
list filename:line : 显示执行文件filename的源码
断点管理
1.添加断点
b 行号 :将断点添加到最近一次显示的文件指定行
b filename:行号 :将断点添加到filename的指定行
b funactionname :将断点添加到funactionname的第一行
2.查看断点信息
info b :主要查看断点的号码和位置
3.删除断点
d 断点号 : 删除指定的断点
4.设置条件断点
- 有时候,我们需要断点在循环的某个条件处时,比如以下代码:
#include <stdio.h>
int main(int argc,char *argv[])
{
int i=0;
for ( ; i<100;i++)
{
int m;
m = i;
}
return 0;
}
-
开始编译
#gcc -g main.c将生成a.out
-
开始断点
#gdb a.out
-
通过以上命令可以看到代码 m = i 处为标记为"11",那么,如何当i=50的时候,断点到 m = i处呢?
(gdb) b 11 if i==50
(gdb) r
Starting program: /home/bluesky/a.out
Breakpoint 1, main (argc=1, argv=0xbffff3b4) at main.c:11
11 m = i;
(gdb) p i
$1 = 50
拓展:vs中添加条件断点的方法如下:
vs2013设置条件断点
5.将断点设置为无效,禁止使用某个断点
(gdb) disable breakpoint 1
1
1
1
该命令将禁止断点 1,同时断点信息的 (Enb)域将变为 n
6.恢复断点,允许使用某个断点
(gdb) enable breakpoint 1
执行流程控制
1.启动调试开始执行 : r
2.单步执行
n
逐过程 调用函数的语句中:n直接执行完整个函数后继续s
逐语句 往下执行,s进入函数一句一句执行- finish 直接将当前函数执行完成,退出到调用函数的下一条指令位置
3.继续执行,直到下一个断点:c
4.直接运行循环,直到循环结束(循环中使用):u
5.退出调试:q
查看变量的值
p
:执行一次p,显示一次,若不执行,则不会显示
p valname
p &valname
p arrname :显示数组中的所有元素的值
p &arrname :显示的是指针的值
*parr@len : 显示所有元素的值
ptype
display : 每执行一次n或s,则显示一次
x : 根据内存地址查看内存的存储值
bt : 显示函数调用堆栈0
总的来说,GDB的常用命令如下:
参考文献:GDB(六)断点