Skip to content

GDB Remote Protocol proposal: linux.vmcoreinfo query packet

Omar Sandoval edited this page Nov 7, 2024 · 1 revision

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.

Protocol Changes

We propose adding a custom query packet that returns the Linux kernel vmcoreinfo note.

According to the GDB Serial Protocol: General Query Packets document:

Packets starting with ‘q’ are general query packets

And:

The names of custom vendor packets should use a company prefix, in lower case, followed by a period. For example, packets designed at the Acme Corporation might begin with ‘qacme.foo’ (for querying foos) or ‘Qacme.bar’ (for setting bars).

It stands to reason that for Linux kernel specific debugging information, we should adopt a prefix of linux.. So, we propose adding a qlinux.vmcoreinfo query. The response will be the vmcoreinfo data encoded in the escaped binary format documented in the GDB Remote Protocol Overview.

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.
  • 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 seems to be the more appropriate option, given that some connections may be rather slow, and we don't expect this protocol to be used over any connection that is not 8-bit clean. 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

Add support for executing this query command via a GDB command like info vmcoreinfo or something similar.

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.