示例代码
cpp
#include <stdio.h>
int Sum(int s, int e)
{
int result = 0;
for (int i = s; i <= e; i++)
{
result += i;
}
return result;
}
int main()
{
int start = 1;
int end = 100;
printf("I will begin\n");
int n = Sum(start, end);
printf("running done, result is: [%d-%d]=%d\n", start, end, n);
return 0;
}
使用watch命令监视变量
假设我们想要监视Sum
函数中result
变量的变化,以确保它正确地累加了从start
到end
的所有整数。
-
编译并启动GDB
gcc -g -o mycmd mycmd.c cgdb mycmd
-
查看main函数的代码并设置断点
(gdb) l main # 查看main函数的代码,确定在哪里设关卡 (gdb) b 20 # 在第20行设关卡,这里是程序调用Sum函数的地方
-
运行程序并进入Sum函数
(gdb) r # 让程序开始运行 (gdb) s # 进入Sum函数
-
设置监视点并继续执行
(gdb) n # 执行下一步,到达变量result声明的地方 (gdb) watch result # 在result变量上安装摄像头,监视它的值 (gdb) c # 继续运行程序,等待摄像头警报
-
观察变量变化 每当
result
的值发生变化时,GDB会暂停程序并通知你。你可以继续使用c
命令来查看result
的下一个变化。
(gdb) c # 再次继续,查看下一个变化
(gdb) c # 继续这个过程,观察result的变化
删除的时候就和删除断点一样。
注意:
如果你有⼀些变量不应该修改,但是你怀疑它修改导致了问题,你可以watch它,如果变化了,就会通知你。
使用set var命令确定问题原因
假设我们在Sum
函数中添加了一个全局变量flag
,并且我们怀疑flag
的值可能影响了Sum
函数的结果。
-
修改代码并重新编译
cppint flag = 0; // 故意设置一个可能影响结果的变量 int Sum(int s, int e) { int result = 0; for (int i = s; i <= e; i++) { result += i; } return result * flag; // 使用flag影响结果 }
-
重新编译并启动GDB
gcc -g -o sum_program sum_program.c gdb ./sum_program
-
设置断点并运行程序
(gdb) l main # 查看main函数的代码 (gdb) b 20 # 在第20行设关卡 (gdb) r # 让程序开始运行
-
进入Sum函数并快速执行到末尾
(gdb) s # 进入Sum函数 (gdb) until 14 # 快速执行到函数末尾,也就是return语句前 (gdb) p result # 查看result变量的值 (gdb) p flag # 查看flag变量的值
-
修改flag的值并继续执行
(gdb) set var flag=1 # 替换零件,把flag的值改为1 (gdb) p flag # 确认零件(flag的值)已经替换成功 (gdb) n # 继续执行下一步 (gdb) n # 再执行一步,看看机器(程序)的反应
我们能使用set var来进行变量值的临时的调整。
使用条件断点
假设我们想要在Sum
函数的循环中,只在i
等于30时暂停程序,以检查此时的result
值。
-
设置普通断点并运行程序
(gdb) l main # 查看main函数的代码 (gdb) b 20 # 在第20行设普通关卡 (gdb) r # 让程序开始运行
-
进入Sum函数并设置条件断点
(gdb) s # 进入Sum函数 (gdb) n # 执行下一步,到达循环开始的地方 (gdb) b 9 if i == 30 # 在第9行设条件断点,只在i等于30时暂停
-
查看断点信息并继续执行
(gdb) info b # 查看所有断点信息,确认条件断点已经设置 (gdb) finish # 让Sum函数执行完,看看结果 (gdb) finish # 再次使用finish,回到main函数
-
给已有断点追加条件 假设我们已经设置了一个普通断点,现在想要给它追加条件。
(gdb) b 9 # 先设一个普通关卡(普通断点) (gdb) info b # 查看所有断点信息,找到刚刚设的关卡编号 (gdb) condition 2 i==30 # 给编号为2的关卡追加条件,只在i等于30时暂停 (gdb) info b # 再次查看所有断点信息,确认条件已经追加成功 (gdb) c # 让程序继续运行,直到满足条件的关卡拦下来 (gdb) p i # 当程序因条件断点暂停时,查看变量i的值 (gdb) p result # 查看此时result变量的值
注意事项
- 使用watch命令 :如果你有一些变量不应该被修改,但怀疑它们被修改导致了问题,可以使用
watch
命令在这些变量上安装"摄像头"。一旦这些变量的值发生变化,GDB会暂停程序并通知你。 - 条件断点 :条件断点有两种常见添加方式:
- 新增条件断点 :在设置断点时直接添加条件,例如
b 9 if i == 30
。 - 给已有断点追加条件 :先设置一个普通断点,然后使用
condition
命令给它追加条件,例如condition 2 i==30
。注意,这里的2
是断点的编号,可以通过info b
命令查看。
- 新增条件断点 :在设置断点时直接添加条件,例如
通过这些步骤,你可以更有效地使用GDB来调试程序,找到并修复隐藏在代码中的问题。希望这些解释和示例能帮助你更好地理解和使用GDB。