]> git.lizzy.rs Git - rust.git/blobdiff - README.md
Merge pull request #766 from RalfJung/sysroot
[rust.git] / README.md
index a366e433b0f39cbef5186db86f98bffb32962569..090694128e3ae047ead08649b0381d86f38bf524 100644 (file)
--- a/README.md
+++ b/README.md
@@ -23,9 +23,11 @@ Be aware that Miri will not catch all possible errors 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, 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.
+  types and when these invariants even have to hold. Miri tries to avoid false
+  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.
 * 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.
@@ -53,7 +55,7 @@ Install Miri via `rustup`:
 rustup 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 to determine a nightly version that comes with Miri and install that, e.g. using `rustup install nightly-2019-03-28`.
+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, e.g. using `rustup install nightly-2019-03-28`.
 
 Now you can run your project in Miri:
 
@@ -105,6 +107,13 @@ You may be running `cargo miri` with a different compiler version than the one
 used to build the custom libstd that Miri uses, and Miri failed to detect that.
 Try deleting `~/.cache/miri`.
 
+#### "no mir for `std::rt::lang_start_internal`"
+
+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.
+
 ## Development and Debugging
 
 If you want to hack on miri yourself, great!  Here are some resources you might
@@ -113,85 +122,88 @@ find useful.
 ### Using a nightly rustc
 
 Miri heavily relies on internal rustc interfaces to execute MIR.  Still, some
-things (like adding support for a new intrinsic) can be done by working just on
-the Miri side.
+things (like adding support for a new intrinsic or a shim for an external
+function being called) can be done by working just on the Miri side.
 
-To prepare, make sure you are using a nightly Rust compiler.  The most
-convenient way is to install Miri using cargo, then you can easily run it on
-other projects:
+To prepare, make sure you are using a nightly Rust compiler.  Then you should be
+able to just `cargo build` Miri.
 
-```sh
-rustup component remove miri # avoid having Miri installed twice
-cargo +nightly install --path "$DIR" --force # or the nightly in `rust-version`
-cargo +nightly miri setup
-```
+In case this fails, your nightly might be incompatible with Miri master.  The
+`rust-version` file contains the commit hash of rustc that Miri is currently
+tested against; you can use that to find a nightly that works or you might have
+to wait for the next nightly to get released.
 
-(We are giving `+nightly` explicitly here all the time because it is important
-that all of these commands get executed with the same toolchain.)
-
-If you want to use a different libstd (not the one that comes with the
-nightly), you can do that by running
-
-```sh
-XARGO_RUST_SRC=~/src/rust/rustc/src/ cargo +nightly miri setup
-```
+### Testing the Miri driver
+[testing-miri]: #testing-the-miri-driver
 
-Either way, you can now do `cargo +nightly miri run` to run Miri with your
-local changes on whatever project you are debugging.
+The Miri driver in the `miri` binary is the "heart" of Miri: it is basically a
+version of `rustc` that, instead of compiling your code, runs it.  It accepts
+all the same flags as `rustc` (though the ones only affecting code generation
+and linking obviously will have no effect) [and more][miri-flags].
 
-`cargo miri setup` should end in printing the directory where the libstd was
-built.  For the next step to work, set that as your `MIRI_SYSROOT` environment
-variable:
+Running the Miri driver requires some fiddling with environment variables, so
+the `miri` script helps you do that.  For example, you can run the driver on a
+particular file by doing
 
 ```sh
-export MIRI_SYSROOT=~/.cache/miri/HOST # or whatever the previous command said
+./miri run tests/run-pass/format.rs
+./miri run tests/run-pass/hello.rs --target i686-unknown-linux-gnu
 ```
 
-### Testing Miri
-
-Instead of running an entire project using `cargo miri`, you can also use the
-Miri "driver" directly to run just a single file.  That can be easier during
-debugging.
+and you can run the test suite using:
 
-```sh
-cargo run tests/run-pass/format.rs # or whatever test you like
+```
+./miri test
 ```
 
-You can also run the test suite with `cargo test --release`.  `cargo test
---release FILTER` only runs those tests that contain `FILTER` in their filename
-(including the base directory, e.g. `cargo test --release fail` will run all
-compile-fail tests).  We recommend using `--release` to make test running take
-less time.
+`./miri test FILTER` only runs those tests that contain `FILTER` in their
+filename (including the base directory, e.g. `./miri test fail` will run all
+compile-fail tests).
 
-Now you are set up!  You can write a failing test case, and tweak miri until it
-fails no more.
 You can get a trace of which MIR statements are being executed by setting the
 `MIRI_LOG` environment variable.  For example:
 
 ```sh
-MIRI_LOG=info cargo run tests/run-pass/vecs.rs
+MIRI_LOG=info ./miri run tests/run-pass/vecs.rs
 ```
 
-Setting `MIRI_LOG` like this will configure logging for miri itself as well as
+Setting `MIRI_LOG` like this will configure logging for Miri itself as well as
 the `rustc::mir::interpret` and `rustc_mir::interpret` modules in rustc.  You
-can also do more targeted configuration, e.g. to debug the stacked borrows
-implementation:
+can also do more targeted configuration, e.g. the following helps debug the
+stacked borrows implementation:
+
 ```sh
-MIRI_LOG=rustc_mir::interpret=info,miri::stacked_borrows cargo run tests/run-pass/vecs.rs
+MIRI_LOG=rustc_mir::interpret=info,miri::stacked_borrows ./miri run tests/run-pass/vecs.rs
 ```
 
 In addition, you can set `MIRI_BACKTRACE=1` to get a backtrace of where an
-evaluation error was originally created.
+evaluation error was originally raised.
+
+### Testing `cargo miri`
 
+Working with the driver directly gives you full control, but you also lose all
+the convenience provided by cargo.  Once your test case depends on a crate, it
+is probably easier to test it with the cargo wrapper.  You can install your
+development version of Miri using
+
+```
+./miri install
+```
+
+and then you can use it as if it was installed by `rustup`.  Make sure you use
+the same toolchain when calling `cargo miri` that you used when installing Miri!
+
+There's a test for the cargo wrapper in the `test-cargo-miri` directory; run
+`./run-test.py` in there to execute it.
 
 ### Using a locally built rustc
 
-Since the heart of Miri (the main interpreter engine) lives in rustc, working on
-Miri will often require using a locally built rustc.  The bug you want to fix
-may actually be on the rustc side, or you just need to get more detailed trace
-of the execution than what is possible with release builds -- in both cases, you
-should develop miri against a rustc you compiled yourself, with debug assertions
-(and hence tracing) enabled.
+A big part of the Miri driver lives in rustc, so working on Miri will sometimes
+require using a locally built rustc.  The bug you want to fix may actually be on
+the rustc side, or you just need to get more detailed trace of the execution
+than what is possible with release builds -- in both cases, you should develop
+miri against a rustc you compiled yourself, with debug assertions (and hence
+tracing) enabled.
 
 The setup for a local rustc works as follows:
 ```sh
@@ -211,36 +223,39 @@ rustup override set custom
 ```
 
 With this, you should now have a working development setup!  See
-["Testing Miri"](#testing-miri) above for how to proceed.
-
-Running `cargo miri` in this setup is a bit more complicated, because the Miri
-binary you just created does not actually run without some environment variables.
-But you can contort cargo into calling `cargo miri` the right way for you:
-
-```sh
-# in some other project's directory, to run `cargo miri test`:
-MIRI_SYSROOT=$(rustc +custom --print sysroot) cargo +custom run --manifest-path /path/to/miri/Cargo.toml --bin cargo-miri --release -- miri test
-```
+[above][testing-miri] for how to proceed working with the Miri driver.
 
 ### Miri `-Z` flags and environment variables
+[miri-flags]: #miri--z-flags-and-environment-variables
 
 Several `-Z` flags are relevant for Miri:
 
-* `-Zmir-opt-level` controls how many MIR optimizations are performed.  miri
+* `-Zmiri-seed=<hex>` is a custom `-Z` flag added by Miri.  It enables the
+  interpreted program to seed an RNG with system entropy.  Miri will keep an RNG
+  on its own that is seeded with the given seed, and use that to generate the
+  "system entropy" that seeds the RNG(s) in the interpreted program.
+  **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
+  faster.
+* `-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.
+  make Miri miss bugs in your program because they got optimized away.
 * `-Zalways-encode-mir` makes rustc dump MIR even for completely monomorphic
-  functions.  This is needed so that miri can execute such functions, so miri
+  functions.  This is needed so that Miri can execute such functions, so Miri
   sets this flag per default.
-* `-Zmiri-disable-validation` is a custom `-Z` flag added by miri.  It 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.
 
 Moreover, Miri recognizes some environment variables:
 
-* `MIRI_SYSROOT` (recognized by `miri`, `cargo miri` and the test suite)
-  indicates the sysroot to use.
-* `MIRI_TARGET` (recognized by the test suite) indicates which target
+* `MIRI_LOG`, `MIRI_BACKTRACE` control logging and backtrace printing during
+  Miri executions, also [see above][testing-miri].
+* `MIRI_SYSROOT` (recognized by `cargo miri` and the test suite)
+  indicates the sysroot to use.  To do the same thing with `miri`
+  directly, use the `--sysroot` flag.
+* `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.
 
@@ -275,15 +290,24 @@ used according to their aliasing restrictions.
 
 ## Bugs found by Miri
 
-Miri has already found a number of bugs in the Rust standard library, which we collect here.
+Miri has already found a number of bugs in the Rust standard library and beyond, which we collect here.
+
+Definite bugs found:
 
 * [`Debug for vec_deque::Iter` accessing uninitialized memory](https://github.com/rust-lang/rust/issues/53566)
 * [`From<&[T]> for Rc` creating a not sufficiently aligned reference](https://github.com/rust-lang/rust/issues/54908)
 * [`BTreeMap` creating a shared reference pointing to a too small allocation](https://github.com/rust-lang/rust/issues/54957)
-* [`VecDeque` creating overlapping mutable references](https://github.com/rust-lang/rust/pull/56161)
+* [`Vec::append` creating a dangling reference](https://github.com/rust-lang/rust/pull/61082)
 * [Futures turning a shared reference into a mutable one](https://github.com/rust-lang/rust/pull/56319)
 * [`str` turning a shared reference into a mutable one](https://github.com/rust-lang/rust/pull/58200)
+* [`rand` performing unaligned reads](https://github.com/rust-random/rand/issues/779)
+
+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)
 
 ## License