GDB调试器的用法

1 功能
一般来说,GDB主要帮忙你完成下面四个方面的功能:
  • 启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
  • 可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
  • 当程序被停住时,可以检查此时你的程序中所发生的事。
  • 动态的改变你程序的执行环境。

2 用法
2.1 启动GDB
先给出一个示例用的小程序,C语言代码,命名为 test.c:
#include <stdio.h>

long func(int n)
{
	int i;
	long sum=0;
	for(i=0; i<n; i++)
	{
		sum+=i;
	}
	return sum;
}

void main()
{
	int i;
	long result = 0;
	for(i=1; i<=100; i++)
	{
		result += i;
	}

	printf("result[1-100] = %ld \n", result );
	printf("result[1-250] = %ld \n", func(250) );
}
输入命令:
gcc -g test.c -o test
编译上述test.c程序,得到包含调试信息的二进制文件test

执行:
gdb test
命令进行调试状态,如下所示:

ethan@ethan-Q57H:~/ubuntuDev/test$ gdb test
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 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 "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test...done.
(gdb)

启动GDB后,首先显示了一段 版权说明(上述蓝色字体部分),然后是gdb的提示符:(gdb) 。可以在(gdb) 之后输入调试命令。

注意:
如果要使用gdb启动时 不输出版权说明,可以在执行时加上 -q选项,如: gdb -q test。也可以在Linux提示符下,直接输入gdb,然后使用file命令转入调试的程序。如:
ethan@ethan-Q57H:~/ubuntuDev/test$ gdb -q
(gdb) file test
Reading symbols from test...done.
(gdb)

2.2 退出GDB
如果要结束调试,使用 quit命令(或者 q)退出gdb,返回到Linux的提示符。
(gdb) q
ethan@ethan-Q57H:~/ubuntuDev/test$

2.3 显示和查找程序源代码
2.3.1 显示程序的源代码
list命令用于列出程序的源代码
  • list:显示当前行后面10行代码,若再次运行该命令则显示接下来的10行代码。
  • list -:显示当前行前面10行代码。
  • list 5,10:显示第5行到第10行的代码。
  • list test.c:5,10:显示源文件test.c的第5行到第10行的代码。在调试含有多个源文 件的程序时使用。
  • list 5:显示第5行周围的代码。
  • list get_sum:显示get_sum函数周围的代码。
  • list test.c:get_sum:显示源文件test.c中get_sum函数周围的代码。在调试含有多个源文件的程序时使用。

注意:
如果在调试过程中运行Linux命令,则可以在gdb的提示符下输入shell命令。如:
(gdb) shell ls
chardev.c t1.c t2.c test test.c T.h

2.3.2 查找程序源代码
search和forward两个命令都用来从当前行向后查找第一个匹配的字符串。
search 字符串
forward 字符串

reverse-search用来从当前行向前查找第一个匹配的字符串。
reverse-search 字符串

2.4 运行程序和获得帮助
在GDB中,运行程序使用run命令。
如果想要详细了解gdb某个命令的使用方法,可以使用help命令。如:
help list
help all

2.5 设置和管理断点
2.5.1 设置断点
在gdb中用break命令来设置断点,设置断点的方法包括:
  • break <function>
在进入指定函数时停住,C++中可以使用class::function或function(type, type)格式来指定函数名。
  • break <linenum>
在指定行号停住。
  • break +offset / break -offset
在当前行号的前面或后面的offset行停住,offiset为自然数。
  • break filename:linenum
在源文件filename的linenum行处停住。
  • break filename:function
在源文件filename的function函数的入口处停住。
  • break *address
在程序运行的内存地址处停住。
  • break
break命令没有参数时,表示在下一条指令处停住。
  • break 行号或函数名 if <condition>
condition表示条件,在条件成立时停住。比如在循环体中,可以设置break if i=100,表示当i为100时停住程序。

2.5.2 查看当前设置的中断点
查看断点时,可使用info命令,如
info breakpoints [n]、
info break [n]
n表示断点号

注意:
在断点处,可以按下  Ctrl+X,A 键查看断点周围代码,如下所示:
(gdb)   b 5
Breakpoint 1 at 0x40052d: file test.c, line 5.
(gdb)  r
Starting program: /home/ethan/ubuntuDev/test/test
result[1-100] = 5050

Breakpoint 1, func (n=250) at test.c:6
6 long sum=0;
(gdb)

此时按下  Ctrl+X,A,出现如下效果:

2.5.3 使中断失效或有效
  • 使某个断点失效
disable 断点编号
  • 使某个断点恢复有效
enable 断点编号

2.5.4 删除断点
  • clear:删除程序中所有的断点。
  • clear 行号:删除次行的断点。
  • clear 函数名:删除该函数的断点。
  • delete 断点编号:删除指定编号的断点。如果一次要删除多个断点,各个断点编号以空格隔开。

2.6 查看和设置变量的值
2.6.1 print命令
print(缩写p)命令一般用来打印变量或表达式的值,也可以用来打印内存中从某个变量开始的一段内存区域的内容,还可以用来对某个变量进行赋值。其使用格式为:
print 变量或表达式:打印变量或表达式当前的值
print 变量=值 :对变量进行赋值
print表达式@要打印的值的个数n :打印以表达式值开始的n个数

2.6.2 whatis命令
whatis命令用来显示某个变量或表达式值的数据类型。
whatis 变量或表达式

2.6.3 set命令
set命令可以用来给变量赋值
set variable 变量=值

注意:
这里 print i=20 与set variable i=20效果等同。

2.7 控制程序的执行
2.7.1 continue命令
让程序继续运行,直到下一个断点或运行完为止。该命令的格式是:
continue [ignore-count]
c [ignore-count]
ignore-count表示忽略其后多少次断点。

2.7.2 kill命令
该命令用于结束当前程序的调试,在gdb提示符下输入kill。如果当前程序正在调试,gdb会询问是否退出,输入y结束调试,输入n继续调试程序。

2.7.3 单步调试命令
在调试过程中,next命令用于单步执行,不会进入函数的内部。
step(缩写s)命令则在单步执行一个函数时,会进入其内部。

单步执行的更复杂用法包括:
  • step <count>
单步跟踪,如果有函数调用,则进入该函数(进入函数的前提是,此函数被编译有debug信息)。step后面不加count表示一条条地执行,加表示执行后面的count条指令,然后再停住。
  • next <count>
单步跟踪,如果有函数调用,它不会进入该函数。同样地,next后面不加count表示一条条地执行,加表示执行后面的count条指令,然后再停住。
  • set step-mode
set step-mode on用于打开step-mode模式,这样,在进行单步跟踪时,程序不会因为没有debug信息而不停住,这个参数的设置可便于查看机器码。set step-mod off用于关闭step-mode模式。
  • finish
运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息。
  • until (缩写u)
一直在循环体内执行单步,退不出来是一件令人烦恼的事情,until命令可以运行程序直到退出循环体。
  • stepi(缩写si)和nexti(缩写ni)
stepi和nexti用于单步跟踪一条机器指令,一条程序代码有可能由数条机器指令完成,stepi和nexti可以单步执行机器指令。 另外,运行“display/i $pc”命令后,单步跟踪会在打出程序代码的同时打出机器指令,即汇编代码。

附录:GDB调试常用命令一览表

 命令
 解释
 示例
file <文件名>
加载被调试的可执行程序文件。
因为一般都在被调试程序所在目录下执行GDB,因而文本名不需要带路径。
(gdb) file gdb-sample
r
Run的简写,运行被调试的程序。
如果此前没有下过断点,则执行完整个程序;如果有断点,则程序暂停在第一个可用断点处。
(gdb) r
c
Continue的简写,继续执行被调试程序,直至下一个断点或程序结束。
(gdb) c
b <行号>
b <函数名称>
b *<函数名称>
b *<代码地址>
d [编号]
b: Breakpoint的简写,设置断点。两可以使用“行号”“函数名称”“执行地址”等方式指定断点位置。
其中在函数名称前面加“*”符号表示将断点设置在“由编译器生成的prolog代码处”。如果不了解汇编,可以不予理会此用法。
d: Delete breakpoint的简写,删除指定编号的某个断点,或删除所有断点。断点编号从1开始递增。
(gdb) b 8
(gdb) b main
(gdb) b *main
(gdb) b *0x804835c
(gdb) d
s, n
s: 执行一行源程序代码,如果此行代码中有函数调用,则进入该函数;
n: 执行一行源程序代码,此行代码中的函数调用也一并执行。
s 相当于其它调试器中的“Step Into (单步跟踪进入)”;
n 相当于其它调试器中的“Step Over (单步跟踪)”。
这两个命令必须在有源代码调试信息的情况下才可以使用(GCC编译时使用“-g”参数)。
(gdb) s
(gdb) n
si, ni
si命令类似于s命令,ni命令类似于n命令。所不同的是,这两个命令(si/ni)所针对的是汇编指令,而s/n针对的是源代码。
(gdb) si
(gdb) ni
p <变量名称>
Print的简写,显示指定变量(临时变量或全局变量)的值。
(gdb) p i
(gdb) p nGlobalVar
display ...
undisplay <编号>
display,设置程序中断后欲显示的数据及其格式。
例如,如果希望每次程序中断后可以看到即将被执行的下一条汇编指令,可以使用命令
“display /i $pc”
其中 $pc 代表当前汇编指令,/i 表示以十六进行显示。当需要关心汇编代码时,此命令相当有用。
undispaly,取消先前的display设置,编号从1开始递增。
(gdb) display /i $pc
(gdb) undisplay 1
i
Info的简写,用于显示各类信息,详情请查阅“help i”。
(gdb) i r
q
Quit的简写,退出GDB调试环境。
(gdb) q
help [命令名称]
GDB帮助命令,提供对GDB名种命令的解释说明。
如果指定了“命令名称”参数,则显示该命令的详细说明;如果没有指定参数,则分类显示所有GDB命令,供用户进一步浏览和查询。
(gdb) help display
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值