print 命令是 GDB 中的表达式求值器,支持算术、指针、结构体、函数调用等合法表达式计算,但不支持宏;默认取局部变量,可用 :: 或 'file.c':: 访问全局;格式修饰符(如 /x、/f)控制输出形式;失败主因是缺失调试信息、优化移除变量或作用域不可见。

用 print 命令直接计算表达式
在 GDB 中,print(简写为 p)不是只用来“打印变量”,它本质是求值器:只要表达式语法合法、当前上下文能解析符号,GDB 就会执行计算并输出结果。
比如你停在函数里,有局部变量 a = 5、b = 3,想看 a * b + 1 的值,直接输:p a * b + 1 → 输出 $1 = 16
- 支持算术运算、指针偏移(
p ptr+2)、结构体成员访问(p obj.field)、函数调用(p strlen("hello"),前提是函数已加载且未被优化掉) - 不支持宏(
#define MAX(a,b) ((a)>(b)?(a):(b))无法在print中使用) - 若表达式含重名变量(如局部
x和全局x),默认取局部;要强制取全局,用p 'file.c'::x或p ::x
print 的格式控制影响输出可读性
默认输出是十进制整数或原始类型表示,但加格式修饰符后能看清底层内容。格式写在斜杠后,例如 p/x 表示十六进制。
-
p/d x:按有符号十进制显示(d是默认,可省略) -
p/u x:无符号十进制,对高位为 1 的 int 很有用(避免误判为负数) -
p/x &var:显示变量地址的十六进制形式 -
p/t *(int*)0x7fffffffe000:把某内存地址当 int 解释并二进制显示(t表示 binary) - 浮点数要用
p/f,否则可能显示为整数位模式(如p/x f显示 IEEE754 位模式,p/f f才显示 3.14)
常见错误:表达式求值失败的几个原因
输入 p expr 后报错 No symbol "xxx" in current context 或 Cannot evaluate function -- undefined symbol,多数不是命令写错,而是环境限制:
- 编译没加
-g:符号表缺失,GDB 不认识变量名和函数名 - 变量被编译器优化掉了(如
gcc -O2):即使有-g,局部变量也可能不存在于栈帧中,info locals都看不到 - 函数内联或删除:
p some_inlined_func()会失败,因为目标代码已合并,符号消失 - 跨作用域访问:在
main里p inner_var(该变量定义在某个 if 块内且当前不在其中)→ 不可见 - C++ 模板实例未显式实例化时,某些模板函数名可能无法解析
比 print 更轻量的替代:用 output 避免自动换行和编号
当你只想看纯结果、不想带 $1 = 前缀或换行,用 output(简写 o):
-
o/x &buf→ 直接输出类似0x7fffffffe010,不换行 -
o/d len→ 输出数字如1024,后面还能接其他命令输出 - 注意:
output不保存历史值(不会生成$2这类序号),也不能用于赋值(o x=5报错) - 适合写调试脚本或快速拼接多个值查看,比如
o/x &arr[0]@4查数组首地址及后续 4 个元素
真正容易被忽略的是上下文依赖——print 能否工作,90% 取决于你停在哪一帧、编译选项是否保留符号、以及变量是否还“活”着。别急着怀疑命令,先 info frame 看栈帧,info locals 确认变量存在,再动手求值。











