Skip to content

Debugging with GDB

Thanks to the hard work of Skitchin on http://psx.dev Discord, nops can act as a bridge between GDB and the PSX.

You are able to step through and debug commerical games, or your own code in the GDB or VSCode.

  • GDB connects to nops via sockets.
  • Nops connects to the PSX/Unirom via serial cable.

Note:

This is still an beta in-development feature, so be sure to swing by the Discord and let us know how you got on, or hurl some abuse at @Skitchin.


Installation

Download the nops + unirom beta package: https://github.com/johnbaumann/unirom.github.io/releases/download/8.0.Kish/nops.gdb_unirom_beta.zip

Other than, the nops/uni, you'll need a copy of gdb for your platform:

Windows:

Easiest to use Nicolas Noble's prebuilt windows GDB (mips) binaries: https://static.grumpycoder.net/pixel/gdb-multiarch-windows/
Remember to add e.g. c:\gdb-multiarch\bin to your %PATH% viable!

Linux/Mac:

Apt-get, brew, etc.


Example flow

Let's pretend we're developing a Hello World example, we'll be using a modern version of GCC. The following projects are suitable for building/testing/tweaking your own code. They all include docker images, so you can use Docker and run dockerrun.bat/dockerrun.sh, dockershell.bat/dockershell.sh, etc or your own GCC setup.

PCSX Redux's 'nugget' tool chain, there's loads of example code: https://github.com/grumpycoders/pcsx-redux/tree/main/src/mips

A basic bare-ish metal demo with pads/gpu etc using the same toolchain: https://github.com/JonathanDotCel/helloworld_and_flappycredits

1: Build your thing

Build your source and you'll generate an .elf and .exe file. The .elf is more suitable for debugging, though if your setup doesn't provide that, don't worry - you just won't have access to all of the symbols, line numbers, etc.

2: Launch nops

Launch nops, and tell it to listen for GDB on a specific port.:

Something like this depending on your OS, speed, port, etc...

  • nops /fast /gdb 127.0.0.1:3333 COM14 /m
  • nops /gdb 127.0.0.1:8888 /dev/tty.SLAB_USBtoUART

Note: Nops will handle putting unirom into /debug mode so you don't have to.

3: Launch GDB and Upload (commandline version)

Might be worth getting the hang of the basics before using the VSCode version:

A: In the terminal:

  • gdb ./helloworld.elf

B: (In GDB) Tell GDB where to find nops

  • target remote locahost:3333

C: Load it and transfer to the PSX:

  • load
  • (or load helloworld.elf if you forgot the filename in the first command)

The psx is now in a halted state with the program ready to run, but you can issue some commands before it starts. tbreak main for example will set a temporary breakpoint at your program's "main()"

D: Done, run it! continue

Further examples:

Ex: If you had a temporary breakpoint set, chances are it will immediately break on that. You could then do (for example)

  • layout asm
  • layout source

Ex: If you wanted to change the value at a particular address:

  • set {int}0x80010000 = 0

Ex: to check register values:

  • info regs

Ex: to check a value:

  • print main

Ex: to step to the next instruction:

  • stepi

And of course, to resume:

  • continue

Once again cheers to Skitchin for his hard work on this feature!

For a full list of available GDB commands: http://davis.lbl.gov/Manuals/GDB/gdb_34.html#SEC636

3: Launch GDB and Upload (via VSCode)

Create/modify the following vscode launch.json and put it here relative to your binary: .../yourproject/helloworld.elf <-- binary here .../yourproject/.vscode/launchjson <-- launch.json here

{

    "version": "0.2.0",
    "configurations": [
        {
            "type": "gdb",
            "request": "launch",
            "name": "(gdb) Launch My Hello World",
            "target": "./helloworld.elf",
            "gdbpath": "/usr/bin/gdb-multiarch",
            "windows": {
                "gdbpath": "C:/gdb-multiarch/bin/gdb.exe",
            },
            "cwd": "${workspaceRoot}",
            "autorun": [
                "target remote localhost:3333",
                "symbol-file ./helloworld.elf",
                "set substitute-path /project .",
                "load ./helloworld.elf",
                // this line for pcsx-redux only!
                "monitor reset halt",
                "tbreak main",
                "continue",
            ],
            "valuesFormatting": "parseText",
        }
    ]
}