Profiles¶
A profile describes one debuggable thing: which adapter, which program, and how to launch it. A project has as many profiles as it has parts worth debugging.
version = 1
default = "api"
[profiles.api]
adapter = "dlv"
program = "cmd/api"
[profiles.worker]
adapter = "dlv"
program = "cmd/worker"
Profile fields¶
| Field | Required | What it is |
|---|---|---|
adapter |
yes | id from the adapter catalog: dlv, codelldb, debugpy, php |
program |
yes | what to debug; a relative path resolves from the root |
adapter_command |
no | overrides the adapter's command — it may live in vendor/ rather than on PATH |
cwd |
no | working directory; defaults to the project root |
args |
no | the debuggee's command-line arguments |
env_file |
no | file of environment variables; path relative to the root |
env |
no | environment variables; override both env_file and inherited ones |
launch_timeout |
no | seconds for the startup handshake (launch / attach and configurationDone); default 120 |
mode |
no | launch (default) or attach |
build |
no | how to build the program; overrides the adapter catalog's build |
launch_arguments |
no | the DAP body as-is, on top of the adapter's defaults |
What program means differs by language¶
| Language | program is |
|---|---|
| Rust, C/C++ | a compiled binary — build it yourself first |
| Go | a package directory |
| Python | a script |
| PHP | the project directory |
Choosing a profile¶
default— what runs when no name is given.:DebugStart workerin Neovim, with Tab completion of names from the config.bugsaur run --project . --profile workerin a terminal.
With a single profile, default is unnecessary. With several and no default,
the launch stops and lists what is available rather than picking one for you.
When a config is generated, default is set to the profile whose file you first
started debugging from. After that it is an ordinary value in the file, edited
by hand.
Building before launch¶
For adapters the catalog knows how to build — Go, in practice — Bugsaur builds
the program itself, in a building phase, before the adapter starts, and hands
the adapter a finished binary.
The result goes to <root>/.bugsaur/build/<program name>. The key is the
program, not the profile, so two profiles for one binary reuse a single build.
Override the build per profile:
[profiles.worker]
adapter = "dlv"
program = "cmd/worker"
[profiles.worker.build]
command = "go"
args = ["build", "-tags=dev", "-gcflags=all=-N -l", "-o", "{out}", "./cmd/worker"]
command and args are separate rather than one string: -gcflags=all=-N -l
has a space inside one argument, and parsing a string would need quoting rules
exactly where a mistake quietly breaks debug information. {out} is the binary
being built; {program} is what program names.
No build happens in attach mode, for adapters with no build in the
catalog, or when the profile names mode or program to the adapter itself in
launch_arguments — that means the launch is being driven by hand.
If the build fails, the session goes to failed with the compiler's text and
the adapter is never started.
Launch timeout¶
The startup handshake — launch / attach and configurationDone — is waited
on for 120 seconds by default. Some adapters build inside launch; others
finish launching after configurationDone and answer both requests together.
Precedence: profile → adapter catalog → 120 seconds. Other requests — such
as threads and evaluate — are unaffected: a slow evaluate is a sign of a
bug, not of a big project.
While waiting, a long request is noted in the Logs panel every 30 seconds, with the pid holding the answer and how long remains. See Logs and Diagnostics.
When not to raise the timeout
If the build is always slow, take it out of the session: build ahead of time
and hand the adapter a finished binary. For Go that is
mode = "exec" — see Languages → Go.
The escape hatch: launch_arguments¶
launch_arguments is passed to the adapter as-is, on top of the catalog's
defaults and on top of everything Bugsaur generated — including program,
cwd, args and env. A key is replaced entirely, not merged: write env
there and that is what goes, not a union with env_file.
This is how to express something the profile schema has no field for. If you find yourself using it routinely, the schema is probably missing a field.