Files
phillipandAntigravity f4c77b32d1 refactor: extract melonDS GDB debugging procedures into melonds-gdb-debugger skill
Create the workspace skill .agents/skills/melonds-gdb-debugger/ with
SKILL.md and diagnose_melonds.sh diagnostic automation script.
Streamline AGENTS.md to link to the new skill to keep it short and concise.

Co-authored-by: Antigravity <antigravity@google.com>
2026-10-04 00:36:22 +02:00

3.6 KiB

name, description
name description
melonds-gdb-debugger Attach to and debug Nintendo DS homebrew applications running in melonDS using arm-none-eabi-gdb. Use when diagnosing crashes, freezes, infinite loops, data aborts (__arm_excpt_dabt, __excpt_entry), stack corruption, or setting breakpoints and inspecting registers/memory on the ARM9 target.

melonDS GDB Debugger Access & Diagnostics

This skill provides step-by-step procedures and recipes for debugging Nintendo DS homebrew applications running inside the melonDS emulator using arm-none-eabi-gdb.


1. Prerequisites & Target Setup

  • Toolchain GDB: ${DEVKITPRO}/devkitARM/bin/arm-none-eabi-gdb (or system arm-none-eabi-gdb).
  • GDB Server Port: localhost:3333 (configured in melonDS when GDB stub is enabled in melonDS.ini).
  • ELF Symbol File: snakePlus.elf or build-debug/snakePlus.elf.

2. Quick Connection & Non-Interactive Inspection

To inspect a running or frozen melonDS instance without an interactive prompt:

arm-none-eabi-gdb snakePlus.elf --batch \
  -ex "target remote localhost:3333" \
  -ex "info registers" \
  -ex "detach" \
  -ex "quit"

To run a diagnosis using the bundled helper script:

bash .agents/skills/melonds-gdb-debugger/scripts/diagnose_melonds.sh snakePlus.elf

3. Diagnosing Crashes, Freezes & Data Aborts

3.1 Exception Vectors in Calico / devkitARM

When an unhandled ARM exception occurs, the hardware branches to vector handlers in ROM/BIOS or Calico runtime:

  • 0x01ff8560 (__arm_excpt_dabt): Data Abort exception handler.
  • 0x01ff8594 (__excpt_entry): Common exception entry point executing an infinite loop (b .).
  • 0x01ff84ec (armWaitForIrq + 4): Low-power halt state while waiting for VBlank or Timer IRQ. Normal running state.

If melonDS freezes, appears unresponsive, or outputs attempt to restore CPSR under bad mode, attach GDB and inspect $pc. If $pc is at 0x01ff8594, the CPU hit a fatal exception.

3.2 Extracting the Faulted Instruction & SPSR

In Calico's __excpt_entry, the exception frame is pushed to memory at 0x02fffd80:

  • Faulted PC (lr_abt - 8): Stored at 0x02fffd98.
  • Faulted SPSR: Stored at 0x02fffd90.

Run the following commands in GDB to identify the offending source line:

(gdb) target remote localhost:3333
(gdb) x/x 0x02fffd98
0x2fffd98:      0x02004284
(gdb) info line *0x02004284
Line 123 of "/path/to/source/game_input.cpp" starts at address 0x2004280 ...

3.3 Diagnosing Stack Overflows & Stack Smash

In calico/lib/ds9.ld, the ARM9 IRQ stack has a total budget of only 256 bytes (__sp_irq = __sp_usr + 0x100), growing downward into user stack (__sp_usr).

  • If an interrupt handler (such as handle_vblank) calls deep functions or formatting routines (iprintf), it clobbers __sp_usr.
  • Symptom: In GDB, $sp is corrupt or misaligned (e.g. sp = 0x02fffd8f, with bit 0 set), or functions crash immediately on register restore / return (ldmia sp!).

4. Interactive Debugging Session

  1. Launch melonDS with ROM:
    melonDS snakePlus.nds
    
  2. Attach GDB:
    arm-none-eabi-gdb snakePlus.elf -ex "target remote localhost:3333"
    
  3. Common GDB Actions:
    • Set Breakpoint: b update_frame or b source/game_input.cpp:50
    • Continue Execution: c
    • Step Instruction / Source: step (or next)
    • Read Memory / Registers: info registers, x/16xw $sp
    • Detach Safely (keeps emulator running): detach, then quit