前言
windows 的界面操作非常丰富,对程序开发也是如此,各种强大的 IDE 真是非常方便。转入 linux 编程后,没有界面,用 vim gcc 搞程序开发,一开始还真是不适应。现在用的多了,反而习惯用 linux 开发了。但是,没法调试程序真是太痛苦了,只能逐行加 printf。。。
其实早就听说 linux 程序开发有 gdb 工具可以用于调试,一直没有去了解。今天加 printf 实在是加到崩溃,肯定要了解一下的。了解后,才发现,gdb 并不复杂,很容易用的工具。好用的工具肯定都是容易使用的。
gdb 是什么,可以做什么?
gdb 就是一个调试工具,一般来说,GDB主要帮助你完成下面四个方面的功能:
- 启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
- 可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
- 当程序被停住时,可以检查此时你的程序中所发生的事。
- 你可以改变你的程序,将一个BUG产生的影响修正从而测试其他BUG。
gdb 调试实战项目,牛刀小试
c 语言小 demo
咱们先用 c 语言随便写一个小 demo 作为测试对象:
// 文件名 test.c
#include <stdio.h>
int GetSum(char num1, char num2)
{
int res = 0;
res = num1 + num2;
return res;
}
int main()
{
char i = 10, j = 10;
int sum = 0;
i ++;
j ++;
sum = GetSum(i, j);
printf("i + j = %d\n", sum);
return 0;
}
很简单的程序,如果打算使用 gdb 调试它,记得编译的时候加上 -g
选项。
gcc -g -Wall -o test test.c
得到可执行程序后,就可以使用 gdb 调试了。
gdb 调试命令
gdb 全速运行
(gdb)run,也可只输入 r
,程序会开始运行,停在第一个断点处。
(gdb)continue,也可只输入 c
,程序继续运行,停在下一个断点处。
gdb 添加搜索代码源文件路径
(gdb)directory [path],也可输入 dir [path]
,将 path 添加到搜索目录中。
gdb 打印代码
gdb + 可执行程序即可进入 gdb 调试:
输入 l
可以打印出代码,如果想输出指定行号的代码,可以加上数字,例如 l 5
。
gdb 断点
下断点有两种方式:
- (gdb)break(也可只输入b) + 函数名
- (gdb)break + 行号
- (gdb)break + 条件。这个命令必须在变量i被定义之后才会成功运行,为了解决这个问题,首先在变量 i 被定义的后一行设置中断,然后使用run命令运行程序,程序暂停后就可以使用watch i==99设置断点了。例如
- break 7 if i==99
- watch i==99
查看断点
- 显示当前gdb的断点信息:
(gdb) info break - 删除指定的某个断点:
(gdb) delete breakpoint 1 - 该命令将会删除编号为1的断点,如果不带编号参数,将删除所有的断点
(gdb) delete breakpoint - 禁止使用某个断点
(gdb) disable breakpoint 1
该命令将禁止断点1,同时断点信息的 (Enb)域将变为 n - 允许使用某个断点
(gdb) enable breakpoint 1
该命令将允许断点1,同时断点信息的 (Enb)域将变为 y - 清除源文件中某一代码行上的所有断点
(gdb)clear number
注:number 为源文件的某个代码行的行号
变量检查赋值编辑
- whatis:识别数组或变量的类型
- ptype:比whatis的功能更强,他可以提供一个结构的定义
- set variable = value:将值赋予变量
- print variable = value or p variable = value : 除了显示一个变量的值外,还可以用来赋值
单步执行编辑
- next 不进入的单步执行
- step 进入的单步执行如果已经进入了某函数,而想退出该函数返回到它的调用函数中,可使用命令finish
函数调用编辑
- call name 调用和执行一个函数
(gdb) call gen_and_sork(1234,1,0)
(gdb) call printf(“abcd”)
=4 - finish 结束执行当前函数,显示其返回值(如果有的话)
gdb 调试linux程序实战
咱们以上面的小 demo 为例。
首先看看代码,然后再 main 处和第 15 行下断点
输入 r(run) 运行,可以看出,运行停在 main 函数入口处了:
输入 n(next) 跳过,期间可以输入 l 查看代码:
来到 GetSum 函数出,输入 s(step into),进入 GetSum 函数:
输入 p(print) + 变量,可以查看变量值。
至此,基本的调试流程已经走完了,输入 run 全速运行,程序运行结束,咱们选择从头开始:
这次取消全部断点,全速运行:
可以看出,直接就运行到程序最后了。
[…] 今天用 C 语言编程时,发现一个非常奇怪的现象:逻辑一切正常,输出却不对。采用 GDB 调试(可参考:gdb工具的使用),定位到错误,居然是乘法运算出了问题。两个数字相乘,结果却是不正确的,始终是错误的。 […]
[…] 今天用 C 语言编程时,发现一个非常奇怪的现象:逻辑一切正常,输出却不对。采用 GDB 调试(可参考:gdb工具的使用),定位到错误,居然是乘法运算出了问题。两个数字相乘,结果却是不正确的,始终是错误的。 […]