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中观察点对局部变量在退出作用域后会自动删除,因此需在循环内暂停时设置。