rust-sanitizers-miri
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseRust Sanitizers and Miri
Rust Sanitizers 和 Miri
Purpose
用途
Guide agents through runtime safety validation for Rust: ASan/TSan/MSan/UBSan via RUSTFLAGS, Miri for compile-time UB detection in unsafe code, and interpreting sanitizer reports.
指导开发者通过Rust进行运行时安全验证:通过RUSTFLAGS使用ASan/TSan/MSan/UBSan,使用Miri检测不安全代码中的编译期未定义行为,以及解读Sanitizer报告。
Triggers
触发场景
- "How do I run AddressSanitizer on Rust code?"
- "How do I use Miri to check my unsafe Rust?"
- "How do I run ThreadSanitizer on a Rust program?"
- "My unsafe Rust might have UB — how do I detect it?"
- "How do I interpret a Rust ASan report?"
- "Can I run Rust sanitizers on stable?"
- "如何在Rust代码上运行AddressSanitizer?"
- "如何使用Miri检查我的不安全Rust代码?"
- "如何在Rust程序上运行ThreadSanitizer?"
- "我的不安全Rust代码可能存在UB,该如何检测?"
- "如何解读Rust ASan的输出报告?"
- "能否在稳定版Rust中运行Sanitizers?"
Workflow
操作流程
1. Sanitizers in Rust (nightly required)
1. Rust中的Sanitizers(需使用nightly版本)
Rust sanitizers require nightly and a compatible platform:
bash
undefinedRust Sanitizers需要nightly版本和兼容的平台:
bash
undefinedInstall nightly
安装nightly版本
rustup toolchain install nightly
rustup component add rust-src --toolchain nightly
rustup toolchain install nightly
rustup component add rust-src --toolchain nightly
AddressSanitizer (Linux, macOS)
AddressSanitizer(Linux、macOS)
RUSTFLAGS="-Z sanitizer=address"
cargo +nightly test -Zbuild-std
--target x86_64-unknown-linux-gnu
cargo +nightly test -Zbuild-std
--target x86_64-unknown-linux-gnu
RUSTFLAGS="-Z sanitizer=address"
cargo +nightly test -Zbuild-std
--target x86_64-unknown-linux-gnu
cargo +nightly test -Zbuild-std
--target x86_64-unknown-linux-gnu
ThreadSanitizer (Linux)
ThreadSanitizer(Linux)
RUSTFLAGS="-Z sanitizer=thread"
cargo +nightly test -Zbuild-std
--target x86_64-unknown-linux-gnu
cargo +nightly test -Zbuild-std
--target x86_64-unknown-linux-gnu
RUSTFLAGS="-Z sanitizer=thread"
cargo +nightly test -Zbuild-std
--target x86_64-unknown-linux-gnu
cargo +nightly test -Zbuild-std
--target x86_64-unknown-linux-gnu
MemorySanitizer (Linux, requires all-instrumented build)
MemorySanitizer(Linux,需要全 instrumentation 构建)
RUSTFLAGS="-Z sanitizer=memory -Zsanitizer-memory-track-origins"
cargo +nightly test -Zbuild-std
--target x86_64-unknown-linux-gnu
cargo +nightly test -Zbuild-std
--target x86_64-unknown-linux-gnu
RUSTFLAGS="-Z sanitizer=memory -Zsanitizer-memory-track-origins"
cargo +nightly test -Zbuild-std
--target x86_64-unknown-linux-gnu
cargo +nightly test -Zbuild-std
--target x86_64-unknown-linux-gnu
UndefinedBehaviorSanitizer
UndefinedBehaviorSanitizer
RUSTFLAGS="-Z sanitizer=undefined"
cargo +nightly test -Zbuild-std
--target x86_64-unknown-linux-gnu
cargo +nightly test -Zbuild-std
--target x86_64-unknown-linux-gnu
`-Zbuild-std` rebuilds the standard library with the sanitizer, which is necessary for accurate results.RUSTFLAGS="-Z sanitizer=undefined"
cargo +nightly test -Zbuild-std
--target x86_64-unknown-linux-gnu
cargo +nightly test -Zbuild-std
--target x86_64-unknown-linux-gnu
`-Zbuild-std`会使用Sanitizer重新构建标准库,这是获得准确结果的必要步骤。2. Stable sanitizer workaround
2. 稳定版Rust使用Sanitizer的替代方案
For stable Rust, use the tool with a Docker image that has sanitizers pre-configured, or run inside a Docker container with a nightly image.
crosscargo testAlternatively, for simpler UB checking without nightly:
bash
undefined对于稳定版Rust,可以使用工具搭配预配置了Sanitizers的Docker镜像,或者在装有nightly版本的Docker容器中运行。
crosscargo test另外,若无需nightly版本进行简单的UB检查,可使用:
bash
undefinedcargo-sanitize (wrapper)
cargo-sanitize(封装工具)
cargo install cargo-sanitize
cargo sanitize address
undefinedcargo install cargo-sanitize
cargo sanitize address
undefined3. Interpreting ASan output in Rust
3. 解读Rust中的ASan输出
==12345==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000050
READ of size 4 at 0x602000000050 thread T0
#0 0x401234 in myapp::module::function /src/main.rs:15
#1 0x401567 in myapp::main /src/main.rs:42
0x602000000050 is located 0 bytes after a 40-byte region allocated at:
#0 0x... in alloc::alloc::alloc ...
#1 0x... in myapp::create_buffer /src/main.rs:10Rust-specific patterns:
| ASan error | Likely Rust cause |
|---|---|
| |
| |
| Returning reference to local |
| Use after |
==12345==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000050
READ of size 4 at 0x602000000050 thread T0
#0 0x401234 in myapp::module::function /src/main.rs:15
#1 0x401567 in myapp::main /src/main.rs:42
0x602000000050 is located 0 bytes after a 40-byte region allocated at:
#0 0x... in alloc::alloc::alloc ...
#1 0x... in myapp::create_buffer /src/main.rs:10Rust特有的错误模式:
| ASan错误 | 可能的Rust原因 |
|---|---|
| |
| Vec重新分配后使用 |
| 返回局部变量的引用 |
| 在 |
4. Miri — interpreter for undefined behaviour
4. Miri — 未定义行为解释器
Miri interprets Rust MIR and detects UB that sanitizers might miss:
bash
undefinedMiri会解释Rust MIR并检测Sanitizers可能遗漏的UB:
bash
undefinedInstall Miri (requires nightly)
安装Miri(需nightly版本)
rustup +nightly component add miri
rustup +nightly component add miri
Run tests under Miri
在Miri下运行测试
cargo +nightly miri test
cargo +nightly miri test
Run specific test
运行指定测试
cargo +nightly miri test test_name
cargo +nightly miri test test_name
Run a binary under Miri
在Miri下运行二进制程序
cargo +nightly miri run
cargo +nightly miri run
Run with Stacked Borrows model (strict aliasing)
使用Stacked Borrows模型(严格别名规则)
MIRIFLAGS="-Zmiri-strict-provenance" cargo +nightly miri test
MIRIFLAGS="-Zmiri-strict-provenance" cargo +nightly miri test
Disable isolation (allow file I/O, randomness)
禁用隔离(允许文件I/O、随机数生成)
MIRIFLAGS="-Zmiri-disable-isolation" cargo +nightly miri test
undefinedMIRIFLAGS="-Zmiri-disable-isolation" cargo +nightly miri test
undefined5. What Miri detects
5. Miri可检测的问题
rust
// 1. Dangling pointer use
unsafe {
let x = Box::new(42);
let ptr = Box::into_raw(x);
let _ = Box::from_raw(ptr); // drop
let _val = *ptr; // Miri: use of dangling pointer
}
// 2. Invalid enum discriminant
let x: u8 = 3;
let e = unsafe { std::mem::transmute::<u8, MyEnum>(x) };
// Miri: enum value has invalid tag
// 3. Uninitialized memory read
let uninit: MaybeUninit<u32> = MaybeUninit::uninit();
let val = unsafe { uninit.assume_init() }; // Miri: reading uninitialized bytes
// 4. Stacked borrows violation
let mut x = 5u32;
let ptr = &mut x as *mut u32;
let _ref = &x; // shared reference
unsafe { *ptr = 10; } // Miri: mutable access while shared borrow exists
// 5. Data races (with threads)
// Miri simulates sequential execution and detects races via Stacked Borrowsrust
// 1. 悬空指针使用
unsafe {
let x = Box::new(42);
let ptr = Box::into_raw(x);
let _ = Box::from_raw(ptr); // 释放
let _val = *ptr; // Miri:检测到悬空指针使用
}
// 2. 无效枚举判别式
let x: u8 = 3;
let e = unsafe { std::mem::transmute::<u8, MyEnum>(x) };
// Miri:枚举值标签无效
// 3. 读取未初始化内存
let uninit: MaybeUninit<u32> = MaybeUninit::uninit();
let val = unsafe { uninit.assume_init() }; // Miri:读取未初始化字节
// 4. Stacked Borrows规则违反
let mut x = 5u32;
let ptr = &mut x as *mut u32;
let _ref = &x; // 共享引用
unsafe { *ptr = 10; } // Miri:存在共享借用时进行可变访问
// 5. 数据竞争(多线程场景)
// Miri通过Stacked Borrows模拟顺序执行并检测竞争6. ThreadSanitizer for Rust
6. Rust中的ThreadSanitizer
bash
RUSTFLAGS="-Z sanitizer=thread" \
RUST_TEST_THREADS=8 \
cargo +nightly test -Zbuild-std \
--target x86_64-unknown-linux-gnu 2>&1 | head -50TSan output:
WARNING: ThreadSanitizer: data race (pid=12345)
Write of size 4 at 0x7f... by thread T2 (mutexes: write M1):
#0 myapp::counter::increment src/counter.rs:10
Previous read of size 4 at 0x7f... by thread T1:
#0 myapp::counter::get src/counter.rs:5bash
RUSTFLAGS="-Z sanitizer=thread" \
RUST_TEST_THREADS=8 \
cargo +nightly test -Zbuild-std \
--target x86_64-unknown-linux-gnu 2>&1 | head -50TSan输出示例:
WARNING: ThreadSanitizer: data race (pid=12345)
Write of size 4 at 0x7f... by thread T2 (mutexes: write M1):
#0 myapp::counter::increment src/counter.rs:10
Previous read of size 4 at 0x7f... by thread T1:
#0 myapp::counter::get src/counter.rs:57. Miri configuration via MIRIFLAGS
7. 通过MIRIFLAGS配置Miri
| Flag | Effect |
|---|---|
| Allow I/O, clock, randomness |
| Strict pointer provenance (stricter than LLVM) |
| Stricter alignment checking |
| Check float/int validity |
| Simulate N CPUs (for concurrency) |
| Seed for random scheduling |
| Suppress memory leak errors |
| Track raw pointer provenance |
| 参数 | 作用 |
|---|---|
| 允许I/O、时钟访问、随机数生成 |
| 严格的指针来源检查(比LLVM更严格) |
| 更严格的对齐检查 |
| 检查浮点数/整数有效性 |
| 模拟N个CPU(用于并发场景) |
| 随机调度的种子 |
| 抑制内存泄漏错误 |
| 追踪原始指针的来源 |
8. CI integration
8. CI集成
yaml
undefinedyaml
undefinedGitHub Actions
GitHub Actions
-
name: Miri run: | rustup toolchain install nightly rustup +nightly component add miri cargo +nightly miri test env: MIRIFLAGS: "-Zmiri-disable-isolation"
-
name: ASan (nightly) run: | rustup component add rust-src --toolchain nightly RUSTFLAGS="-Z sanitizer=address"
cargo +nightly test -Zbuild-std
--target x86_64-unknown-linux-gnu
undefined-
name: Miri run: | rustup toolchain install nightly rustup +nightly component add miri cargo +nightly miri test env: MIRIFLAGS: "-Zmiri-disable-isolation"
-
name: ASan (nightly) run: | rustup component add rust-src --toolchain nightly RUSTFLAGS="-Z sanitizer=address"
cargo +nightly test -Zbuild-std
--target x86_64-unknown-linux-gnu
undefinedRelated skills
相关技能
- Use for GDB/LLDB debugging of Rust panics
skills/rust/rust-debugging - Use for C/C++ sanitizer usage and comparison
skills/runtimes/sanitizers - Use for unsafe Rust patterns and review checklist
skills/rust/rust-unsafe - Use to generate inputs that trigger sanitizer errors
skills/runtimes/fuzzing
- 若需使用GDB/LLDB调试Rust panic,请使用
skills/rust/rust-debugging - 若需C/C++ Sanitizer的使用方法及对比,请使用
skills/runtimes/sanitizers - 若需不安全Rust的模式及审查清单,请使用
skills/rust/rust-unsafe - 若需生成触发Sanitizer错误的输入,请使用
skills/runtimes/fuzzing