Skip to content

GDB Remote Protocol proposal: qXfer:vmcoreinfo packet

Stephen Brennan edited this page Jan 27, 2025 · 4 revisions

Rationale

When debugging remote Linux kernel targets, it is useful to know several pieces of information:

  1. The KASLR offset (a.k.a. KERNELOFFSET) is needed to get the correct address for kernel symbols.
  2. The kernel release and build ID can be used to identify the required debuginfo files.
  3. The physical load address of the kernel, i.e. phys_base on x86_64, can be useful when virtual address mappings aren't available.
  4. When DWARF debuginfo is unavailable, symbol addresses related to the kallsyms table can be used to debug using kallsyms and CTF/BTF.

Without this information, debugging is still possible but not as convenient. For example, the kernel can be booted without nokaslr, or the load address can be provided to the debugger manually. Without the release and build ID, debuginfo files can be provided to the debugger manually, but the debugger can't verify that the correct files were provided.

All of the above information is provided in the Linux kernel's vmcoreinfo note. It consists of key=value pairs, one per line:

OSRELEASE=6.10.11-200.fc40.x86_64
BUILD-ID=10ec4eb10b2a543ab4b49ae92779eee292273374
PAGESIZE=4096
SYMBOL(init_uts_ns)=ffffffffab7c2e80
...

Multiple kernel debugging tools like drgn, crash, and makedumpfile already depend on vmcoreinfo for various purposes. Making vmcoreinfo available to tools using the GDB remote protocol would improve the user experience.

The data contained in the vmcoreinfo is typically around 3k bytes. (EG: my laptop has 3264 bytes vmcoreinfo). For slow connections (e.g. 9600 baud w/ parity & stop bits: 960 bytes/sec), this would take around 3 seconds to transmit. We want to ensure that we design this as efficiently as possible, to reduce the amount of time spent reading the data.

Protocol Changes

We propose adding a new object type vmcoreinfo to the qXfer command. The qXfer command allows fetching arbitrary binary data from the target. The command operates as follows:

Request: qXfer:vmcoreinfo:read::OFFSET,LENGTH

Reply:

  • m [DATA] - DATA read from the target OFFSET. More data may yet to be read. The amount of data returned may be less than LENGTH.
  • l [DATA] - DATA read from the target offset. There is no more data to be read. The amount of data may be less than LENGTH.
  • l - There is no data at that offset.

Update to qSupported response

GDB stubs supporting this should include qXfer:vmcoreinfo:read in their list of capabilities as a response to the qSupported command.

Background on Binary Data Encoding

The remote protocol seems to have two main approaches for encoding binary data: "M-type" and "X-type" packets. You can see them implemented in the gdbserver.

  • M type: each byte of data is transmitted as two hexadecimal digits. This is used for older commands which did not assume an 8-bit clean connection.
  • X type: each byte is transmitted as-is, but the characters $#}* must be escaped. The encoding is described in Binary Data. Implemented here in GDB for read and write.

The X type is what is used by the qXfer commands, and it works for vmcoreinfo. Even if the connection is not 8-bit clean, the contents of vmcoreinfo are valid ASCII, and the escaping scheme doesn't introduce non-ASCII bytes.

Anticipated Changes

GDB

  • Update the GDB Remote Protocol manual with documentation of this new qXfer object.
  • Add support for executing this query command via a GDB command like info vmcoreinfo or something similar.

A Python GDB script is provided below, which can be used as the client side when testing stub implementations: https://gist.github.com/brenns10/c936c8e7ef8193e668884ed70070ccfb

QEMU

Implement support for this query command which relies on the VmCoreInfo device.

Linux

Implement support for this query command in the kgdb gdb stub based on the built-in vmcoreinfo. This will require implementing an encoder for the escaped binary format (kgdb_mem2ebin()).

drgn

Add client support for this query command as part of the gdbstub support feature for kernel targets.

Alternatives Considered

  • A previous version of this document described a generic query packet, q linux.vmcoreinfo. We realized that for typical vmcoreinfo sizes (nearing 4096 bytes), including the entirety of the data in a single packet would require a large buffer in the kgdb implementation, and it would also violate expectations of buffer sizes in other implementations. After consulting with GDB developers, we updated this proposal to use the qXfer command, which allows the client to request data from a specific offset and length. This ensures that the client & stub can use the best buffer sizes available to both, and the data is transmitted across multiple packets as necessary.