GDB 调试
GDB 是一个功能强大的调试器,也是 Linux 系统中默认的调试器。GDB 主要提供以下四种功能,这些功能可以方便我们定位程序的 BUG。
- 启动程序
- 设置断点
- 检查程序运行状态,例如查看变量的值
- 修改程序运行状态,例如修改变量的值
本文简单讲述 GDB 的调试方法。
我们需要调试的程序如下所示,该程序只是为了演示 GDB 的用法,并没有实际的意义。
1 |
|
我们先对上面的程序进行编译,编译命令为:
g++ -g -o hello hello.cpp
- -g 选项的含义是生成源代码的调试信息,方便我们在调试过程中查看源代码
- -o 选项可以指定生成的可执行程序名称
本文的重点不在于介绍 gcc 或者 g++ 编译器的使用,有关 gcc 和 g++ 的使用,请参考其使用手册。
编译好程序后,我们就可以使用 GDB 来调试程序了。
gdb hello
进入 GDB 的提示符界面,如果需要退出,可以使用 quit 命令即可。
(gdb) quit
一、设置断点
使用 break 命令可以设置程序的断点,例如,我们在程序的第 7 行设置一个断点。
(gdb) break 7
Breakpoint 1 at 0x400860: file hello.cpp, line 7.
如果当前需要调试的程序由多个源文件组成,则可以在设置断点时指定文件的名称,例如,下面的命令设置 hello.cpp 源文件中的第 8 行为断点。
(gdb) break hello.cpp:8
Breakpoint 2 at 0x40086b: file hello.cpp, line 8.
如果需要查看断点的信息,可以使用 info break 命令:
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000400860 in f1(int, double) at hello.cpp:7
2 breakpoint keep y 0x000000000040086b in f1(int, double) at hello.cpp:8
可以看到,程序设置了两个断点,分别是程序第 7 行和第 8 行。
如果需要删除断点,可以使用 clear 命令。
设置好断点后,就可以运行程序了,使用 run 命令运行程序。
(gdb) run
Starting program: /home/lihao/code/cpp/test/hello
begin to gdb test
Breakpoint 1, f1 (a=10, d=3.1400000000000001) at hello.cpp:7
7 int b = (a + 5) * 2;
可以看到程序运行到第 7 行即断点处,停了下来。
二、查看程序运行状态
如果需要查看执行的源代码,可以使用 list 或者 l (小写字母 L)命令:
(gdb) l
2
3 using namespace std;
4
5 double f1(int a, double d)
6 {
7 int b = (a + 5) * 2;
8 double ret = d * b;
9
10 return ret;
11 }
可以看到,GDB 把当前程序执行位置前面和后面的代码都展示了出来。如果需要继续查看下面的代码,可以继续按下回车键。
为了打印变量的值,可以使用 print 命令或者 p 命令:
1 | (gdb) p a |
如果变量为字符串类型,且值的长度很长,为了完整输出字符串的内容,可以使用以下命令设置打印变量时显示完整的字符串:
set print element 0
如果需要查看程序运行的堆栈,可以使用 bt 命令:
1 | (gdb) bt |
可以看到,hello 程序的调用链为 main -> f2 -> f1。
三、执行程序
为了便于演示,我们先将所有的断点删除,只保留第 7 行的断点。
如果需要在断点处继续执行程序,可以使用 step 命令或者 s 命令, step 命令的含义是逐语句执行。
(gdb) step
8 double ret = d * b;
程序继续执行到了第 8 行。
step 命令是逐语句执行,遇到子函数的情况,会进入子函数中逐语句继续执行。
next 命令也是逐语句执行,与 step 命令不同的是,遇到子函数,不会进入子函数中执行,只会把子函数当成一条语句执行。
(gdb) next
10 return ret;
程序执行过程中,如果需要让程序一直执行到下一个断点,可以使用 continue 命令或者 c 命令。
(gdb) c
Continuing.
103.62
Program exited normally.
本文只讲述 GDB 调试中涉及的最常用的几个命令,更详细和复杂的使用,可以参考 GDB 的说明文档。
附:如何解决 GDB 运行时,提示 Missing separate debuginfos 异常的问题。
解决步骤
- 修改 /etc/yum.repos.d/CentOS-Debuginfo.repo 文件,设置 enable=1
- 安装 glibc,yum install glibc
- 安装 yum-utils, yum install yum-utils
- debuginfo-install glibc-2.12-1.209.el6_9.2.x86_64 libgcc-4.4.7-18.el6.x86_64 libstdc++-4.4.7-18.el6.x86_64
参考资料
- http://www.gnu.org/software/gdb/
- Linux 程序设计,第四版,人民邮电出版社,Neil Matthew 等著