How to use
- Copy the installation command and review the source package before installing it in your own agent environment.
- Check the source document for required tools, credentials and supported hosts.
- Describe your input and desired deliverable; review the output against the source material.
npx skills add https://github.com/mohitmishra786/low-level-dev-skills --skill rust-debuggingBefore you start
- Installation does not include a model subscription, API allowance or permission to access your files.
- Repository stars and installation counts describe activity, not an independent quality or security test.
Rendered from the source repository. Headings, examples, code, tables, links, and referenced images are preserved.
Rust Debugging
Purpose
Guide agents through debugging Rust programs: GDB/LLDB with Rust pretty-printers, backtrace configuration, panic triage, async debugging with tokio-console, and #[no_std] debugging strategies.
Triggers
- "How do I use GDB/LLDB to debug a Rust binary?"
- "How do I get a full backtrace from a Rust panic?"
- "How do I debug async Rust / Tokio?"
- "Rust pretty-printers aren't working in GDB"
- "How do I debug a Rust panic in production?"
- "How do I use dbg! and tracing in Rust?"
Workflow
1. Build for debugging
# Debug build (default) — full debug info, no optimization
cargo build
# Release with debug info (for profiling real workloads)
cargo build --release --profile release-with-debug
# Or configure in Cargo.toml:
# [profile.release-with-debug]
# inherits = "release"
# debug = true
# Run directly
cargo run
cargo run -- arg1 arg22. GDB with Rust pretty-printers
# Use rust-gdb wrapper (sets up pretty-printers automatically)
rust-gdb target/debug/myapp
# Or set up manually in ~/.gdbinit:
# python
# import subprocess, sys
# ...Common GDB session for Rust:
# Basic
(gdb) break main
(gdb) run arg1 arg2
(gdb) next # step over
(gdb) step # step into
(gdb) continue
# Rust-aware inspection
(gdb) print my_string # Shows String content via pretty-printer
(gdb) print my_vec # Shows Vec elements
(gdb) print my_option # Shows Some(value) or None
(gdb) info locals
# Break on panic
(gdb) break rust_panic
(gdb) break core::panicking::panic
# Backtrace
(gdb) bt # Short backtrace
(gdb) bt full # Full with locals3. LLDB with Rust pretty-printers
# Use rust-lldb wrapper
rust-lldb target/debug/myapp
# Manual setup
lldb target/debug/myapp
(lldb) command script import /path/to/rust/lib/rustlib/etc/lldb_lookup.py
(lldb) command source /path/to/rust/lib/rustlib/etc/lldb_commandsCommon LLDB session:
(lldb) b main::main
(lldb) r arg1 arg2
(lldb) n # next (step over)
(lldb) s # step into
(lldb) c # continue
(lldb) frame variable # show locals
(lldb) p my_string # print variable with pretty-printer
(lldb) bt # backtrace
(lldb) bt all # all threads4. Backtrace configuration
# Short backtrace (default on panic)
RUST_BACKTRACE=1 ./myapp
# Full backtrace with all frames
RUST_BACKTRACE=full ./myapp
# With symbols (requires debug build or separate debug info)
RUST_BACKTRACE=full ./target/debug/myapp
# Capture backtrace programmatically
use std::backtrace::Backtrace;
let bt = Backtrace::capture();
eprintln!("{bt}");For release binaries, keep debug symbols in a separate file:
# Build release with debug info
cargo build --release
objcopy --only-keep-debug target/release/myapp target/release/myapp.debug
strip --strip-debug target/release/myapp
objcopy --add-gnu-debuglink=target/release/myapp.debug target/release/myapp5. Panic triage
// Set a custom panic hook for structured logging
use std::panic;
panic::set_hook(Box::new(|info| {
let backtrace = std::backtrace::Backtrace::force_capture();
eprintln!("PANIC: {info}");
eprintln!("{backtrace}");
// Log to file, send to Sentry, etc.
}));Common panic patterns:
| Panic message | Likely cause |
|---|---|
index out of bounds: the len is N but the index is M | Array/vec OOB access |
called Option::unwrap() on a None value | Unwrap on None |
called Result::unwrap() on an Err value | Unwrap on error |
attempt to subtract with overflow | Integer underflow (debug build) |
assertion failed | Failed assert! or assert_eq! |
stack overflow | Infinite recursion |
Use panic = "abort" in release to get a crash dump instead of unwind.
6. The dbg! macro
// dbg! prints file, line, value and returns the value
let result = dbg!(some_computation(x));
// prints: [src/main.rs:15] some_computation(x) = 42
// Chain multiple values
let (a, b) = dbg!((compute_a(), compute_b()));
// Inspect inside iterator chains
let sum: i32 = (0..10)
.filter(|x| dbg!(x % 2 == 0))
.map(|x| dbg!(x * x))
.sum();7. Structured logging with tracing
[dependencies]
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }use tracing::{debug, error, info, instrument, warn};
#[instrument] // Auto-traces function entry/exit with arguments
fn process(id: u64, data: &str) -> Result<(), Error> {
debug!("Processing item");
info!(item_id = id, "Started processing");
if data.is_empty() {
warn!(item_id = id, "Empty data");
return Err(Error::EmptyData);
}
error!(item_id = id, err = ?some_result, "Failed");
Ok(())
}
// Initialize in main
tracing_subscriber::fmt()
.with_env_filter("myapp=debug,warn")
.init();# Control log levels at runtime
RUST_LOG=debug ./myapp
RUST_LOG=myapp::module=trace,warn ./myapp8. Async debugging with tokio-console
[dependencies]
console-subscriber = "0.3"
tokio = { version = "1", features = ["full", "tracing"] }// In main
console_subscriber::init();# Install and run tokio-console
cargo install tokio-console
tokio-console # Connects to running Rust process at port 6669tokio-console shows: task states, waker activity, blocked tasks, poll durations.
For GDB/LLDB command reference and pretty-printer setup, see references/rust-gdb-pretty-printers.md.
Related skills
- Use
skills/rust/rustc-basicsfor debug info flags and build configuration - Use
skills/debuggers/gdbfor GDB fundamentals - Use
skills/debuggers/lldbfor LLDB fundamentals - Use
skills/rust/rust-sanitizers-mirifor memory safety and undefined behaviour





