blob: 25c4e2d98496c8680c2a3dd445fa712fc29df15b [file] [log] [blame] [view]
# Inspecting memory in zxdb
Zxdb supports the following commands for inspecting memory:
* [`aspace`](#aspace_show_mapped_memory_regions)
* [`mem-analyze`](#mem-analyze_dumps_memory_trying_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_map_addresses_to_symbols)
## `aspace`: Show mapped memory regions.
The `aspace` command, abbreviated `as`, outputs address space information for the process. In
Fuchsia, virtual memory consists of a hierarchy of [Virtual Memory
Objects](/docs/reference/kernel_objects/vm_object.md) (VMOs).
With no parameters, the `aspace` command shows all VMOs in the process.
```none {:.devsite-disable-click-to-copy}
[zxdb] as
```
When given an address, the `aspace` command shows the VMO hierarchy containing just that 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 is.
```none {:.devsite-disable-click-to-copy}
[zxdb] as 0x10b7f304d28
```
### Understanding the output
In the following example, the `aspace` command details the following about the `0x10b7f304d28`
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.
```none {:.devsite-disable-click-to-copy}
Start End Size Koid Offset Com.Pgs Name
0x1000000 0x7ffffffff000 127T proc:3109
0x1000000 0x7ffffffff000 127T root
0x10b7f104000 0x10b7f305000 2M useralloc
0x10b7f105000 0x10b7f305000 2M 3824 0x0 2 pthread_t:0x10c4ea38b00
```
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 used only 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 can tell you the library name
for that address.
To see more information about a VMO, use the command `handle -k <koid>`
The "Cmt.Pgs" column shows the number of committed pages (not bytes) in that memory region in the
mapped VMO. This can be surprising for memory mapped files like blobs and other shared VMOs.
If a VMO is a child (as in the case of mapped blobs), the original data will be present in the
parent VMO but the child VMO that is actually mapped will indirectly reference this data. The only
pages in the child that will count as committed are those that are duplicated due to copy-on-write.
This is why blobs and other files that are not modified will have a 0 committed page count.
## `mem-analyze`: Dumps memory, trying to interpret pointers.
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 (see the [`aspace`](#aspace_show_mapped_memory_regions)
command). It can be useful for dumping unknown memory.
```none {:.devsite-disable-click-to-copy}
[zxdb] ma 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
```
See also [`stack`](#stack_provides_a_low-level_analysis_of_the_stack), which is a variant of the
`mem-analyze` command for stack analysis.
## `mem-read`: Dump process memory
The `mem-read` command, abbreviated `x`, provides hex dumps of the given address. You supply
the address and optionally override the default size with the `-s` option.
```none {:.devsite-disable-click-to-copy}
[zxdb] x -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
```
You can also supply an expression that evaluates to an address. If the type of the pointer has
a known size, the dump automatically shows that many bytes:
```none {:.devsite-disable-click-to-copy}
[zxdb] x &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`: Provides a low-level analysis of the stack
The `stack-data` command analyzes the stack in a similar way to `mem-analyze`. It 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.
```none {:.devsite-disable-click-to-copy}
[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
```
In the notes column, left-pointing arrows indicate which registers point to that stack location,
while right-pointing arrows indicate where the value of the stack entry points to if it is
interpreted as an address.
## `sym-near`: Map addresses to symbols
The `sym-near` command, abbreviated `sn`, 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.
```none {:.devsite-disable-click-to-copy}
[zxdb] sym-near 0x125dd3a845e
0x125dd3a845e, power_manager::main() main.rs:37
```