Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Remote GDB debugging

Copperline includes a built-in GDB remote debugging stub:

./target/release/copperline --config copperline.example.toml --noaudio --gdb :2345

Port-only syntax (2345 or :2345) binds to 127.0.0.1. To bind to all interfaces on a trusted local network, specify 0.0.0.0:2345. The stub has no authentication, so do not expose it to untrusted networks.

Headless and windowed modes

--gdb runs headless: the stub takes control of the machine, halts at reset, and advances unthrottled. It cannot be combined with an interactive window, the scheduled capture flags (--screenshot-after, --expect-screenshot, --save-state-after, --dump-frames, --gif-after), scheduled input, scheduled floppy or CD inserts, --record-input, --exit-on-return, or --benchmark-until. It serves one client at a time: a detach or dropped connection leaves the machine paused for the next client, and GDB’s kill ends the process. Reverse execution is armed from the start, with the budget and snapshot interval taken from COPPERLINE_DBG_RR_BUDGET_MB and COPPERLINE_DBG_RR_INTERVAL.

--gdb-gui ADDR attaches the GDB remote stub to an interactive windowed session:

./target/release/copperline --config copperline.example.toml --gdb-gui :2345

Standard GDB frontends work with both modes: VS Code cppdbg configurations ("MIMode": "gdb", "miDebuggerServerAddress": "localhost:2345", "miDebuggerPath" pointing to m68k-amigaos-gdb) or Native Debug’s target remote setup, with --gdb-gui keeping the Amiga display live alongside the IDE. For IDE debugging without a GDB at all, with source lines read straight from the hunk executable, see the Debug Adapter Protocol server (copperline-ctl --dap).

Connecting from GDB

Start a 68k-aware GDB (such as m68k-amigaos-gdb or multiarch gdb) and connect:

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

The target starts halted at reset. The stub supports:

Amiga-specific monitor commands

GDB’s monitor command provides access to Amiga custom chipset state, raster positions, Copper disassembly, and Exec structures:

(gdb) monitor help             # List the monitor commands
(gdb) monitor reset            # Warm-reset the machine (keyboard reset)
(gdb) monitor status           # Summary: PC, SR, frame, beam position, reverse debug status
(gdb) monitor beam             # Current raster beam position (VPOS, HPOS) and colour clock
(gdb) monitor custom           # Custom chipset state dump
(gdb) monitor reg DMACON       # Read custom register without side effects
(gdb) monitor write-reg COLOR00 00F # Write custom register
(gdb) monitor watch-reg BPLCON0 # Stop when the CPU or Copper writes the register
(gdb) monitor unwatch-reg BPLCON0 # Remove one register watch
(gdb) monitor clear-reg-watches # Remove every register watch
(gdb) monitor copper           # Disassemble Copper instructions
(gdb) monitor beam-trap 100 40 # Break when beam reaches VPOS 100, HPOS 40
(gdb) monitor clear-beam-traps # Remove every beam trap
(gdb) monitor copper-break C01000 # Break when Copper PC reaches address
(gdb) monitor clear-copper-breaks # Remove every Copper breakpoint
(gdb) monitor stepover         # Step over a BSR/JSR/TRAP (single step otherwise)
(gdb) monitor finish           # Run until the current subroutine returns
(gdb) monitor return-to-program # Run until PC leaves $F80000-$FFFFFF
(gdb) monitor segments         # List loaded hunk segments for current process
(gdb) monitor who F81234       # Name a live ROM/LVO address and offset
(gdb) monitor execbase         # Exec's scheduler state and boot-time machine facts
(gdb) monitor tasks            # List Exec ready, waiting, and active tasks
(gdb) monitor task input.device # One task or process in full (default: ThisTask)
(gdb) monitor memlist          # Exec's memory regions with free space and attributes
(gdb) monitor loadseg-break    # Toggle a stop whenever a new program is loaded
(gdb) monitor loadseg-list     # List tracked program loads and their segments

Register arguments take a name or a hex offset (NAME|OFFSET), and write-reg values are hex. beam-trap VPOS [HPOS] takes decimal beam positions; it and copper-break ADDR (hex) toggle, so repeating the command removes the trap. copper [auto|pc|ADDR] [COUNT] starts at COP1LC (auto, the default), the Copper’s current PC (pc), or a hex address, and disassembles COUNT instructions (COUNT is hex; the default is 64). task takes a $-prefixed address or a task name (matched case-insensitively), and with no argument shows ExecBase->ThisTask. stepover, finish, and return-to-program stop early at a breakpoint or watchpoint and give up after 5,000,000 instructions.

monitor who reads the running guest’s Exec library and device vectors, so it follows SetFunction() patches and does not depend on the Kickstart version. Addresses not reached through a public vector are identified by their containing ROM resident module when possible.

In windowed mode (--gdb-gui), monitor warp on|off|status controls the GDB client’s warp hold, running unthrottled with audio muted until that hold is released or the client disconnects (another holder keeps the machine warping; status names every holder).

Source-level debugging and program loading

Launching with --run

When using --run alongside --gdb, Copperline automatically halts at the entry point of the loaded Amiga executable before the first instruction executes:

copperline --run build/hello --gdb :2345

In GDB:

(gdb) target remote :2345
(gdb) continue
# Halts at LoadSeg completion, reporting hunk base address
(gdb) add-symbol-file build/hello.elf 0x018FE8
(gdb) break main
(gdb) continue

Automatic library and segment relocation

If your GDB client supports qXfer:libraries:read, Copperline reports new program loads dynamically. When using m68k-amigaos-gdb with an existing process:

  1. Launch your program from the Amiga shell.

  2. In GDB, run target remote :2345.

  3. GDB queries qOffsets, automatically aligning symbols with the loaded hunk addresses.

Reverse debugging with GDB

The GDB stub integrates with Copperline’s snapshot ring buffer:

GDB commandAction
reverse-stepReconstructs and steps backward by one instruction
reverse-continueExecutes backward until a preceding GDB breakpoint is reached
monitor last-writer ADDRFinds the last instruction that modified memory at ADDR

Bartman extension backend

Install the public Copperline fork of Bartman’s Amiga C/C++ extension using the pinned-revision VSIX instructions in Bartman with Copperline. That guide includes a complete project setup and illustrated profiler walkthrough; it does not depend on an upstream merge or release. The fork adds these VS Code settings:

{
  "amiga.emulator": "copperline",
  "amiga.copperline-path": "/path/to/copperline"
}

Use the extension’s usual launch configuration (program is the ELF path without its extension, beside a matching .exe hunk executable). The backend keeps the extension’s patched m68k-amiga-elf-gdb, maps its model and memory presets to Copperline CLI arguments, and seeds the guest RTC from the host clock. Use the bundled AROS ROM (omit kickstart) or Kickstart 1.3 or newer for --run; detached launches require 2.0+ or AROS. The standard Marketplace extension does not contain this backend; keep the fork installed as described in the setup guide.

The equivalent manual command is:

copperline --factory --model A500 --chip 512K --slow 512K \
  --run build/demo.exe --gdb-gui :2345 --gdb-dialect bartman

--gdb-dialect bartman works with --gdb and --gdb-gui. Standard is the default; the switch explicitly selects the patched GDB’s wire contract:

(gdb) monitor profile 2 "build/demo.unwind" "/tmp/demo.profile"

This runs a bounded capture of 1-100 frames, sends live PRF: n/N console packets, and writes the mixed-endian binary consumed by the extension’s ProfileFile reader. Use an empty unwind path ("") for leaf-only sampling. The writer finishes the current partial frame before snapshotting replay memory, then captures complete frames. It publishes the output only on success and restores its instrumentation on failure. Both transports suspend their session-owned exception catches and memory watches during capture, restoring them and their watch baselines afterward.

The legacy binary has a fixed PAL 227 by 313 DMA grid and carries chip and slow RAM only. NTSC and programmable geometry use Copperline’s native profile captures. The upstream .uss editor’s UAE launch path is separate; use USS import for those states.

To exercise attach ordering, exact main and ROM-exit stops, a two-frame capture, restart, and illegal-instruction/address-error signals using the real patched GDB:

python3 tools/check-bartman-gdb.py \
  --gdb /path/to/vscode-amiga-debug/bin/darwin/opt/bin/m68k-amiga-elf-gdb \
  --program build/demo.exe --elf build/demo.elf --out /tmp/gdb-check

An optional --unwind FILE uses the extension’s compact table; --gui checks the windowed transport, including an exact breakpoint stop when automatic launch warp ends at the same boundary. The output directory contains the emulator and GDB logs and the binary profile, suitable for tools/check-bartman-profile.cjs.