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>
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 systemarm-none-eabi-gdb). - GDB Server Port:
localhost:3333(configured in melonDS when GDB stub is enabled inmelonDS.ini). - ELF Symbol File:
snakePlus.elforbuild-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 at0x02fffd98. - 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,
$spis 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
- Launch melonDS with ROM:
melonDS snakePlus.nds - Attach GDB:
arm-none-eabi-gdb snakePlus.elf -ex "target remote localhost:3333" - Common GDB Actions:
- Set Breakpoint:
b update_frameorb source/game_input.cpp:50 - Continue Execution:
c - Step Instruction / Source:
step(ornext) - Read Memory / Registers:
info registers,x/16xw $sp - Detach Safely (keeps emulator running):
detach, thenquit
- Set Breakpoint: