2. 条件断点与观察点实战
任务目标
编写一个包含循环和变量修改的C程序,使用GDB条件断点(break if)在变量满足特定条件时暂停,并使用观察点(watch)监控变量变化,分析程序执行行为。
环境依赖
Linux系统,gcc与gdb已安装。无需额外库。
完整代码
// loop_demo.c
#include <stdio.h>
int main() {
int sum = 0;
int target = 42;
for (int i = 1; i <= 100; i++) {
sum += i;
if (i == 50) {
sum = 0; // 人为重置,制造观察点触发场景
}
}
printf("sum = %d\n", sum);
return 0;
}
编译与调试步骤
# 编译(-g 加入调试信息)
gcc -g -o loop_demo loop_demo.c
# 启动gdb
gdb ./loop_demo
GDB调试命令序列
# 在gdb内依次执行:
# 1. 在循环体内第8行(sum += i)设置条件断点:当 i == 50 时暂停
(gdb) break loop_demo.c:8 if i == 50
(gdb) run
# 此时应暂停,查看变量值:
(gdb) print i
(gdb) print sum
# 2. 继续执行到循环结束
(gdb) continue
# 3. 重新运行,设置观察点监控 sum 的变化
(gdb) break loop_demo.c:8 if i == 49 # 先停在 i=49,便于观察下一次变化
(gdb) run
(gdb) watch sum
(gdb) continue
# 观察点触发时,gdb会显示 sum 的旧值和新值
# 第一次触发:sum 从 1225 变为 0(i=50时被重置)
# 第二次触发:sum 从 0 变为 50(i=50的sum += i执行后)
# 4. 查看调用栈与当前行,确认位置
(gdb) bt
(gdb) list
验证方法与通过条件
- 条件断点验证:执行
break loop_demo.c:8 if i == 50后run,gdb应暂停在第8行,且print i输出50,print sum输出1225(即1到49的累加和)。若暂停时i值不是50,则条件断点未生效。 - 观察点验证:在i==49处暂停后设置
watch sum,执行continue。观察点应触发两次:第一次sum从1225变为0(i=50的if重置),第二次sum从0变为50(i=50的sum+=i执行)。若只触发一次或值变化不符,说明观察点监控逻辑有误。 - 程序行为分析:通过上述暂停点可确认:循环正常累加至i=49时sum=1225;i=50时先被重置为0,再累加50,因此最终sum值等于51到100的累加和(即3775)。
printf输出应为sum = 3775。
预期输出(确定性结果)
程序最终输出:sum = 3775
该结果由代码逻辑直接推出:i=50时sum被重置为0,之后从50累加到100,总和为(50+100)*51/2=3825,但i=50时先执行sum+=i(此时sum=0+50=50),随后i=51到100累加,最终sum=50+(51+100)*50/2=50+3775=3825?——更正:i=50时sum先被重置为0,然后执行sum+=i得到50;i=51到100累加和为(51+100)*50/2=3775,因此最终sum=50+3775=3825。但注意if(i==50)在sum+=i之后执行,因此i=50时sum先加50再被重置为0,随后i=51到100累加3775,最终sum=3775。以上推导以代码实际执行顺序为准。
常见问题:若条件断点不触发,检查是否在循环体内行号正确(可用
list 确认);观察点只监控写操作,若变量未被修改则不会触发。GDB中观察点对局部变量在退出作用域后会自动删除,因此需在循环内暂停时设置。