前言
调试, 是编写程序过程中确保程序正确性的重要环节, 现在使用的IDE大多都集成了调试器, 但linux最著名的调试器是命令行形式的C/C++调试器GDB。以下将介绍GDB的基本使用方法。
安装GDB
大多数的发行版Linux系统中都有GDB
Debian 或 Ubuntu
$ sudo apt-get install gdb
Arch Linux
$ sudo pacman -S gdb
Fedora, CentOS 或 RHEL
$ sudo yum install gdb
也可以从官网中下载。
示例代码
学习任何一项技能, 动手试验才是关键。以下是本文演示GDB的代码, 多文件调试, 它可以很好的体现GDB的特性。将它拷贝下来并且进行实验——这是最好的方法。
**a.c**
1 |
|
**b.h**
1 |
|
**b.c**
1 |
|
**c.h**
1 |
|
**c.c**
1 |
|
GDB的使用
编译Debug程序
首先最重要的, 你需要使用编译器的"-g"
选项来编译程序, 这样可执行程序才能通过GDB来运行。
1 | gcc a.c b.c c.c -g -o mydebug |
开始调试
1 | gdb -tui [可执行程序名] |
使用'-tui'
选项可以将代码显示在一个漂亮的交互式窗口内(所以被称为文本用户界面TUI), 在这个窗口内可以滚动鼠标滑轮, 同时在下面的GDB shell中输入命令。
查看代码 list
我们可以使用list
命令来显示代码, 使用方法有
1 | list [file:]start[,end] |
1. 查看c.c的第1行
1 | list c.c:1 |
or 简写
1 | l c.c:1 |
2. 查看b.c的3到8行
1 | list b.c:3,8 |
or 简写
1 | l b.c:3,8 |
3. 查看c.c的mytool2_print函数
1 | list c.c:mytool2_print |
or 简写
1 | l c.c:mytool2_print |
运行程序 run
gdb 输入run即可运行程序
1 | run |
设置断点 break
1 | break [file:]行号 |
1. 在a.c第10行设置断点
1 | list a.c:1 |
or
1 | break a.c:10 |
从图可见, 文本用户界面TUI下, 设置断点会标志在文本的左侧
2. 在a.c main函数开始处设置断点
1 | list a.c:1 |
or
1 | break a.c:main |
3. 在a.c的第10行设置条件断点
条件断点的意思是, 当条件满足时, 断点会被执行; 条件不满足, 断点不会被执行
1 | break a.c:10 if i == 150 |
设置了当i等于150时, 执行断点, 方便在调试循环的时候, 想调试第几次循环的结果
设置观察点 watch
设置一个'观察断点', 当这个被观察的变量发生变化时, 程序会被停止。
1 | watch 变量 (发生变化时暂停运行) |
1. 给a.c中的sum变量设置观察点
1 | list a.c:1 |
观察点要在程序运行的时候才能设置
继续运行continue
遇到断点时, 要继续向下运行到下一个断点或者运行到结束程序, 使用continue命令
跳出循环until
在执行完循环体内的最后一条语句之后执行 until, 就会执行完循环体到后面的一个语句停下。
PS: 就是循环体要执行一遍, 回到循环判断条件, 再执行until命令就会跳出循环
查看变量值 print
print用来查看变量的值
1 | print 变量 |
ptype用来查看变量的类型
1 | ptype 变量 |
修改变量的值 set
这样会覆盖变量的值。不过需要注意, 你不能创建一个新的变量或改变变量的类型。
1 | set var [变量] = [新的值] |
单步调试
step 运行到下一条语句, 有可能进入到一个函数里面
1 | step |
next 直接运行下一条语句, 而不进入子函数内部
1 | next |
删除断点
1 | delete 断点号 |
退出程序 quit
1 | quit |
查看gdb内部命令 help
1 | help 命令名 |
complete 列出命令
列出所有以字符串str开头的命令
1 | complete str |
其他命令
1 | info breakpoints (显示断点信息) |