blob: 2f3577df39a8e9e9be2707e6a9f58e80ea949bc8 [file] [log] [blame] [view]
# Inspect memory in zxdb
Zxdb can help you inspect memory for debugging purposes with the following
commands:
* [`aspace`](#aspace)
Shows mapped memory regions.
* [`mem-analyze`](#mem-analyze)
Dumps memory to help you to interpret pointers.
* [`mem-read` / `x`](#mem-read)
Dumps process memory.
* [`stack-data`](#stack-data)
Provides a low-level analysis of the stack.
* [`sym-near`](#sym-near)
Maps addresses to symbols.
## `aspace` {#aspace}
Note: This is the `aspace` command. You can also use `as` to express `aspace`.
The `aspace` command outputs address space information for the process. In
Fuchsia, virtual memory consists of a hierarchy of [Virtual Memory
Objects][vmo-object] (VMOs).
For example, the `aspace` command shows all VMOs in the process:
```none {: .devsite-terminal data-terminal-prefix="[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.)
```
If you specify an address, the `aspace` command shows the VMO hierarchy that
contains the specified address. This can be useful to determine where an address
is in memory, as the names of the VMOs typically indicate what type of region
that memory address is.
```none {: .devsite-terminal data-terminal-prefix="[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
```
In the example above, the `aspace` command details the following about the
`0x6d0d1ad000` address:
* Hierarchy of VMOs that contain the address.
* The address and size of each VMO.
* The name of each VMO, which can give clues about their purpose.
* From the name in this example, you can tell the address is in a stack
allocated by `pthreads`.
The `Cmt.Pgs` column shows the number of committed pages (not bytes) in that
memory region in the mapped VMO.
If a VMO is a child (as in the case of mapped blobs), the original data is
present in the parent VMO but the child VMO that is actually mapped indirectly
references this data. The only pages in the child that count as committed
are those that are duplicated due to copy-on-write. This is why BLOBs and other
files that are unmodified will have a 0 committed page count.
### Additional details about the output
The following are relevant VMO names that could be included in output from the
`aspace` command:
* `initial-thread`: The stack of the startup thread.
* `pthread_t:0x...`: The stack of a pthread-created thread. The address
indicates the memory location of the `pthread_t structure for that thread.
* `*uncompressed-bootfs`: A memory-mapped library coming from bootfs (core
system libraries). The `libs` command can tell you the library name for that
address.
* `stack: msg of ...`: The startup stack. This very small stack is only used
by the dynamic linker and loader code.
* `scudo:*`: Pages allocated with the scudo memory manager. If the process is
using scudo, these regions are the application heap.
* `vdso/next`: The built-in library that implements the next system calls.
* `vdso/stable`: The built-in library that implements the stable system calls.
* `blob-*`: Mapped library coming from blobfs. The `libs` command returns
the library name for that address.
To see more information about a VMO, use the command `handle -k <koid>`
## `mem-analyze` {#mem-analyze}
Note: This is the `mem-analyze` command. You can also use `ma` to express
`mem-analyze`.
This command attempts to interpret memory as pointers and decode what they
point to. Addresses with corresponding symbols are symbolized, while other
addresses indicate the name of the memory-mapping region they fall into.
Note: For more information about dumping unknown memory, see the
[`aspace`](#aspace) command.
This example analyzes `0x42ff9c2fdd30`:
```none {: .devsite-terminal data-terminal-prefix="[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
```
The `stack-data` command is a variant of `mem-analyze` and helps you analyze a stack.
For more information, see [`stack-data`](#stack-data).
## `mem-read` {#mem-read}
Note: This is the `mem-read` command. You can also use `x` to express `mem-read`.
The `mem-read` command provides hex dumps of the given address. Optionally, you
can override the default byte size to read with the `-size` (`-s`) option.
This example show the hex dumps for address `0x42ff9c2fdd30` while only reading
up to `100` bytes:
```none {: .devsite-terminal data-terminal-prefix="[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
```
The `mem-read` command also supports an expression that evaluates to an address.
For example, if the type of the pointer has a known size, the dump automatically
shows that many bytes:
```none {: .devsite-terminal data-terminal-prefix="[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`
The `stack-data` command provides a low-level analysis of the stack. This works
similarly to `mem-analyze`. `stack-data` defaults to the top of the current
thread's stack. The `stack-data` command attempts to decode addresses present in
the memory region, but it also adds annotations for the known register values
and stack base pointers of the thread.
For example:
```none {: .devsite-terminal data-terminal-prefix="[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 zx_status::Status::ok
0x1605a5d1460 0x0000000000000000 frame 2 rsp
0x1605a5d1468 0x0000000000000000
0x1605a5d1470 0x0000000000000000
0x1605a5d1478 0x0000000000000000
0x1605a5d1480 0x0000000000000000 rdx, r14
```
In the notes column:
* Left-pointing arrows indicate which registers point to that stack location.
* Right-pointing arrows indicate where the value of the stack entry points to
if it is interpreted as an address.
## `sym-near` {#sym-near}
Note: This is the `sym-near` command. You can also use `sn` to express `sym-near`.
The `sym-near` command attempts to map an address to a symbol name. Running the
command outputs the name and line information (if available) for the symbol at
or preceding the address and is most often used to tell what a pointer points to.
For example:
```none {: .devsite-terminal data-terminal-prefix="[zxdb]" }
sym-near 0x125dd3a845e
0x125dd3a845e, power_manager::main() main.rs:37
```
[vmo-object]: /docs/reference/kernel_objects/vm_object.md