debugger-cli
A command-line debugger built for LLM coding agents
debugger-cli is a cross-platform debugging tool that enables LLM coding agents (and humans!) to debug executables using the Debug Adapter Protocol (DAP). It provides a simple, scriptable CLI interface that maintains persistent debug sessions across multiple command invocations.
Why This Exists
LLM agents need to debug programs interactively, but CLI commands are ephemeral. Traditional debuggers require an interactive session that's incompatible with agent workflows. This tool solves that by:
- Maintaining persistent sessions: A background daemon keeps the debug session alive between commands
- Buffering events: Output, breakpoint hits, and stop events are captured even when no client is connected
- Providing a unified interface: Works with any DAP adapter (lldb-dap, CodeLLDB, debugpy, Delve, etc.)
- Being LLM-friendly: Clear, parseable output optimized for agent consumption
Features
- Multi-language support: Debug C, C++, Rust, Python, Go, and more
- Zero-friction setup:
debugger setup lldbinstalls everything you need - Full breakpoint control: Line, function, and conditional breakpoints
- Rich inspection: Variables, expressions, stack traces, and source context
- Thread management: List, switch, and navigate threads and stack frames
- Structured output: JSON-friendly for agent consumption
- Cross-platform: Linux, macOS, and Windows support
Quick Start
Installation
# Install from crates.io cargo install debugger-cli # Install a debug adapter (e.g., lldb for C/C++/Rust) debugger setup lldb
Or build from source:
git clone https://github.com/akiselev/debugger-cli.git cd debugger-cli cargo install --path .
Prerequisites
You need a DAP-compatible debug adapter. The easiest way is:
# List available debuggers debugger setup --list # Install for your language debugger setup lldb # C, C++, Rust, Swift debugger setup python # Python (debugpy) debugger setup go # Go (Delve) debugger setup gdb # C, C++ (requires GDB 14.1+) debugger setup cuda-gdb # CUDA (Linux only)
Or install manually:
- Arch Linux:
sudo pacman -S lldb - Ubuntu/Debian:
sudo apt install lldb - macOS:
xcode-select --install(includes lldb)
Basic Usage
# Start debugging a program debugger start ./myprogram # Set a breakpoint debugger break main.c:42 # or debugger breakpoint add my_function # Run until breakpoint debugger continue # Wait for the program to stop debugger await # Inspect current state debugger context # Source code + variables debugger locals # Local variables debugger backtrace # Stack trace debugger print myvar # Evaluate expression # Step through code debugger next # Step over debugger step # Step into debugger finish # Step out # Clean up debugger stop
Commands Reference
Session Management
| Command | Aliases | Description |
|---|---|---|
start <program> [-- args] |
Start debugging a program | |
attach <pid> |
Attach to running process | |
stop |
Stop debug session and terminate debuggee | |
detach |
Detach from process (keeps it running) | |
status |
Show daemon and session status | |
restart |
Restart program with same arguments |
Start options:
--adapter <name>- Use specific debug adapter--stop-on-entry- Stop at program entry point--break <location>/-b- Set initial breakpoint(s) before program starts
Breakpoints
| Command | Aliases | Description |
|---|---|---|
breakpoint add <location> |
break, b |
Add breakpoint (file:line or function) |
breakpoint remove <id> |
Remove breakpoint by ID | |
breakpoint remove --all |
Remove all breakpoints | |
breakpoint list |
List all breakpoints |
Breakpoint options:
--condition <expr>- Break only when expression is true--hit-count <n>- Break after N hits
Execution Control
| Command | Aliases | Description |
|---|---|---|
continue |
c |
Resume execution |
next |
n |
Step over (execute current line) |
step |
s |
Step into (enter function calls) |
finish |
out |
Step out (run until function returns) |
pause |
Pause execution | |
await |
Wait for next stop event |
Inspection
| Command | Aliases | Description |
|---|---|---|
context |
where |
Show source + variables at current position |
locals |
Show local variables | |
backtrace |
bt |
Show stack trace |
print <expr> |
p |
Evaluate expression |
eval <expr> |
Evaluate with side effects | |
threads |
List all threads |
Navigation
| Command | Description |
|---|---|
thread <id> |
Switch to thread |
frame <n> |
Navigate to stack frame |
up |
Move up the stack (to caller) |
down |
Move down the stack |
Program Output
| Command | Description |
|---|---|
output |
Get program stdout/stderr |
output --follow |
Stream output continuously |
output --tail <n> |
Get last N lines |
Setup
| Command | Description |
|---|---|
setup <debugger> |
Install a debug adapter |
setup --list |
List available debuggers |
setup --check |
Check installed debuggers |
setup --auto |
Auto-install for detected project |
Architecture
┌─────────────────┐ IPC Socket ┌─────────────────┐ stdio (DAP) ┌─────────────────┐
│ CLI Mode │◄──────────────────►│ Daemon Mode │◄──────────────────►│ DAP Adapter │
│ (user facing) │ │ (background) │ │ (lldb-dap) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
The tool runs as a single binary in two modes:
- CLI Mode (thin client): Parses commands, connects to daemon via IPC, displays results
- Daemon Mode (background): Manages the debug session, communicates with the DAP adapter, buffers events
This architecture allows:
- Persistent debug sessions across multiple CLI invocations
- Event buffering when no client is connected
- Non-blocking command execution
- Clean process lifecycle management
Configuration
Configuration is stored in ~/.config/debugger-cli/config.toml:
# Default debug adapter adapter = "lldb-dap" # Request timeout in seconds timeout = 30 # Custom adapter paths [adapters] lldb-dap = "/usr/bin/lldb-dap" codelldb = "~/.local/share/debugger-cli/adapters/codelldb/adapter/codelldb"
Supported Debug Adapters
| Adapter | Languages | Status |
|---|---|---|
| lldb-dap | C, C++, Rust, Swift | ✅ Full support |
| debugpy | Python | ✅ Full support |
| Delve | Go | ✅ Full support |
| GDB | C, C++ | ✅ Full support (requires GDB 14.1+) |
| CUDA-GDB | CUDA, C, C++ | ✅ Full support (Linux only) |
| js-debug | JavaScript, TypeScript | ✅ Full support |
| CodeLLDB | C, C++, Rust | 🚧 Planned |
| cpptools | C, C++ | 🚧 Planned |
Examples
Debugging a Rust Program
# Build with debug info cargo build # Start debugging with initial breakpoint debugger start ./target/debug/myprogram --break main # Run to breakpoint debugger continue debugger await # Inspect state debugger context # Thread 1 stopped at src/main.rs:15 # # 13 | let config = Config::load()?; # 14 | let processor = Processor::new(config); # -> 15 | processor.run()?; # # Locals: # config: Config { max_threads: 4, timeout: 30 } # Evaluate expressions debugger print config.max_threads # 4 # Step through code debugger step debugger await # Clean up debugger stop
Debugging a Go Program
# Build with debug info go build -gcflags="all=-N -l" -o myprogram # Start debugging debugger start ./myprogram --adapter go --break main.main # Continue to breakpoint debugger continue debugger await # Inspect goroutines debugger threads # View locals debugger locals # Clean up debugger stop
Debugging CUDA Code (Linux)
# Compile with debug info nvcc -g -G -o cuda_program kernel.cu # Start debugging (uses cuda-gdb) debugger start ./cuda_program --adapter cuda-gdb --break main # Set kernel breakpoint debugger break vectorAdd # Run to kernel debugger continue debugger await # View CUDA threads debugger threads debugger stop
Development
See docs/DEVELOPMENT.md for the developer guide, including:
- Architecture deep-dive
- Adding new commands
- Working with the DAP client
- Testing and debugging tips
License
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit issues and pull requests.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request