使用gdb调试时,如何打印某个内存地址的值

在 GDB 中打印内存地址的值,可以使用以下两种核心命令:x(examine)和 print。以下是具体用法和示例:


1. 使用 x 命令(直接检查内存)

x 命令的语法为:

bash
复制
x/[数量][格式][单位] <内存地址>

参数说明

  • 数量:要显示的内存单元数量(例如 10 表示显示连续的 10 个单元)。

  • 格式

    • x:十六进制

    • d:十进制整数

    • u:无符号十进制整数

    • t:二进制

    • c:字符

    • s:字符串

    • i:汇编指令

  • 单位

    • b:字节(Byte,1字节)

    • h:半字(Halfword,2字节)

    • w:字(Word,4字节)

    • g:大双字(Giant word,8字节)

示例

bash
复制
# 以十六进制显示地址 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 可以通过类型转换直接解析内存地址的值,语法为:

bash
复制
print *(<类型>*)<内存地址>

示例

bash
复制
# 将地址 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. 注意事项

  1. 权限问题

    • 如果内存地址不可读(如未分配或权限不足),GDB 会报错:

      bash
      复制
      Cannot access memory at address 0xdeadbeef
    • 确保地址有效(例如通过调试符号或程序逻辑确认)。

  2. 动态地址

    • 若地址来自变量(如指针),可以直接用变量名:

      bash
      复制
      (gdb) p *ptr       # 打印指针指向的值
      (gdb) x/x ptr      # 直接检查指针指向的内存
  3. 寄存器中的地址

    • 打印寄存器中的地址值:

      bash
      复制
      (gdb) x/x $rax     # 检查 rax 寄存器中的地址
      (gdb) p *(int*)$rax

4. 综合示例

假设调试以下代码:

c
复制
int main() {
    int num = 42;
    int *ptr = &num;
    return 0;
}

调试步骤:

bash
复制
(gdb) break main
(gdb) run
(gdb) p &num           # 获取 num 的地址,假设为 0x7fffffffd00c
(gdb) x/1dw 0x7fffffffd00c  # 以十进制显示该地址的值(输出 42)
(gdb) p *ptr           # 直接通过指针变量打印值(输出 42)

通过上述方法,你可以灵活地查看任意内存地址的值,无论是通过直接地址、指针变量还是寄存器。

 
 
 
posted @ 2025-02-06 13:35  墨尔基阿德斯  阅读(1684)  评论(0)    收藏  举报