gdb中print默认十进制但受变量类型影响,p/d可强制有符号十进制显示,x/d用于内存地址的十进制查看,作用域同名变量需用::限定,/d不适用于浮点和指针。

gdb中print默认就是十进制,但要注意隐式类型影响
直接用 print(或简写 p)输出整型变量时,GDB 默认按十进制显示,前提是变量本身是带符号整型(如 int)。但如果你看到的是十六进制或异常值,大概率是类型推断出错,或者变量被优化掉了。
- 确认变量未被编译器优化:调试前务必用
gcc -g -O0编译,-O2或更高会删掉局部变量、内联函数,导致p var报错No symbol "var" in current context - 若变量声明为
unsigned int,p var仍可能显示为十进制,但实际语义是无符号;想强制按有符号十进制解释,可用p/d var -
p/d是显式指定“十进制有符号”格式的可靠写法,不受变量原始声明类型干扰
x/d 适合查看内存地址里的十进制值
当你要看某块内存(比如数组、结构体字段、栈上原始字节)的十进制内容时,print 不适用,得用 examine(简写 x)命令:
-
x/d &var:查看变量var地址处的一个有符号十进制整数(默认按int大小,通常是 4 字节) -
x/5d &arr[0]:从arr[0]地址开始,连续显示 5 个有符号十进制整数 -
x/8d $rsp:查看栈顶起始地址往后 8 个int的十进制值(注意栈向下增长,$rsp指向最新压入项) - 注意:
x/d不解析变量名,只读内存;所以必须提供有效地址,比如&var或寄存器值
局部变量和全局变量同名时,p/d 可能不生效
如果当前作用域里有局部变量 count,同时文件级也有同名全局变量,p/d count 默认取局部变量——哪怕你本意想看全局的。这时 /d 格式修饰符不起作用,关键在作用域限定:
- 用
p/d ::count强制访问当前编译单元的全局count(双冒号前不加文件名) - 若全局变量定义在
utils.c中,写成p/d 'utils.c'::count - 函数内静态变量也属文件作用域,同样适用
::语法,例如p/d func_name::static_var - 别依赖
set print pretty off等设置来“修复”,它只影响结构体缩进,不解决作用域遮蔽
浮点数和指针用 p/d 会出问题
p/d 仅对整数语义安全。对其他类型强行加 /d,GDB 会按整数重新解释比特位,结果不可预测:
-
float f = 3.14;→p/d f输出一个毫无意义的大整数(比如1078523331),这是把 IEEE 754 二进制表示当成了有符号整数 -
int *p = &x;→p/d p显示指针地址的十进制数值(如140737488348944),但通常你更需要p/x p看十六进制地址,或p *p看所指内容 - 要查浮点值,就用
p/f f;要看指针指向的整数内容,用p/d *p,而不是p/d p
/d 修饰符不改变数据读取方式,只改变显示解释方式。同一块内存,x/d 和 p/d 底层行为不同——前者按地址读原始字节再转十进制,后者先求变量值再格式化。混用会导致你以为“看了同一个东西”,其实根本不是。











