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 5Breakpoint 1 at 0x40052d: file test.c, line 5.(gdb) rStarting program: /home/ethan/ubuntuDev/test/testresult[1-100] = 5050
Breakpoint 1, func (n=250) at test.c:66 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调试常用命令一览表