rgoussu@goussu: ~/library/rust/toolchain
~/library/rust/toolchain cat miri.md

miri — undefined-behaviour detection

# The MIR interpreter that catches undefined behaviour in unsafe code — aliasing-model violations, use-after-free, data races — as a nightly component run under cargo miri test.

Conceptsaved 2026-08-09 #rust#tooling#unsafe#miri#correctness

Overview

Miri executes your program by interpreting rustc's MIR instead of compiling it, checking every memory access against Rust's operational rules as it goes. Its job is the one the type system can't do: policing unsafe blocks. Where the borrow checker proves safe code correct statically, miri catches what unsafe code does wrong dynamically — use-after-free, out-of-bounds access, uninitialized reads, aliasing-model violations, even data races. No JVM or Go analog exists because no other mainstream ecosystem lets you opt out of safety and then offers a tool to audit the opt-out.

Key points

  • Nightly component: rustup +nightly component add miri, then cargo +nightly miri test — runs the test suite interpreted. Expect 10–100× slowdown; scope it to the crates/tests that contain or exercise unsafe.
  • What it catches: heap UB (use-after-free, double-free, OOB), invalid values (uninitialized reads, bad enum discriminants, null references), aliasing violations per the Tree Borrows / Stacked Borrows experimental models, memory leaks, and data races on the interpreted thread schedule.
  • What it can't: FFI calls (no C code to interpret — it errors or shims them), inline asm, and it only sees UB on executed paths — it is a dynamic tool; coverage is your test suite's coverage.
  • The aliasing models are the point: &mut uniqueness is Rust's core promise, and raw-pointer code violating it is UB even when it "works". Miri is the only tool that checks this — LLVM sanitizers can't, they don't know Rust's rules.
  • Randomized execution: seeds vary alignments, allocation addresses and thread interleavings (-Zmiri-many-seeds to sweep) — flushing out latent assumptions.
  • CI posture: any crate with meaningful unsafe runs miri in CI on its unsafe-heavy test subset; pair with #[deny(unsafe_op_in_unsafe_fn)] and cargo-geiger for the audit trail.
  • Also a UB oracle for dependencies: running your suite under miri interprets your deps' code too — how several ecosystem-wide soundness bugs were found.

Examples

rustup +nightly component add miri
cargo +nightly miri test -p my-unsafe-crate
MIRIFLAGS="-Zmiri-many-seeds=0..16" cargo +nightly miri test unsafe_ring_buffer

Related

  • The Rust toolchain — parent catalog.
  • rustc — the MIR this tool interprets.
  • Deep dive Rust — the ownership rules miri enforces dynamically where the borrow checker can't reach.
  • Security testing — miri's place in the unsafe audit toolbox beside cargo-geiger and fuzzing.