Skip to content
bunnie edited this page May 7, 2023 · 7 revisions

Building

To build, add --gdb-stub to the xtask command line argument:

cargo xtask app-image-xip --gdb-stub

Note that the target service being debugged can not be an XIP (flash-based) binary, because GDB depends upon being able to patch the binary to set breakpoints.

Then load the kernel into an image onto the target device.

Usage

To use, attach gdb to the serial port.

From Your Build Machine

You can run GDB from your build machine, if you have wired up your device to a serial adapter (e.g. by powering up the debug HAT from a bench supply and using jumper cables to patch into an RS-232 adapter).

For example, to debug the ticktimer, you might run:

$ riscv-none-elf-gdb \
    -ex 'tar ext \\.\COM43' \
    -ex 'attach 2' \
    target/riscv32imac-unknown-xous-elf/release/xous-ticktimer

This will load the xous-ticktimer ELF file, then attach to the GDB server running on the serial port connected to COM43, then attach to process ID 2.

From a Raspberry Pi with Debug HAT

To set up a Raspberry Pi with the debug HAT:

  1. Load a RISC-V toolchain onto the Raspberry Pi (such as this one), and add it to your PATH
  2. Load the custom kernel with --gdb-stub enabled (either via USB update or by the betrusted-scripts helpers)
  3. Ensure that ttyS0 is configured for 115200 mode. This can be done by, for example, first running screen -fn /dev/ttyS0 115200 and then quitting the session with key sequence of ctrl-a then \ then y. The baud rate configuration only has to happen once per boot.
  4. Ensure that there are no open screen sessions or other serial terminals active on the RPi that are attached to the serial port (perhaps by running ps aux | grep -i screen)

To debug using the Raspberry Pi:

  1. Boot the target, then type console app into shellchat. This switches the UART over to the GDB-owned UART.
  2. Copy the binary for the server of interest to the Raspberry Pi
  3. Run the above command line with 'tar ext /dev/ttyS0' as the external target specifier, and your target binary as the last argument. Ensure that the 'attach PID' argument uses the PID as enumerated in the build script output.

For example:

riscv-none-elf-gdb -ex 'tar ext /dev/ttyS0' -ex 'attach 27' ~/vault

You will then be able to use normal GDB commands to inspect memory, single-step, add breakpoints, and switch threads.

Useful GDB Commands

The info thr command will list current threads. You may then switch threads with e.g. thr 4 to switch to thread 4.

The x command can be used to examine arbitrary memory.

b is used to insert breakpoints. Note that breakpoints are accomplished by replacing instructions in memory with c.ebreak instructions, so debugging does not work with XIP processes.

c will continue execution, and Control-C will pause execution.

stepi will single-step assembly execution.

You may switch processes with attach [PID]

Debugging and servers

When a process is under debug, messages will queue up. Interrupts are masked, and the process is paused.

When you continue a process under debug, it is unpaused, interrupts are re-enabled, and messages are delivered.

Renode fixes

When running this under Renode, a very recent copy (from April 2023 or later) is required. This also requires adjustments to the simulation models, which are included in this patchset.

Other Notes

If the serial link seems unstable, it may help to add

-ex 'set remote noack-packet off' first in your GDB command list.

You can also use

-ex 'set debug remote 1' to print debug info.