检查 zxdb 中的内存

Zxdb 可以帮助您检查内存以进行调试,方法如下: 命令:

aspace

aspace 命令会输出进程的地址空间信息。在 Fuchsia,虚拟内存由虚拟内存层级结构组成 对象 (VMO)。

例如,aspace 命令会显示进程中的所有 VMO:

[zxdb] aspace
           Start              End  Prot   Size      Koid       Offset  Cmt.Pgs  Name
        0x200000   0x7ffffffff000  ---    127T                                  proc:14629522
        0x200000   0x7ffffffff000  ---    127T                                    root
     0xe4ff29000      0xe5012a000  ---      2M                                      useralloc
     0xe4ff2a000      0xe5012a000  rw-      2M  14629569     0x201000        2        initial-thread
    0x6d0d1ad000     0x6d4d1b2000  ---      1G  14629573          0x0        0      scudo:reserved
    0x6d4d1b2000     0x6d4d1f2000  rw-    256K  14629575       0x5000        2      scudo:primary
...
  0x42afdf75e000   0x42afdf761000  rw-     12K  14629536          0x0        1        data:uncompressed-bootfs
  0x42afdf761000   0x42afdf771000  rw-     64K  14629537          0x0       16        bss:uncompressed-bootfs

              Page size: 4096
     Total mapped bytes: 48329449472
  Total committed pages: 125 = 512000 bytes
                         (See "help aspace" for what committed pages mean.)

如果您指定了地址,aspace 命令会显示 包含指定的地址。这有助于确定 因为 VMO 的名称通常表示什么类型的区域 找到该内存地址

[zxdb] aspace 0x6d0d1ad000
         Start              End  Prot  Size      Koid  Offset  Cmt.Pgs  Name
      0x200000   0x7ffffffff000  ---   127T                             proc:14629522
      0x200000   0x7ffffffff000  ---   127T                               root
  0x6d0d1ad000     0x6d4d1b2000  ---     1G  14629573     0x0        0      scudo:reserved

              Page size: 4096

在上面的示例中,aspace 命令详细介绍了 0x6d0d1ad000地址:

  • 包含地址的 VMO 的层次结构。
  • 每个 VMO 的地址和大小。
  • 每个 VMO 的名称,可用于提供有关其用途的线索。
    • 通过此示例中的名称,您可以看出该地址位于堆栈中 由 pthreads 分配。

Cmt.Pgs 列显示该时间段内提交的页面数(而非字节) 映射的 VMO 中的内存区域。

如果 VMO 是一个子项(如映射的 blob 中一样),则原始数据为 存在于父 VMO 中,但实际上间接映射的子 VMO 引用此数据。子级中唯一计为已提交的页面 因写入时复制而复制的内容。这就是 BLOB 和其他 未修改的文件的提交页数将为 0。

有关输出的其他详细信息

以下是相关的 VMO 名称,可以包含在 aspace 命令:

  • initial-thread:启动线程的堆栈。
  • pthread_t:0x...:pthread 创建的线程的堆栈。地址 表示该线程的 `pthread_t 结构体的内存位置。
  • *uncompressed-bootfs:来自 bootfs(核心 系统库)。libs 命令可以告诉您 地址。
  • stack: msg of ...:启动堆栈。这个非常小的堆栈 由动态链接器和加载器代码决定
  • scudo:*:使用 Scudo 内存管理器分配的页面。如果进程 这些区域就是应用堆
  • vdso/next:实现后续系统调用的内置库。
  • vdso/stable:用于实现稳定系统调用的内置库。
  • blob-*:来自 blobfs 的映射库。libs 命令会返回 该地址的图书馆名称。

如需详细了解 VMO,请使用命令 handle -k <koid>

mem-analyze

此命令会尝试将内存解释为指针,并解码内存中的内容 。带有相应符号的地址经过符号化处理,而其他 表示它们所在内存映射区域的名称。

以下示例分析了 0x42ff9c2fdd30

[zxdb] mem-analyze 0x42ff9c2fdd30
       Address               Data
0x42ff9c2fdd30 0x00000000000015f0
0x42ff9c2fdd38 0x0000000000000008
0x42ff9c2fdd40 0x000042f401a8a730 ▷ ldso
0x42ff9c2fdd48 0x000042f401a8a9f8 ▷ $(dls3.app)
0x42ff9c2fdd50 0x0000000000000053
0x42ff9c2fdd58 0x0000000010469c6b
0x42ff9c2fdd60 0x000042f401a8a9f8 ▷ $(dls3.app)
0x42ff9c2fdd68 0x0000000000000000
0x42ff9c2fdd70 0x000042ff9c2fde70 ▷ inside map "stack: msg of 0x1000"
0x42ff9c2fdd78 0x000042f4015e5548 ▷ dls3 + 0x42b
0x42ff9c2fdd80 0x10469c6b10769c7b
0x42ff9c2fdd88 0x10569c3310469c23
0x42ff9c2fdd90 0x10469c2710469c37

stack-data 命令是 mem-analyze 的变体,可帮助您分析堆栈。 如需了解详情,请参阅 stack-data

mem-read

mem-read 命令提供给定地址的十六进制转储。您可以选择 可以使用 -size (-s) 选项替换要读取的默认字节大小。

此示例显示了地址 0x42ff9c2fdd30 的十六进制转储,同时仅读取 最多 100 个字节:

[zxdb] mem-read -s 100 0x42ff9c2fdd30
0x42ff9c2fdd30:  f0 15 00 00 00 00 00 00-08 00 00 00 00 00 00 00  |
0x42ff9c2fdd40:  30 a7 a8 01 f4 42 00 00-f8 a9 a8 01 f4 42 00 00  |0    B       B
0x42ff9c2fdd50:  53 00 00 00 00 00 00 00-6b 9c 46 10 00 00 00 00  |S       k F
0x42ff9c2fdd60:  f8 a9 a8 01 f4 42 00 00-00 00 00 00 00 00 00 00  |     B
0x42ff9c2fdd70:  70 de 2f 9c ff 42 00 00-48 55 5e 01 f4 42 00 00  |p /  B  HU^  B
0x42ff9c2fdd80:  7b 9c 76 10 6b 9c 46 10-23 9c 46 10 33 9c 56 10  |{ v k F # F 3 V
0x42ff9c2fdd90:  37 9c 46 10

mem-read 命令还支持计算结果为地址的表达式。 例如,如果指针的类型大小已知,则转储 会显示许多字节:

[zxdb] mem-read &self->main_waker
0x1605a5d1ed0:  70 1a c8 36 47 04 00 00-68 fe 3d dd 25 01 00 00  |p  6G   h = %

stack-data

stack-data 命令提供堆栈的底层分析。这行 类似于 mem-analyzestack-data 默认为当前行的顶部 线程堆栈。stack-data 命令尝试解码 但它也会为已知寄存器值添加注解 和堆栈基指针

例如:

[zxdb] stack-data
      Address               Data
0x1605a5d1428 0x000042a352fca11f ◁ rsp. ▷ _zx_port_wait + 0x1f
0x1605a5d1430 0x000001605a5d1460 ◁ frame 1 rsp. ▷ inside map "initial-thread"
0x1605a5d1438 0x000001605a5d1540 ▷ inside map "initial-thread"
0x1605a5d1440 0x7fffffffffffffff
0x1605a5d1448 0x0000044ab6c81800 ▷ inside map "scudo:primary"
0x1605a5d1450 0x000001605a5d14d0 ◁ rbp, frame 1 base. ▷ inside map "initial-thread"
0x1605a5d1458 0x00000125dd3566f5 ▷ fuchsia_zircon_status::Status::ok
0x1605a5d1460 0x0000000000000000 ◁ frame 2 rsp
0x1605a5d1468 0x0000000000000000
0x1605a5d1470 0x0000000000000000
0x1605a5d1478 0x0000000000000000
0x1605a5d1480 0x0000000000000000 ◁ rdx, r14

在“备注”列中:

  • 左指箭头指示哪些寄存器指向该堆栈位置。
  • 右指箭头指示堆栈入口点的值 如果它被解释为地址。

sym-near

sym-near 命令会尝试将地址映射到符号名称。运行 命令会输出 处符号的名称和行信息(如果有的话) 或地址前,常用于判断指针所指向的内容。

例如:

[zxdb] sym-near 0x125dd3a845e
0x125dd3a845e, power_manager::main() • main.rs:37