最直接设断点的方式是用break命令,它支持函数名、行号、文件加行号及条件断点等多种定位方式;若不生效,多因未编译调试信息(-g)或代码被优化;tbreak用于一次性断点,run可传参或Ctrl+C中断运行中程序。

用 break 设置断点是最直接的方式
程序不会自己停在你想看的地方,必须显式告诉 GDB 停在哪。最常用、最可靠的就是 break 命令,它支持多种定位方式,本质是让程序执行到某处前暂停。
常见错误是输错行号或函数名后直接 r 运行,结果程序跑飞了——因为断点没设成功,GDB 也不会报错提醒你。
-
break main:停在main函数入口,适合刚启动就想观察初始化逻辑 -
break 23:停在当前文件第 23 行;注意:这个“当前文件”是上次用list或file指定的,不是源码原始路径里的行号 -
break utils.c:45:明确指定文件和行号,跨文件调试时必须这么写 -
break process_data if count > 10:条件断点,只在满足条件时中断,避免频繁手动c
为什么 break 有时不生效
断点设了但程序没停,大概率是编译时没带调试信息,或者代码被优化掉了。
GDB 只能停在有调试符号(-g)且未被编译器内联/删除的代码位置。比如你对一个 inline 函数设断点,GCC 在 -O2 下可能直接展开它,导致断点“消失”。
- 确认编译命令含
-g,例如:gcc -g -O0 -o test test.c - 避免用
-O2或更高优化等级调试;-O0最稳妥 - 用
info breakpoints查看断点状态,如果显示pending,说明 GDB 还没找到对应位置,可能是函数名拼错,或该函数尚未加载(如延迟加载的 shared library)
临时中断不用保存断点:用 tbreak
有时候你只想看一次某行的行为,比如循环体第一轮,之后就不再关心。反复 disable/enable 断点太麻烦,tbreak 更轻量。
-
tbreak 100:在第 100 行设一个“一次性断点”,命中后自动删除 -
tbreak my_func:同理,函数入口只停一次 - 它不写入断点列表(
info b不显示),也不影响其他断点,适合探索性调试
运行前没设断点?用 run 加参数也能控制起点
如果程序已经跑起来、或者你根本不确定该在哪设断点,run 命令本身就能干预初始行为。
-
run --debug-level=3:传参给程序,让它在更详细日志模式下启动,可能提前暴露问题位置 -
run后立刻按Ctrl+C:强制中断,此时程序停在任意位置,再用bt看调用栈,常用于卡死或无限循环场景 - 配合
catch syscall write这类事件断点,不依赖源码行号,而是拦截系统调用,适合追踪 I/O 或崩溃前最后一刻
print、display、x/4xw 配合验证。


















