设置断点与单步执行 —— 一行一行揪出 bug
设置断点
在代码编辑器里,每一行左边有一个行号 gutter。点击 gutter 上某一行,该行会出现一个红点——这就是断点。
断点的含义:程序运行到这一行还没执行的时候,会自动停下来等待调试。
int main() {
int x = 10; ← 设断点在这里
int y = x * 2;
return y;
}
调试运行时,程序停在 int x = 10; 这行之前。此时变量 x 还没被赋值。点击 Continue(或 F5)会把这行执行完,然后停在下一行。
四种执行控制
| 操作 | 快捷键(如支持) | 含义 |
|---|---|---|
| Step Over(单步跳过) | F10 | 执行当前行,遇到函数调用不进入,直接执行完停在下一行 |
| Step Into(单步进入) | F11 | 执行当前行,遇到函数调用进入函数内部,停在函数第一行 |
| Step Out(单步跳出) | Shift+F11 | 如果当前在某个函数内部,继续执行直到函数返回,停在调用点下一行 |
| Continue(继续) | F5 | 从断点处直接跑到下一个断点,中间不停 |
什么时候用哪个
Step Over
最常用的操作。你在看主流程逻辑,一行一行往下走就行:
processData(input); ← 用 Step Over:不想管 processData 内部细节
validateResult(); ← 用 Step Over
saveToDB(); ← 用 Step Over
Step Into
你想看某个函数内部到底做了什么:
int result = compute(x, y); ← 用 Step Into:我要看看 compute 内部有没有 bug
Step Into 会把调试器带到 compute 函数内部,停在第一行。
Step Out
你不小心 Step Into 进了一个标准库函数或某个你不感兴趣的辅助函数:
sort(vec.begin(), vec.end()); ← 不小心 Step Into 进了 std::sort
... ← 在 sort 内部不想待了 → 用 Step Out
Step Out 会把 std::sort 完整执行完,停在调用它的下一行。
Continue
你已经定位到大概哪段代码有问题,在那里设了断点,直接 Continue 过去:
for (int i = 0; i < 1000; ++i) { ← 循环 1000 次不想每次都 Step
if (i == 500) { ← 在这设断点
// 只关心 i == 500 的情况
}
}
Continue 会把 i 从 0 一路跑到 500,在那个断点处停住。
条件断点(如果你的版本支持)
某些版本的 Cxxdroid gdb 可能支持条件断点——只有当某个条件满足时才触发断点:
for (auto &item : items) {
process(item); ← 条件断点:item.id == 42 时才停
}
如果你的版本不支持条件断点,用 Continue + 在循环体里设普通断点也能实现同样效果——只是需要手动多跑几次。
查看变量值
程序停在断点处时,调试面板会显示当前作用域内所有可见变量的值:
- 局部变量(函数内部定义的变量)
- 函数参数
- 全局变量
变量值会随着单步执行实时更新——你可以直接看到每个变量的变化过程。