Skip to content

Debug Rust with Bugsaur

Adapter: codelldb

Install the adapter

Install CodeLLDB and make sure the binary is on PATH:

command -v codelldb

If it came from Mason:

export PATH="$HOME/.local/share/nvim/mason/bin:$PATH"

Configure

bugsaur init detects the project by Cargo.toml and writes one profile per binary — every [[bin]] in the manifest, or the package's src/main.rs. Libraries get no profile: there is nothing to launch.

A single binary

app/
├── Cargo.toml       [package] name = "app"
├── src/main.rs
└── .env
version = 1
default = "app"

[profiles.app]
adapter = "codelldb"
program = "target/debug/app"

The working directory is the package root, not target/debug where the artifact lives — the same as what cargo run from the root gives you.

A workspace

workspace/
├── Cargo.toml       members = ["crates/*"]
└── crates/
    ├── cli/src/main.rs
    ├── daemon/src/main.rs
    └── core/src/lib.rs   ← a library, no profile
version = 1
default = "cli"

[profiles.cli]
adapter = "codelldb"
program = "target/debug/cli"

[profiles.daemon]
adapter = "codelldb"
program = "target/debug/daemon"

The root is the workspace root: that is where target/ is, and where cargo run -p daemon works from.

Build before you launch

Bugsaur does not build Rust for you

program points at a build artifact. If it is not there, the launch fails with program is not readable.

cargo build && bugsaur gui --project . --break src/main.rs:10

Rust is the only one of the four languages where program is neither a source file nor a directory. Go is built by Bugsaur itself; Python and PHP have nothing to compile.

Debug a binary

cargo build
bugsaur gui --project . --profile cli --break src/main.rs:15

Debug cargo test

Use the test-under-cursor flow rather than writing a profile: put the cursor on a test and run :DebugTest in Neovim, or pass the location directly:

bugsaur gui --project . --test-at src/lib.rs:42

Bugsaur builds the tests with cargo test --no-run --message-format=json, picks the resulting test binary and debugs that. Everything else — adapter, environment, working directory — is inherited from the profile; only the program and its arguments are replaced.

Full recipe: Guides → Debug cargo test.

Two things specific to Rust

Release builds have no useful debug info

A binary built with --release is optimised: variables are missing, frames are inlined away and breakpoints land in surprising places. Debug the debug build.

cargo run sets variables that a direct launch does not

cargo run puts part of CARGO_* into the process environment. Code that reads those at runtime behaves differently under the debugger, which launches the binary directly. Add what you need explicitly:

env = { CARGO_MANIFEST_DIR = "${root}" }

A workspace member with its own .env

The root is the workspace root, so crates/api/.env is not picked up on its own:

[profiles.api]
adapter = "codelldb"
program = "target/debug/api"
env_file = "crates/api/.env"

Diagnostics

Symptom Likely cause Where to look
program is not readable the binary is not built run cargo build
Session never starts codelldb not on PATH Adapter fails to start
Stops, but no variables release build, or a frame without debug info Variables
Breakpoint never hit non-executable line, or code that never runs Breakpoints not hit
Wrong source shown paths disagree Source not found