rust-debugging

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Rust Debugging

Rust调试

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.
为开发者提供Rust程序调试指南:包括搭配Rust美化打印机使用GDB/LLDB、回溯配置、Panic问题排查、用tokio-console调试异步代码,以及
#[no_std]
代码的调试策略。

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?"
  • "如何使用GDB/LLDB调试Rust二进制文件?"
  • "如何从Rust Panic中获取完整的回溯信息?"
  • "如何调试异步Rust / Tokio代码?"
  • "Rust美化打印机在GDB中无法工作"
  • "如何在生产环境中调试Rust Panic?"
  • "如何在Rust中使用dbg!和tracing?"

Workflow

操作流程

1. Build for debugging

1. 为调试构建程序

bash
undefined
bash
undefined

Debug build (default) — full debug info, no optimization

Debug build (default) — full debug info, no optimization

cargo build
cargo build

Release with debug info (for profiling real workloads)

Release with debug info (for profiling real workloads)

cargo build --release --profile release-with-debug
cargo build --release --profile release-with-debug

Or configure in Cargo.toml:

Or configure in Cargo.toml:

[profile.release-with-debug]

[profile.release-with-debug]

inherits = "release"

inherits = "release"

debug = true

debug = true

Run directly

Run directly

cargo run cargo run -- arg1 arg2
undefined
cargo run cargo run -- arg1 arg2
undefined

2. GDB with Rust pretty-printers

2. 搭配Rust美化打印机使用GDB

bash
undefined
bash
undefined

Use rust-gdb wrapper (sets up pretty-printers automatically)

Use rust-gdb wrapper (sets up pretty-printers automatically)

rust-gdb target/debug/myapp
rust-gdb target/debug/myapp

Or set up manually in ~/.gdbinit:

Or set up manually in ~/.gdbinit:

python

python

import subprocess, sys

import subprocess, sys

...

...


Common GDB session for Rust:
```gdb

Rust程序的常见GDB会话:
```gdb

Basic

Basic

(gdb) break main (gdb) run arg1 arg2 (gdb) next # step over (gdb) step # step into (gdb) continue
(gdb) break main (gdb) run arg1 arg2 (gdb) next # step over (gdb) step # step into (gdb) continue

Rust-aware inspection

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
(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

Break on panic

(gdb) break rust_panic (gdb) break core::panicking::panic
(gdb) break rust_panic (gdb) break core::panicking::panic

Backtrace

Backtrace

(gdb) bt # Short backtrace (gdb) bt full # Full with locals
undefined
(gdb) bt # Short backtrace (gdb) bt full # Full with locals
undefined

3. LLDB with Rust pretty-printers

3. 搭配Rust美化打印机使用LLDB

bash
undefined
bash
undefined

Use rust-lldb wrapper

Use rust-lldb wrapper

rust-lldb target/debug/myapp
rust-lldb target/debug/myapp

Manual setup

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_commands

Common LLDB session:
```lldb
(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 threads
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_commands

Rust程序的常见LLDB会话:
```lldb
(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 threads

4. Backtrace configuration

4. 回溯配置

bash
undefined
bash
undefined

Short backtrace (default on panic)

Short backtrace (default on panic)

RUST_BACKTRACE=1 ./myapp
RUST_BACKTRACE=1 ./myapp

Full backtrace with all frames

Full backtrace with all frames

RUST_BACKTRACE=full ./myapp
RUST_BACKTRACE=full ./myapp

With symbols (requires debug build or separate debug info)

With symbols (requires debug build or separate debug info)

RUST_BACKTRACE=full ./target/debug/myapp
RUST_BACKTRACE=full ./target/debug/myapp

Capture backtrace programmatically

Capture backtrace programmatically

use std::backtrace::Backtrace; let bt = Backtrace::capture(); eprintln!("{bt}");

For release binaries, keep debug symbols in a separate file:
```bash
use std::backtrace::Backtrace; let bt = Backtrace::capture(); eprintln!("{bt}");

对于发布版二进制文件,将调试符号保存在单独文件中:
```bash

Build release with debug info

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/myapp
undefined
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/myapp
undefined

5. Panic triage

5. Panic问题排查

rust
// 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 messageLikely 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.
rust
// 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.
}));
常见Panic模式:
Panic消息可能原因
index out of bounds: the len is N but the index is M
数组/向量越界访问
called Option::unwrap() on a None value
对None调用unwrap
called Result::unwrap() on an Err value
对错误调用unwrap
attempt to subtract with overflow
整数下溢(调试构建)
assertion failed
assert!
assert_eq!
断言失败
stack overflow
无限递归
在发布版中设置
panic = "abort"
以生成崩溃转储而非展开调用栈。

6. The dbg! macro

6. dbg!宏的使用

rust
// 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();
rust
// 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

7. 使用tracing实现结构化日志

toml
[dependencies]
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
rust
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();
bash
undefined
toml
[dependencies]
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
rust
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();
bash
undefined

Control log levels at runtime

Control log levels at runtime

RUST_LOG=debug ./myapp RUST_LOG=myapp::module=trace,warn ./myapp
undefined
RUST_LOG=debug ./myapp RUST_LOG=myapp::module=trace,warn ./myapp
undefined

8. Async debugging with tokio-console

8. 用tokio-console调试异步代码

toml
[dependencies]
console-subscriber = "0.3"
tokio = { version = "1", features = ["full", "tracing"] }
rust
// In main
console_subscriber::init();
bash
undefined
toml
[dependencies]
console-subscriber = "0.3"
tokio = { version = "1", features = ["full", "tracing"] }
rust
// In main
console_subscriber::init();
bash
undefined

Install and run tokio-console

Install and run tokio-console

cargo install tokio-console tokio-console # Connects to running Rust process at port 6669

tokio-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](references/rust-gdb-pretty-printers.md).
cargo install tokio-console tokio-console # Connects to running Rust process at port 6669

tokio-console可展示:任务状态、唤醒器活动、阻塞任务、轮询时长。

关于GDB/LLDB命令参考和美化打印机设置,请参阅[references/rust-gdb-pretty-printers.md](references/rust-gdb-pretty-printers.md)。

Related skills

相关技能

  • Use
    skills/rust/rustc-basics
    for debug info flags and build configuration
  • Use
    skills/debuggers/gdb
    for GDB fundamentals
  • Use
    skills/debuggers/lldb
    for LLDB fundamentals
  • Use
    skills/rust/rust-sanitizers-miri
    for memory safety and undefined behaviour
  • 调试信息标志和构建配置请参考
    skills/rust/rustc-basics
  • GDB基础请参考
    skills/debuggers/gdb
  • LLDB基础请参考
    skills/debuggers/lldb
  • 内存安全与未定义行为请参考
    skills/rust/rust-sanitizers-miri