💾 Archived View for nox.im › snippets › debugging-golang-with-vs-code captured on 2024-02-05 at 09:48:27. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-09-28)

-=-=-=-=-=-=-

Debugging Golang Applications With Visual Studio Code

The vast majority of debugging I've encountered recently is usually done with `printf`. Debuggers are either a forgotten craft or not appealing, but the benefits are so vast while usage is so easy that I find myself writing up a referencable snippet on this.

The average developer in 2022 uses Visual Studio Code. I'm going to exercise how to debug golang applications based on this environment. VS Code uses the Go delve[1] debugger, short dlv. This is just good to know but VS Code hides even this fact from you, so you can get debugging utility just from a few clicks in the UI.

1: delve

Setup the development environment

Pressing F5 or Run -> Start Debugging the first time in a project will ask you to create a `launch.json` file.

VS Code Start Debuggingg Go[1]

1: VS Code Start Debuggingg Go

We create `.vscode/launch.json`:

{
    "version": "0.2.0",
    "configurations": [

        {
            "name": "Launch Package",
            "type": "go",
            "request": "launch",
            "mode": "auto",
            "showLog": true,
            "program": "${workspaceFolder}",
        }
    ]
}

If our project uses dotenv (a `.env` file with environment variables) abiding the 12 factor app methodology[1], you can inform VS Code to source these variables into the debug environment by adding:

1: 12 factor app methodology

{
    // ...
    "configurations": [
        {
            // ...
            "envFile": "${workspaceFolder}/.env"
        }
    ]
}

Your dotenv file probably looks something like this:

SERVICE_ADDRESS=:8082
CLUSTER_RPC_URL=http://localhost:8899
CLUSTER_WEBSOCKET_URL=ws://localhost:8900
# ...

If the application requires command line arguments, such as for example sqliteviz[1], add them like so:

1: sqliteviz

{
    // ...
    "configurations": [
        {
            // ...
            "args": ["-db", "chinook.db", "-ignore", "schema_migrations,sqlite_stat1"]
        }
    ]
}

Setting breakpoints

Set a breakpoint and run the app in mode "test" or "auto" mode and wait for your breakpoint to hit and while the program is paused, we have a full view of stack variables available:

VS Code Go Debugging Breakpoint[1]

1: VS Code Go Debugging Breakpoint

Should your app segfault, you will get interactive call stacks:

VS Code Go segfault[1]

1: VS Code Go segfault

If the application deadlocks, we can see where we try to acquire a semaphore and the call stack leading up to the deadlock.

It's that easy. For a deeper dive see golang/vscode-go/docs/debugging.md[1].

1: golang/vscode-go/docs/debugging.md