]> git.lizzy.rs Git - rust.git/blobdiff - README.md
make 'fn convert_path_separator' to take Cow<> (to remove unnecessary allocation)
[rust.git] / README.md
index 8c5a29880c7cbfd464a752bc9983cb7147ba1665..03b995aa56d3fd76e9561099ccb6096b9d9b48ea 100644 (file)
--- a/README.md
+++ b/README.md
@@ -14,13 +14,14 @@ for example:
 * 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
@@ -28,8 +29,8 @@ program, and cannot run all programs:
   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.
@@ -39,30 +40,30 @@ program, and cannot run all programs:
   addresses or other non-deterministic data, try running Miri with different
   values for `-Zmiri-seed` to test different executions.
 * Miri runs the program as a platform-independent interpreter, so the program
-  has no access to any platform-specific APIs or FFI. A few APIs have been
+  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, or file system
-  access.
+  currently does not support concurrency, or SIMD, or networking.
 
 [rust]: https://www.rust-lang.org/
 [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
 
 
-## Running Miri on your own project (and its test suite)
+## 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, e.g. using
-`rustup install nightly-2019-03-28`.
+determine a nightly version that comes with Miri and install that using
+`rustup toolchain install nightly-YYYY-MM-DD`.
 
 Now you can run your project in Miri:
 
@@ -75,23 +76,27 @@ 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.  `cargo miri test -- -- -Zunstable-options
---exclude-should-panic` skips `#[should_panic]` tests, which is a good idea
-because Miri does not support unwinding or catching panics.
+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() {
-    let x = 0u8;
-    assert!(&x as *const _ as usize % 4 < 4);
+    std::thread::spawn(|| println!("Hello Thread!"))
+        .join()
+        .unwrap();
 }
 ```
 
@@ -105,12 +110,13 @@ nightly that *does* come with Miri:
 ```sh
 MIRI_NIGHTLY=nightly-$(curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/miri)
 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 -- -- -Zunstable-options --exclude-should-panic
+cargo miri test
 ```
 
 We use `cargo miri setup` to avoid getting interactive questions about the extra
@@ -148,15 +154,25 @@ Several `-Z` flags are relevant for Miri:
 
 * `-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-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
   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.
@@ -165,6 +181,12 @@ Several `-Z` flags are relevant for 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:
 
@@ -176,133 +198,15 @@ 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.
-
-## Development and Debugging
-
-If you want to hack on miri yourself, great!  Here are some resources you might
-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 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.  Then you should be
-able to just `cargo build` Miri.
-
-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. You can also use
-[`rustup-toolchain-install-master`](https://github.com/kennytm/rustup-toolchain-install-master)
-to install that exact version of rustc as a toolchain:
-```
-rustup-toolchain-install-master $(cat rust-version) -c rust-src
-```
-
-Another common problem is outdated dependencies: Miri does not come with a
-lockfile (it cannot, due to how it gets embedded into the rustc build). So you
-have to run `cargo update` every now and then yourself to make sure you are
-using the latest versions of everything (which is what gets tested on CI).
-
-### Testing the Miri driver
-[testing-miri]: #testing-the-miri-driver
-
-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].
-
-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
-./miri run tests/run-pass/format.rs
-./miri run tests/run-pass/hello.rs --target i686-unknown-linux-gnu
-```
-
-and you can run the test suite using:
-
-```
-./miri test
-```
-
-`./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).
-
-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 ./miri run tests/run-pass/vecs.rs
-```
-
-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. the following helps debug the
-stacked borrows implementation:
-
-```sh
-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 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
-
-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
-git clone https://github.com/rust-lang/rust/ rustc
-cd rustc
-cp config.toml.example config.toml
-# Now edit `config.toml` and set `debug-assertions = true` and `test-miri = true`.
-# The latter is important to build libstd with the right flags for miri.
-# This step can take 30 minutes and more.
-./x.py build src/rustc
-# If you change something, you can get a faster rebuild by doing
-./x.py --keep-stage 0 build src/rustc
-# You may have to change the architecture in the next command
-rustup toolchain link custom build/x86_64-unknown-linux-gnu/stage2
-# Now cd to your Miri directory, then configure rustup
-rustup override set custom
-```
-
-With this, you should now have a working development setup!  See
-[above][testing-miri] for how to proceed working with the Miri driver.
+* `MIRI_TEST_FLAGS` (recognized by the test suite) defines extra flags to be
+  passed to Miri.
 
 ## Contributing and getting help
 
-Check out the issues on this GitHub repository for some ideas. There's lots that
-needs to be done that I haven't documented in the issues yet, however. For more
-ideas or help with running or hacking on Miri, you can open an issue here on
+If you want to contribute to Miri, great!  Please check out our
+[contribution guide](CONTRIBUTING.md).
+
+For help with running Miri, you can open an issue here on
 GitHub or contact us (`oli-obk` and `RalfJ`) on the [Rust Zulip].
 
 [Rust Zulip]: https://rust-lang.zulipchat.com
@@ -343,13 +247,17 @@ Definite bugs found:
 * [`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