GDB的x命令默认按4字节(w)读取而非字节(b),因u参数缺省值为w,故x/10x实际读取40字节并每4字节解析为一整数;要精确按字节查看必须显式指定x/Nxb。

直接用 x/16xb 这类命令就能按字节查看,但必须明确指定单位 b,否则 GDB 默认按 4 字节(w)读取,结果完全不对。
为什么 x 默认不按字节显示
GDB 的 x 命令中,u(unit)参数决定每次读取多少字节,不写就默认是 w(word = 4 字节)。哪怕你只写 x/10x,它也会读 10 个 4 字节单元(共 40 字节),并把每 4 字节当一个整数解析——这不是“按字节”,而是“按字”。
- 想真正按单字节看,
b必须显式写出,例如x/16xb -
x/16x和x/16xb输出外观可能相似,但底层读取方式、地址步进、数值解释完全不同 - 在小端机上,
x/4xw 0x7fffffffe000会把0x01 02 03 04显示为0x04030201;而x/4xb 0x7fffffffe000就老老实实显示0x01 0x02 0x03 0x04
x/Nxb 的典型使用场景
按字节查看适用于需要精确观察内存布局的场合,比如:
- 调试字符串越界或填充字节(
x/32xb &buf看缓冲区原始字节) - 检查结构体字段对齐和 padding(
x/24xb &my_struct对照ptype my_struct验证偏移) - 分析网络包或二进制协议头(
x/12xb pkt_buf逐字节核对 magic、len、flags) - 确认 memset 或 memcpy 是否写入预期值(
x/8xb &data配合set {char} &data = 0xff验证)
容易踩的坑:地址自动偏移和格式延续
按字节查看时,GDB 的两个隐式行为特别容易导致误读:
- 执行
x/8xb &var后按回车,GDB 会从&var + 8开始继续显示下 8 字节——它记住的是“上次结束地址”,不是“起始地址” - 如果之前用过
x/4xw,再输x/8x,GDB 仍按w(4 字节)单位读,不会自动切到b;必须写全x/8xb才安全 - 对指针变量用
x/8xb ptr是查看ptr指向的内容;若想看指针自身存储的地址值(即 8 字节指针值),得用x/1xg &ptr或x/8xb &ptr
最稳妥的做法:每次按字节查都写全 x/Nxb,别依赖默认或历史格式;查完立刻用 x/1xb $pc 或 x/1xb &some_var 验证当前地址是否符合预期。内存调试里,差一个字节就可能跳到另一块数据上。











