* **Experimental**: Violations of the [Stacked Borrows] rules governing aliasing
for reference types
+On top of that, Miri will also tell you about memory leaks: when there is memory
+still allocated at the end of the execution, and that memory is not reachable
+from a global `static`, Miri will raise an error. Note however that
+[leak checking is currently disabled on Windows targets](https://github.com/rust-lang/miri/issues/1302).
+
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
-program, and cannot run all programs:
+However, 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
types and when these invariants even have to hold. Miri tries to avoid false
* Miri runs the program as a platform-independent interpreter, so the program
has no access to most platform-specific APIs or FFI. A few APIs have been
implemented (such as printing to stdout) but most have not: for example, Miri
- currently does not support concurrency, or SIMD, or networking.
+ currently does not support SIMD or networking.
+* Miri currently does not check for data-races and most other concurrency-related
+ issues.
[rust]: https://www.rust-lang.org/
[mir]: https://github.com/rust-lang/rfcs/blob/master/text/1211-mir.md
echo "Installing latest nightly with Miri: $MIRI_NIGHTLY"
rustup set profile minimal
rustup default "$MIRI_NIGHTLY"
-
rustup component add miri
-cargo miri setup
cargo miri test
```
-We use `cargo miri setup` to avoid getting interactive questions about the extra
-setup needed for Miri.
-
### Common Problems
When using the above instructions, you may encounter a number of confusing compiler
This means the sysroot you are using was not compiled with Miri in mind. This
should never happen when you use `cargo miri` because that takes care of setting
-up the sysroot. If you are using `miri` (the Miri driver) directly, see
-[below][testing-miri] for how to set up the sysroot.
+up the sysroot. If you are using `miri` (the Miri driver) directly, see the
+[contributors' guide](CONTRIBUTING.md) for how to use `./miri` to best do that.
## Miri `-Z` flags and environment variables
[miri-flags]: #miri--z-flags-and-environment-variables
-Several `-Z` flags are relevant for Miri:
+Miri adds its own set of `-Z` flags:
-* `-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. 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 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-alignment-check` disables checking pointer alignment. This is
+ useful to avoid [false positives][alignment-false-positives]. However, setting
+ this flag means Miri could miss bugs in your program.
* `-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-validation` disables enforcing validity invariants, which are
+ enforced by default. This is mostly useful to focus on other failures (such
+ as out-of-bounds accesses) first. Setting this flag means Miri will miss bugs
+ in your program. However, this can also help to make Miri run faster.
* `-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.
+ the host so that it cannot be accessed by the program. Can be used multiple
+ times to exclude several variables. On Windows, the `TERM` environment
+ variable is excluded by default.
+* `-Zmiri-ignore-leaks` disables the memory leak checker.
+* `-Zmiri-seed=<hex>` configures the seed of the RNG that Miri uses to resolve
+ non-determinism. This RNG is used 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-track-alloc-id=<id>` shows a backtrace when the given allocation is
+ being allocated or freed. This helps in debugging memory leaks and
+ use after free bugs.
+* `-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.
+
+[alignment-false-positives]: https://github.com/rust-lang/miri/issues/1074
+
+Some native rustc `-Z` flags are also very relevant for Miri:
+
* `-Zmir-opt-level` controls how many MIR optimizations are performed. Miri
overrides the default to be `0`; be advised that using any higher level can
make Miri miss bugs in your program because they got optimized away.
functions. This is needed so that Miri can execute such functions, so 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.
+ enables this per default because it is needed for [Stacked Borrows].
Moreover, Miri recognizes some environment variables:
* `MIRI_TEST_FLAGS` (recognized by the test suite) defines extra flags to be
passed to Miri.
+The following environment variables are internal, but used to communicate between
+different Miri binaries, and as such worth documenting:
+
+* `MIRI_BE_RUSTC` when set to any value tells the Miri driver to actually not
+ interpret the code but compile it like rustc would. This is useful to be sure
+ that the compiled `rlib`s are compatible with Miri.
+
## Contributing and getting help
If you want to contribute to Miri, great! Please check out our
* [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)
+* [`beef` leaking memory](https://github.com/maciejhirsz/beef/issues/12)
+* [`EbrCell` using uninitialized memory incorrectly](https://github.com/Firstyear/concread/commit/b15be53b6ec076acb295a5c0483cdb4bf9be838f#diff-6282b2fc8e98bd089a1f0c86f648157cR229)
+* [TiKV performing an unaligned pointer access](https://github.com/tikv/tikv/issues/7613)
+* [`servo_arc` creating a dangling shared reference](https://github.com/servo/servo/issues/26357)
+* [TiKV constructing out-of-bounds pointers (and overlapping mutable references)](https://github.com/tikv/tikv/pull/7751)
Violations of [Stacked Borrows] found that are likely bugs (but Stacked Borrows is currently just an experiment):
* [`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)
+* [`sized-chunks` creating aliasing mutable references](https://github.com/bodil/sized-chunks/issues/8)
+* [`String::push_str` invalidating existing references into the string](https://github.com/rust-lang/rust/issues/70301)
+* [`ryu` using raw pointers outside their valid memory area](https://github.com/dtolnay/ryu/issues/24)
+* [ink! creating overlapping mutable references](https://github.com/rust-lang/miri/issues/1364)
+* [TiKV creating overlapping mutable reference and raw pointer](https://github.com/tikv/tikv/pull/7709)
## License