display 比反复用 p 更省事,因为它在每次程序暂停时自动打印已设置的变量值,无需手动重复输入 p 命令,适合持续观察循环变量、递归参数等随执行节奏更新的量。

display 命令为什么比反复用 p 更省事
因为 display 是「每次程序暂停时自动打印」,不是一次性命令。你设好之后,只要 continue、next、step 导致停住(比如命中断点、单步结束、信号中断),GDB 就会立刻把所有 display 跟踪的变量值刷出来——不用你再敲一遍 p x。
它不像 watch 那样监听内存变化触发中断,也不依赖条件;它只管“停就显”,适合观察循环变量、递归参数、状态计数器这类随执行节奏稳定更新的量。
怎么加、改、删 display 项
加一个变量:display x,之后每次暂停都会显示类似 1: x = 42 的行(前面的 1: 是编号)
加多个变量:display a b *ptr@3,支持表达式,比如 *ptr@3 表示从 ptr 指向地址开始连续打印 3 个元素
查看当前所有 display 项:info display,会列出编号、表达式、是否启用、当前值
禁用某一项(不删,只是暂时不显示):disable display 2
删除某一项:undisplay 2 或 delete display 2
清空全部:delete display
常见坑:变量突然不显示了,或者显示 <optimized out></optimized>
最常踩的坑是编译没带 -g,或者开了 -O2 及以上优化。GDB 没调试信息,或变量被编译器优化掉,display 就只能报 <optimized out></optimized>。
确认编译命令用了 gcc -g -O0(或至少 -O1),且没加 -fomit-frame-pointer 这类激进选项
局部变量在函数返回后自然失效,display 仍会尝试求值,但可能报 No symbol "x" in current context —— 这不是 bug,是作用域结束了
结构体成员要写全路径,比如 display s.name,别只写 name,否则容易因作用域或重名找不到
和 watch / print 的关键区别在哪
watch 是「值一变就中断」,开销大,适合抓突变;display 是「一停就显」,轻量,适合看节奏性变化
print 是手动快照,适合查一次性的中间结果;display 是自动轮播,适合盯住几个关键变量跑完整个循环
三者能共存:display i 看循环索引,watch sum 抓异常累加,p buffer[0] 临时查某次内容 —— 但别堆太多 display 项,尤其带复杂表达式(如 display *(int*)p@1000),每次暂停都计算,会明显拖慢调试节奏











