3 Debugging with LLDB
SonicSwordcane edited this page 2025-01-19 22:57:44 +00:00

Debugging with LLDB

Lemur can be used as a server for the gdb/lldb debuggers. If you're a homebrew developer, this gives you a rich source-level debugging experience for your C, C++, Rust, or assembly games. If you're reverse-engineering commercial games, it does a passable job at debugging ROMs without source code.

Setup

Setting up LLDB

To debug Virtual Boy games, you need a version of gdb or lldb built to target the Virtual Boy. The llvm-v810 compiler comes with a working version of lldb. At this time, there is no compatible version of gdb, so just use lldb.

  1. Download the latest llvm-v810 compiler for your OS (Windows, Darwin/Mac, or Linux). The download link is under "Assets".
    • For Windows, download llvm-v810-windows-main.7z from the assets of a release with "Windows" in the name.
    • For Mac, download llvm-v810-darwin-main.tar.xz from the assets of a release with "Darwin" in the name.
    • For Linux, download llvm-v810-linux-main.tar.xz from the assets of a release with "Linux" in the name.
  2. Extract the files.
    • For command-line debugging, you'll need the lldb executable from llvm-v810/bin/lldb (or llvm-v810/bin/lldb.exe on Windows).
    • For IDE integration, you'll need the lldb-dap executable from llvm-v810/bin/lldb-dap (or llvm-v810/bin/lldb-dap.exe on Windows).

Compiling with debug info

To use source-level debugging, you must compile debug info into your game. To do this, simply add -g to your CFLAGS.

The -g flag is supported in

Note that VUEngine Studio uses an older version of v810-gcc, so source-level debugging doesn't work for VUEngine games. This will be fixed Eventually™️.

This debug info will be added to your game's .elf file, but stripped from the final .vb file. This means compiling with -g won't make your ROM bigger or slower.

Running the server

To run the server, you can go to "Tools > GDB Server" and click Start. It will run on port 8080 by default. You can also pass --debug-port 8080 on the command line, to run the server as soon as the app starts. Your game will be paused until the debugger connects.

Command-line debugging with lldb

You can use lldb as a command-line tool. To do this, pass your game's .elf file to lldb, and tell it to connect to Lemur on startup:

lldb /path/to/your/game.elf -o "process connect connect://127.0.0.1:8080"

You can also run lldb without an .elf file, but it'll be missing a lot of features (like variable inspection and call stack visualization) if you do.

lldb -o "process connect connect://127.0.0.1:8080"

At this point you can debug your game like any program. See this lldb tutorial for some examples of what you can do.

VSCode integration with lldb-dap

If your IDE has a debugger, lldb-dap lets you use it to debug your Virtual Boy game. The below instructions are for VSCode, but this will work for almost any IDE (except VUEngine Studio).

  1. Download the LLDB DAP extension.
  2. Configure the extension to use the lldb-dap you downloaded earlier. Add this to your .vscode/settings.json:
{
    "lldb-dap.executable-path": "/path/to/llvm-v810/bin/lldb-dap"
}
  1. Add a launch configuration to your project. Add this to .vscode/launch.json:
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Debug",
            "type": "lldb-dap",
            "request": "launch",
            "program": "${workspaceFolder}/mygame.elf", // path to your .elf file
            "launchCommands": ["gdb-remote 8080"], // replace 8080 with whichever port your server uses
            "preLaunchTask": "Emulate" // see step 4
        }
    ]
}
  1. When you click the "Debug" button, you probably want to launch the emulator with your game. Set up a task to do this. Add this to .vscode/tasks.json:
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Emulate",
            "type": "shell",
            "command": "/path/to/lemur",
            "args": [
                "${workspaceFolder}/mygame.vb", // path to your rom
                "--debug-port",
                "8080"
            ],
            "isBackground": true,
            "problemMatcher": {
                "pattern": {
                    "regexp": ""
                },
                "background": {
                    "activeOnStart": true,
                    "beginsPattern": "Connecting",
                    "endsPattern": "Connecting"
                }
            }
        }
    ]
}

If you're feeling spicy, you can add a "Compile" task which this "Emulate" task depends on, so that clicking "Debug" is all you need to do to start debugging.

Happy debugging!