Set the RUST_BACKTRACE environment variable to 1 before running your Rust binary to automatically include a full stack trace whenever a panic occurs. This provides the exact file, line number, and function call chain leading to the crash, which is essential for debugging complex logic errors.
For a quick one-off run, prefix your command with the variable assignment:
RUST_BACKTRACE=1 cargo run
If you need this behavior permanently for a specific project or environment, export it in your shell configuration (e.g., .bashrc or .zshrc) or set it within your CI/CD pipeline. For more detailed information, including inlined code snippets, set the variable to full:
RUST_BACKTRACE=full cargo run
Here is a practical example of a panic scenario and the resulting output difference:
fn main() {
let data = vec![1, 2, 3];
// This will panic because index 5 is out of bounds
println!("{}", data[5]);
}
Without RUST_BACKTRACE:
thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 5', src/main.rs:4:20
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
With RUST_BACKTRACE=1:
thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 5', src/main.rs:4:20
stack backtrace:
0: rust_begin_unwind
1: core::panicking::panic_fmt
2: core::panicking::panic_bounds_check
3: my_app::main
4: core::ops::function::FnOnce::call_once
...
The backtrace reveals the execution path, allowing you to see if the panic was triggered directly in main or propagated from a deeper helper function. Note that for the backtrace to be fully useful, you should compile with debug symbols (the default for cargo run), but if you are building a release binary, you must explicitly enable them using RUSTFLAGS="-C debuginfo=2" or by configuring profile.release.debug = true in your Cargo.toml. Without debug symbols, the backtrace will show function names but may lack precise line numbers.