直接用 break 加 if 条件可在循环中精准停住,如 break test.c:15 if i == 7;条件表达式需变量在作用域且未被优化(编译加 -g -o0);可用 condition 命令为已有断点添加或清除条件;汇编级需用寄存器名前加 $,如 $rax;优化可能导致变量不可见或值不准,应先确认调试信息完整。

直接用 break 加 if 条件就能在循环里精准停下,不需要改代码、也不依赖循环变量名是否可见。
break 行号 if 变量 == 值 是最常用写法
比如你在 test.c 第 15 行有个 for 循环体,想让程序只在 i == 7 那次迭代暂停:
(gdb) break test.c:15 if i == 7
这个断点会在每次执行到第 15 行时检查 i 的值,仅当为 7 才真正中断。其他次数直接跳过。
- 条件表达式必须是 GDB 能求值的——变量得在当前作用域,且没被编译器优化掉(所以务必加
-g -O0编译) - 行号要选循环体内实际执行的语句,不是
for (i = 0; ...)那行本身(那行只执行一次) - 如果循环体有多行,设在第一行最稳;设在最后一行可能导致错过某次迭代的判断时机
给已有断点补条件用 condition 命令
你已经用 break 15 设了普通断点,后来发现只想看第 3 次触发?不用删重设:
(gdb) info breakpoints<br>(gdb) condition 1 i == 3
这里 1 是断点编号,condition 会覆盖之前可能设过的条件(包括无条件)。
- 如果想取消条件,让断点变回无条件触发:
condition 1(不带表达式) - 注意
condition对watch或catch断点也有效 - 误设条件导致断点从不触发?先
info breakpoints看 Condition 列是否为空
汇编循环里怎么设条件断点
没有 C 变量名时,得靠寄存器或内存地址。比如 x86-64 下一个计数器存在 %rax,上限在 %rbx,你想在 %rax == %rbx 时停:
(gdb) break *0x40102a if $rax == $rbx
其中 0x40102a 是 cmp 或 jne 指令的地址,可用 disassemble 查到。
- 寄存器名前加
$,如$rax、$r12;内存地址用*0x...表示取值 - 不能写
rax == rbx(GDB 会报 unknown type) - 如果循环没符号信息,
info registers和x/4xw $rsp配合看栈上数据更可靠
条件断点真正的坑不在语法,而在于编译优化会让变量“消失”或值“不准”——哪怕你看到 info locals 里有 i,也可能在 if i == 5 时它根本没被加载到寄存器。遇到断点不触发,先 file 看是否带调试信息,再 show debug-line 确认行号映射是否正常。











