Skip to the content.

GDB remote debugging

Amiberry can expose the emulated 68k CPU to a GDB client through the GDB remote serial protocol. The server is part of the built-in debugger, is off by default, and is controlled only by configuration options. It comes from WinUAE.

Enabling the server

Add these lines to a .uae configuration:

debugging_features=gdbserver
gdb_port=2345

or pass them on the command line:

amiberry -s debugging_features=gdbserver -s gdb_port=2345

gdb_port defaults to 2345. Amiberry logs WinUAE GDB: listening on 127.0.0.1:<port> when the server starts.

The standalone application and libretro core build the server when both DEBUGGER and GDBSERVER are defined. Both poll it from handle_events().

The server is not available with the threaded CPU option (cpu_threaded=true). In that mode Amiberry logs WinUAE GDB: not available with the threaded CPU (cpu_threaded=true) and does not listen.

gdb_server_poll() runs from Amiberry’s handle_events() loop. It never accesses emulated state from a socket thread. The server listens on 127.0.0.1 only and accepts one client at a time. It is unauthenticated: any local process that connects gets full control of the guest. When it is enabled but no client is attached, the only cost is a non-blocking accept() once per frame; nothing traces the CPU.

Connecting

Use any GDB that supports m68k, for example m68k-elf-gdb, m68k-amigaos-gdb or gdb-multiarch:

(gdb) set endian big
(gdb) set architecture m68k
(gdb) target remote 127.0.0.1:2345

gdb-multiarch needs set endian big when no m68k executable is loaded; otherwise it shows every register byte-swapped.

The CPU stops at the next debugger boundary when a client attaches. If the emulator is paused in Amiberry, unpause it first, because the CPU has to run to reach that boundary. While the CPU is stopped, the Amiberry window does not update.

What is supported

Memory addresses are physical; guest MMU translation is not applied. A watchpoint range must end at or below the watch limit: $01000000 with 24-bit addressing, $7FFF0000 otherwise. GDB data watchpoints, watch range, and dma-watch spans are at most 64 KiB long; watch add accepts sizes of 1, 2, or 4 bytes only. Watchpoints are unavailable while the debugger’s MMU mode is enabled.

Because the target provides a memory map, GDB refuses to access addresses outside the listed RAM and ROM regions. To read custom chip registers, allow access to unlisted regions first:

(gdb) set mem inaccessible-by-default off
(gdb) x/2xh 0xdff004

Monitor commands

Amiberry-specific operations use GDB monitor (qRcmd) commands. Replies are hex-encoded text, usually JSON. Numeric arguments are hexadecimal unless a command says otherwise. Commands require a stopped CPU except capabilities, execution-status, and input commands. Input events and frame-scheduled input sequences may be submitted while the guest runs.

monitor capabilities is the authoritative command list. It omits commands that are unavailable in the active build or configuration.

IPC

The same monitor text is available on the IPC socket as MONITOR, without a GDB client. The command, the stop behaviour, and the ownership rule are described in docs/ipc.md. IPC refuses step-over and checkpoint and names DEBUG_STEP_OVER, SAVESTATE, and LOADSTATE (saving state requires resuming or pausing first if the debugger has the CPU stopped). A GDB connection is refused while IPC holds monitor state, and IPC will not change that state while a GDB client is connected.

Detaching

detach, or closing the client, resumes the emulation and removes the breakpoints and watchpoints that the client set, along with monitor conditions, exception selection, entry state, history recording, the watch event log, captured output, and held input. Breakpoints and watchpoints set from Amiberry’s own debugger stay in place. A hard reset of the emulated machine closes the connection.