| name | rust-sanitizers-miri |
| description | Rust sanitizers and Miri skill for memory safety validation. Use when running AddressSanitizer or ThreadSanitizer on Rust code, interpreting sanitizer reports, using Miri to detect undefined behaviour in unsafe Rust, or validating unsafe code correctness. Activates on queries about Rust ASan, Rust TSan, Miri, RUSTFLAGS sanitize, cargo miri, unsafe Rust UB, or interpreting Rust sanitizer output. |
Rust Sanitizers and 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.
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?"
Workflow
1. Sanitizers in Rust (nightly required)
Rust sanitizers require nightly and a compatible platform:
rustup toolchain install nightly
rustup component add rust-src --toolchain nightly
RUSTFLAGS="-Z sanitizer=address" \
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
RUSTFLAGS="-Z sanitizer=memory -Zsanitizer-memory-track-origins" \
cargo +nightly test -Zbuild-std \
--target x86_64-unknown-linux-gnu
RUSTFLAGS="-Z sanitizer=undefined" \
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.
2. Stable sanitizer workaround
For stable Rust, use the cross tool with a Docker image that has sanitizers pre-configured, or run cargo test inside a Docker container with a nightly image.
Alternatively, for simpler UB checking without nightly:
cargo install cargo-sanitize
cargo sanitize address
3. Interpreting ASan output in Rust
==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:10
Rust-specific patterns:
| ASan error | Likely Rust cause |
|---|
heap-buffer-overflow | unsafe slice access past bounds |
use-after-free | unsafe pointer use after Vec realloc |
stack-use-after-return | Returning reference to local |
heap-use-after-free | Use after drop() or Box::from_raw |
4. Miri — interpreter for undefined behaviour
Miri interprets Rust MIR and detects UB that sanitizers might miss:
rustup +nightly component add miri
cargo +nightly miri test
cargo +nightly miri test test_name
cargo +nightly miri run
MIRIFLAGS="-Zmiri-strict-provenance" cargo +nightly miri test
MIRIFLAGS="-Zmiri-disable-isolation" cargo +nightly miri test
5. What Miri detects
unsafe {
let x = Box::new(42);
let ptr = Box::into_raw(x);
let _ = Box::from_raw(ptr);
let _val = *ptr;
}
let x: u8 = 3;
let e = unsafe { std::mem::transmute::<u8, MyEnum>(x) };
let uninit: MaybeUninit<u32> = MaybeUninit::uninit();
let val = unsafe { uninit.assume_init() };
let mut x = 5u32;
let ptr = &mut x as *mut u32;
let _ref = &x;
{ *ptr = ; }
6. ThreadSanitizer for Rust
RUSTFLAGS="-Z sanitizer=thread" \
RUST_TEST_THREADS=8 \
cargo +nightly test -Zbuild-std \
--target x86_64-unknown-linux-gnu 2>&1 | head -50
TSan 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:5
7. Miri configuration via MIRIFLAGS
| Flag | Effect |
|---|
-Zmiri-disable-isolation | Allow I/O, clock, randomness |
-Zmiri-strict-provenance | Strict pointer provenance (stricter than LLVM) |
-Zmiri-symbolic-alignment-check | Stricter alignment checking |
-Zmiri-check-number-validity | Check float/int validity |
-Zmiri-num-cpus=N | Simulate N CPUs (for concurrency) |
-Zmiri-seed=N | Seed for random scheduling |
-Zmiri-ignore-leaks | Suppress memory leak errors |
-Zmiri-tag-raw-pointers | Track raw pointer provenance |
8. CI integration
- 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
Related skills
- Use
skills/rust/rust-debugging for GDB/LLDB debugging of Rust panics
- Use
skills/runtimes/sanitizers for C/C++ sanitizer usage and comparison
- Use
skills/rust/rust-unsafe for unsafe Rust patterns and review checklist
- Use
skills/runtimes/fuzzing to generate inputs that trigger sanitizer errors