在 GDB 中打印内存地址的值,可以使用以下两种核心命令:x
(examine)和 print
。以下是具体用法和示例:
1. 使用 x
命令(直接检查内存)
x
命令的语法为:
x/[数量][格式][单位] <内存地址>
参数说明:
-
数量:要显示的内存单元数量(例如
10
表示显示连续的 10 个单元)。 -
格式:
-
x
:十六进制 -
d
:十进制整数 -
u
:无符号十进制整数 -
t
:二进制 -
c
:字符 -
s
:字符串 -
i
:汇编指令
-
-
单位:
-
b
:字节(Byte,1字节) -
h
:半字(Halfword,2字节) -
w
:字(Word,4字节) -
g
:大双字(Giant word,8字节)
-
示例:
# 以十六进制显示地址 0xffffd008 处的 4 个字节
(gdb) x/4xb 0xffffd008
0xffffd008: 0x7f 0x00 0x00 0x00# 以十进制显示地址 0xffffd008 处的 1 个四字节整数
(gdb) x/1dw 0xffffd008
0xffffd008: 127# 以字符串显示地址 0x404000 处的内存(直到遇到 '\0')
(gdb) x/s 0x404000
0x404000: "Hello, World!"# 以汇编指令显示地址 0x401000 处的代码
(gdb) x/3i 0x401000
0x401000: push %rbp
0x401001: mov %rsp,%rbp
0x401004: sub $0x10,%rsp
2. 使用 print
命令(表达式求值)
print
可以通过类型转换直接解析内存地址的值,语法为:
print *(<类型>*)<内存地址>
示例:
# 将地址 0xffffd008 视为 int 指针并打印其值
(gdb) p *(int*)0xffffd008
$1 = 127# 将地址 0x404000 视为 char 指针并打印字符串
(gdb) p (char*)0x404000
$2 = 0x404000 "Hello, World!"# 将地址 0x401000 视为函数指针并调用反汇编
(gdb) disassemble *(void(*)())0x401000
Dump of assembler code for function main:
...
3. 注意事项
-
权限问题:
-
如果内存地址不可读(如未分配或权限不足),GDB 会报错:
Cannot access memory at address 0xdeadbeef
-
确保地址有效(例如通过调试符号或程序逻辑确认)。
-
-
动态地址:
-
若地址来自变量(如指针),可以直接用变量名:
(gdb) p *ptr # 打印指针指向的值 (gdb) x/x ptr # 直接检查指针指向的内存
-
-
寄存器中的地址:
-
打印寄存器中的地址值:
(gdb) x/x $rax # 检查 rax 寄存器中的地址 (gdb) p *(int*)$rax
-
4. 综合示例
假设调试以下代码:
int main() {int num = 42;int *ptr = #return 0;
}
调试步骤:
(gdb) break main
(gdb) run
(gdb) p &num # 获取 num 的地址,假设为 0x7fffffffd00c
(gdb) x/1dw 0x7fffffffd00c # 以十进制显示该地址的值(输出 42)
(gdb) p *ptr # 直接通过指针变量打印值(输出 42)
通过上述方法,你可以灵活地查看任意内存地址的值,无论是通过直接地址、指针变量还是寄存器。