Implement vFile fallback for when qMemoryRegionInfo is not supported
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
With `lldb` connected to a `gdbserver`, if you try to get memory regions you see:
```
(lldb) memory region 0
error: qMemoryRegionInfo is not supported
```
`qMemoryRegionInfo` is [specific to lldb](https://lldb.llvm.org/resources/lldbgdbremote.html#qmemoryregioninfo-addr). What has actually happened is we tried it, it did not work, then we tried to use the [XML memory map](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Memory-Map-Format.html). This is not available because it turns out that upstream `gdbserver` does not generate them at all. Must be some other debug server in the wild that does, and if they do, we do have code in lldb already that will parse it.
So we know why we get no regions for `lldb` -> `gdbserver`, but a `gdb` -> `gdbserver` connection shows this:
```
(gdb) info proc mappings
process 991519
Mapped address spaces:
Start Addr End Addr Size Offset Perms objfile
0x400000 0x47f000 0x7f000 0x0 r-xp /tmp/test.o
0x48f000 0x493000 0x4000 0x7f000 r--p /tmp/test.o
0x493000 0x496000 0x3000 0x83000 rw-p /tmp/test.o
0x496000 0x49b000 0x5000 0x0 rw-p
0x49b000 0x4bd000 0x22000 0x0 rw-p [heap]
0xfffff7ffd000 0xfffff7fff000 0x2000 0x0 r--p [vvar]
0xfffff7fff000 0xfffff8000000 0x1000 0x0 r-xp [vdso]
0xfffffffdf000 0x1000000000000 0x21000 0x0 rw-p [stack]
```
When you use `gdb` directly on the host, it can read `/proc/pid/[maps|smaps]`, but it must be doing something else for remote connections.
It is using `vFile` to read the file:
```
[remote] Sending packet: $vFile:setfs:0#bf
[remote] Packet received: F0
[remote] Sending packet: $vFile:open:2f70726f632f3939313531392f6d617073,0,1c0#4b
//// AKA /proc/991519/maps
[remote] Packet received: F5
[remote] remote_hostio_pread: readahead cache miss 9
[remote] Sending packet: $vFile:pread:5,47ff,0#6a
[remote] Packet received: F269;00400000-0047f000 r-xp 00000000 103:01 5634 /tmp/test.o\n0048f000-00493000 r--p 0007f000 103:01 5634 /tmp/test.o\n00493000-00496000 rw-p 00083000 103:01 5634 /tmp/test.o\n00496000-0049b000 rw-p 00000000 00:00 0 \n0049b000-004bd000 rw-p 00000000 00:00 0 [heap]\nfffff7ffd000-fffff7fff000 r--p 00000000 00:00 0 [vvar]\nfffff7fff000-fffff8000000 r-xp 00000000 00:00 0 [110 bytes omitted]
[remote] remote_hostio_pread: readahead cache miss 10
[remote] Sending packet: $vFile:pread:5,47ff,269#db
[remote] Packet received: F0;
[remote] Sending packet: $vFile:close:5#b5
[remote] Packet received: F0
```
In theory we can do the same thing. I tried it by manually sending packets to `gdbserver`:
```
$ ./bin/lldb /tmp/test.o
(lldb) target create "/tmp/test.o"
Current executable set to '/tmp/test.o' (aarch64).
(lldb) gdb-remote 1234
Process 991262 stopped
* thread #1, stop reason = signal SIGTRAP
frame #0: 0x0000000000400580 test.o`_start
test.o`_start:
-> 0x400580 <+0>: nop
0x400584 <+4>: mov x29, #0x0 ; =0
0x400588 <+8>: mov x30, #0x0 ; =0
0x40058c <+12>: mov x5, x0
(lldb) process plugin packet send vFile:open:2f70726f632f3939313236322f736d617073,0,0
packet: vFile:open:2f70726f632f3939313236322f736d617073,0,0
/////// AKA: /proc/991262/smaps
response: F5
(lldb) process plugin packet send vFile:pread:5,400,0
packet: vFile:pread:5,400,0
response: F400;00400000-0047f000 r-xp 00000000 103:01 5634 /tmp/test.o
<...>
(lldb) process plugin packet send vFile:pread:5,400,400
packet: vFile:pread:5,400,400
response: F400; 0 kB
<...>
(lldb) process plugin packet send vFile:close:5
packet: vFile:close:5
response: F0
```
Maybe we can blindly try the file path, or better, check we're at least connected to some Linux first. Though this might not be possible because for one thing, when using `gdbremote`, the platform is still the host machine's platform.
Try `smaps` first, then `maps`. We already have a parser used in lldb-server, we can use that in lldb too.
I also tried `gdb` -> `qemu`. It does not produce an XML memory map and it does not support this usage of `vFile`:
```
[remote] Sending packet: $qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;memory-tagging+#ec
[remote] Received Ack
[remote] Packet received: PacketSize=1000;qXfer:features:read+;qXfer:auxv:read+;vContSupported+;multiprocess+
<...>
(gdb) info proc mappings
process 1
[remote] Sending packet: $vFile:setfs:0#bf
[remote] Received Ack
[remote] Packet received:
[remote] packet_ok: Packet vFile:setfs (hostio-setfs) is NOT supported
[remote] Sending packet: $vFile:open:2f70726f632f312f6d617073,0,1c0#3b
[remote] Received Ack
[remote] Packet received:
[remote] packet_ok: Packet vFile:open (hostio-open) is NOT supported
warning: unable to open /proc file '/proc/1/maps'
```
Contributor guide
Research direction
Trace the existing qMemoryRegionInfo and XML memory-map fallback in LLDB, then locate the parser already used in lldb-server. Read the vFile handling and test remote reads of smaps followed by maps; done means supported Linux gdbserver connections return parsed memory regions while unsupported vFile targets continue to fail safely.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- linux
- Domain
- devtools, operating-systems
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100