Skip to main content

Debugging with GDB

Nintendo 3DS

To debug crashes in LÖVE Potion, you'll need to use gdb in combination with the Rosalina menu. Follow these steps to set up the debugger:

Step 1: Set Up the Rosalina Debugger

  1. Open the Rosalina Menu on the console and navigate to Debugger Options.
  2. Enable the Debugger and make note of the IP address for the system.
  3. Enable the option Force-debug next application at launch.
  4. Once these changes are made, exit the Rosalina menu completely.

Step 2: Prepare for Debugging

  1. Navigate the terminal to the working directory to where the compiled LÖVE Potion ELF binary is located. This is essential for loading the correct debug symbols.
cd path/to/build/directory

Step 3: Start gdb

  1. Run gdb by entering the following command in the terminal:
/opt/devkitpro/devkitARM/bin/arm-none-eabi-gdb
  1. Once gdb starts, load the ELF binary for LÖVE Potion by running:
file lovepotion.elf

Step 4: Connect to the Console

  1. Connect gdb to the console by running:
target remote {ip}:4003

Replace {ip} with the IP address from earlier (e.g., target remote 192.168.3.30:4003).

  1. After confirming the connection is established, run LÖVE Potion.

Step 5: Start Debugging

  1. In the gdb terminal, type the following to continue execution:
continue
  1. When the program hits an interrupt (e.g., a segfault), gdb will pause execution. At this point, type the following command to generate a backtrace:
backtrace
  1. gdb will output the backtrace in the terminal, showing you the stack frames leading to the crash. This information will help you diagnose the issue and identify the exact location in the code where the crash occurred.

Nintendo Switch

Step 1: Set Up atmosphère

  1. On the microSD card, create a file (or if it exists, modify it) called system_settings.ini under the /atmosphere/config directory. Add the following to the config file:
[atmosphere]
enable_htc = u8!0x0
enable_standalone_gdbstub = u8!0x1
  1. Reboot the console for this to take affect.

Step 2: Prepare for Debugging

  1. Navigate the terminal to the working directory to where the compiled LÖVE Potion ELF binary is located. This is essential for loading the correct debug symbols.
cd path/to/build/directory

Step 3: Start gdb

  1. Run gdb by entering the following command in the terminal:
/opt/devkitpro/devkitA64/bin/aarch64-none-elf-gdb

Step 4: Connect to the Console

  1. Connect gdb to the console by running:
target extended-remote {ip}:22225

Replace {ip} with the IP address of the console (e.g., target remote 192.168.3.30:22225).

  1. Find the hbloader process via info os processes.
  2. Attach to the process id found from the previous step.
  3. Run continue as attaching to the running process will pause.

Step 5: Start Debugging

  1. Run the LÖVE Potion binary on console.
  2. Load the ELF binary for LÖVE Potion by running:
share .
  1. Continue execution of the application with continue.
  2. When the program hits an interrupt (e.g., a segfault), gdb will pause execution. At this point, type the following command to generate a backtrace:
backtrace
  1. gdb will output the backtrace in the terminal, showing you the stack frames leading to the crash. This information will help you diagnose the issue and identify the exact location in the code where the crash occurred.

Useful GDB Commands

CommandPurposeUseWhy it's helpful
backtrace (or bt)Displays the call stack (function calls leading to the crash)backtrace or btShows the sequence of function calls that led to the crash, helping to pinpoint the issue.
bt fullDisplays the call stack along with local variables in each framebt fullProvides additional context by showing the local variables in each stack frame, aiding deeper diagnosis.
continue (or c)Resumes the program’s execution after a breakpoint or interruptcontinue or cContinues program execution until it encounters another breakpoint or crash.
listDisplays the source code around the current line or functionlistUseful for viewing the code at the current location of the crash.
info localsShows local variables in the current functioninfo localsAllows inspection of local variables to identify issues with the function’s state.
info registersDisplays the current state of CPU registersinfo registersProvides insight into the CPU state at the time of the crash.
frameSwitches to a specific stack frameframe <frame-number>Lets you navigate through the call stack to inspect individual function calls.
printPrints the value of a variable or expressionprint <variable-name> or print <expression>Helps to inspect the value of variables or evaluate expressions during debugging.
quitExits the gdb sessionquitCleanly exits the gdb session after finishing the debugging process.
break (or b)Sets a breakpoint at a specific line or functionbreak <function-name> or break <file-name>:<line-number>Stops execution at specific points in the code to inspect behavior or crashes.
step (or s)Steps into the next function call or line of codestep or sSteps into function calls to inspect their behavior during execution.
next (or n)Steps over the next function call (executes it without stepping in)next or nSkips over function calls, useful for moving through code without diving into functions.