* Not sufficiently aligned memory accesses and references
* Violation of *some* basic type invariants (a `bool` that is not 0 or 1, for example,
or an invalid enum discriminant)
-* WIP: Violations of the rules governing aliasing for reference types
+* **Experimental**: Violations of the [Stacked Borrows] rules governing aliasing
+ for reference types
Miri has already discovered some [real-world bugs](#bugs-found-by-miri). If you
found a bug with Miri, we'd appreciate if you tell us and we'll add it to the
list!
-Be aware that Miri will not catch all cases of undefined behavior in your
+Be aware that Miri will **not catch all cases of undefined behavior** in your
program, and cannot run all programs:
* There are still plenty of open questions around the basic invariants for some
positives here, so if you program runs fine in Miri right now that is by no
means a guarantee that it is UB-free when these questions get answered.
- In particular, Miri does currently not check that integers are initialized
- or that references point to valid data.
+ In particular, Miri does currently not check that integers/floats are
+ initialized or that references point to valid data.
* If the program relies on unspecified details of how data is laid out, it will
still run fine in Miri -- but might break (including causing UB) on different
compiler versions or different platforms.
[mir]: https://github.com/rust-lang/rfcs/blob/master/text/1211-mir.md
[`unreachable_unchecked`]: https://doc.rust-lang.org/stable/std/hint/fn.unreachable_unchecked.html
[`copy_nonoverlapping`]: https://doc.rust-lang.org/stable/std/ptr/fn.copy_nonoverlapping.html
+[Stacked Borrows]: https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md
## Using Miri
-Install Miri via `rustup`:
+Install Miri on Rust nightly via `rustup`:
```sh
-rustup component add miri
+rustup +nightly component add miri
```
If `rustup` says the `miri` component is unavailable, that's because not all
nightly releases come with all tools. Check out
[this website](https://rust-lang.github.io/rustup-components-history) to
determine a nightly version that comes with Miri and install that using
-`rustup install nightly-YYYY-MM-DD`.
+`rustup toolchain install nightly-YYYY-MM-DD`.
Now you can run your project in Miri:
The first time you run Miri, it will perform some extra setup and install some
dependencies. It will ask you for confirmation before installing anything.
+Miri supports cross-execution: if you want to run the program as if it was a
+Linux program, you can do `cargo miri run --target x86_64-unknown-linux-gnu`.
+This is particularly useful if you are using Windows, as the Linux target is
+much better supported than Windows targets.
+
You can pass arguments to Miri after the first `--`, and pass arguments to the
interpreted program or test suite after the second `--`. For example, `cargo
miri run -- -Zmiri-disable-validation` runs the program without validation of
-basic type invariants and references.
+basic type invariants and without checking the aliasing of references.
-When running code via `cargo miri`, the `miri` config flag is set. You can
-use this to exclude test cases that will fail under Miri because they do things
+When compiling code via `cargo miri`, the `miri` config flag is set. You can
+use this to ignore test cases that will fail under Miri because they do things
Miri does not support:
```rust
-#[cfg(not(miri))]
#[test]
+#[cfg_attr(miri, ignore)]
fn does_not_work_on_miri() {
std::thread::spawn(|| println!("Hello Thread!"))
.join()
* `-Zmiri-seed=<hex>` is a custom `-Z` flag added by Miri. It configures the
seed of the RNG that Miri uses to resolve non-determinism. This RNG is used
- to pick base addresses for allocations, and when the interpreted program
- requests system entropy. The default seed is 0.
+ to pick base addresses for allocations. When isolation is enabled (the default),
+ this is also used to emulate system entropy. The default seed is 0.
**NOTE**: This entropy is not good enough for cryptographic use! Do not
generate secret keys in Miri or perform other kinds of cryptographic
operations that rely on proper random numbers.
-* `-Zmiri-disable-validation` disables enforcing the validity invariant, which
- is enforced by default. This is mostly useful for debugging; it means Miri
- will miss bugs in your program. However, this can also help to make Miri run
+* `-Zmiri-disable-validation` disables enforcing validity invariants, which are
+ enforced by default. This is mostly useful for debugging. It means Miri will
+ miss bugs in your program. However, this can also help to make Miri run
faster.
-* `-Zmiri-disable-isolation` disables host host isolation. As a consequence,
- the program has access to host resources such as environment variables and
- randomness (and, eventually, file systems and more).
-* `-Zmiri-env-exclude=<var>` keeps the `var` environment variable isolated from
+* `-Zmiri-disable-stacked-borrows` disables checking the experimental
+ [Stacked Borrows] aliasing rules. This can make Miri run faster, but it also
+ means no aliasing violations will be detected.
+* `-Zmiri-disable-isolation` disables host isolation. As a consequence,
+ the program has access to host resources such as environment variables, file
+ systems, and randomness.
+* `-Zmiri-ignore-leaks` disables the memory leak checker.
+* `-Zmiri-env-exclude=<var>` keeps the `var` environment variable isolated from
the host. Can be used multiple times to exclude several variables. The `TERM`
environment variable is excluded by default.
* `-Zmir-opt-level` controls how many MIR optimizations are performed. Miri
sets this flag per default.
* `-Zmir-emit-retag` controls whether `Retag` statements are emitted. Miri
enables this per default because it is needed for validation.
+* `-Zmiri-track-pointer-tag=<tag>` shows a backtrace when the given pointer tag
+ is popped from a borrow stack (which is where the tag becomes invalid and any
+ future use of it will error). This helps you in finding out why UB is
+ happening and where in your code would be a good place to look for it.
+* `-Zmiri-track-alloc-id=<id>` shows a backtrace when the given allocation is
+ being allocated. This helps in debugging memory leaks.
Moreover, Miri recognizes some environment variables:
* `MIRI_TEST_TARGET` (recognized by the test suite) indicates which target
architecture to test against. `miri` and `cargo miri` accept the `--target`
flag for the same purpose.
+* `MIRI_TEST_FLAGS` (recognized by the test suite) defines extra flags to be
+ passed to Miri.
## Contributing and getting help
* [`rand` performing unaligned reads](https://github.com/rust-random/rand/issues/779)
* [The Unix allocator calling `posix_memalign` in an invalid way](https://github.com/rust-lang/rust/issues/62251)
* [`getrandom` calling the `getrandom` syscall in an invalid way](https://github.com/rust-random/getrandom/pull/73)
+* [`Vec`](https://github.com/rust-lang/rust/issues/69770) and [`BTreeMap`](https://github.com/rust-lang/rust/issues/69769) leaking memory under some (panicky) conditions
+* [Memory leak in `beef`](https://github.com/maciejhirsz/beef/issues/12)
-Violations of Stacked Borrows found that are likely bugs (but Stacked Borrows is currently just an experiment):
+Violations of [Stacked Borrows] found that are likely bugs (but Stacked Borrows is currently just an experiment):
* [`VecDeque` creating overlapping mutable references](https://github.com/rust-lang/rust/pull/56161)
* [`BTreeMap` creating mutable references that overlap with shared references](https://github.com/rust-lang/rust/pull/58431)
* [`LinkedList` creating overlapping mutable references](https://github.com/rust-lang/rust/pull/60072)
* [`Vec::push` invalidating existing references into the vector](https://github.com/rust-lang/rust/issues/60847)
+* [`align_to_mut` violating uniqueness of mutable references](https://github.com/rust-lang/rust/issues/68549)
+* [Aliasing mutable references in `sized-chunks`](https://github.com/bodil/sized-chunks/issues/8)
## License