rewirte development part of README
This commit is contained in:
parent
2481d6091a
commit
bf6b7aa550
119
README.md
119
README.md
@ -113,63 +113,56 @@ 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:
|
||||
|
||||
```sh
|
||||
rustup component remove miri # avoid having Miri installed twice
|
||||
cargo +nightly install --path "$DIR" --force
|
||||
cargo +nightly miri setup
|
||||
```
|
||||
|
||||
(We are giving `+nightly` explicitly here all the time because it is important
|
||||
that all of these commands get executed with the same toolchain.)
|
||||
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.
|
||||
|
||||
If you want to use a different libstd (not the one that comes with the
|
||||
nightly), you can do that by running
|
||||
### Testing the Miri driver
|
||||
[testing-miri]: #testing-the-miri-driver
|
||||
|
||||
```sh
|
||||
XARGO_RUST_SRC=~/src/rust/rustc/src/ cargo +nightly miri setup
|
||||
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].
|
||||
|
||||
To run the Miri driver, you need to have the `MIRI_SYSROOT` environment variable
|
||||
set to an appropriate sysroot. You can generate such a sysroot with the
|
||||
following incantation:
|
||||
|
||||
```
|
||||
cargo run --bin cargo-miri -- miri setup
|
||||
```
|
||||
|
||||
Either way, you can now do `cargo +nightly miri run` to run Miri with your
|
||||
local changes on whatever project you are debugging.
|
||||
This basically runs the `cargo-miri` binary (which backs the `cargo miri`
|
||||
subcommand) with `cargo`, and asks it to `setup`. It should in the end print
|
||||
the directory where the libstd was built. In the following, we will assume it
|
||||
is `~/.cache/miri/HOST`; you may have to adjust that if you are not using Linux.
|
||||
|
||||
`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:
|
||||
Now you can run the driver directly using
|
||||
|
||||
```sh
|
||||
export MIRI_SYSROOT=~/.cache/miri/HOST # or whatever the previous command said
|
||||
MIRI_SYSROOT=~/.cache/miri/HOST cargo run tests/run-pass/format.rs # or whatever test you like
|
||||
```
|
||||
|
||||
### Testing Miri
|
||||
and you can run the test suite using
|
||||
|
||||
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.
|
||||
|
||||
```sh
|
||||
cargo run tests/run-pass/format.rs # or whatever test you like
|
||||
```
|
||||
cargo 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.
|
||||
We recommend adding the `--release` flag to make tests run faster.
|
||||
|
||||
`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).
|
||||
|
||||
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:
|
||||
|
||||
@ -177,26 +170,43 @@ You can get a trace of which MIR statements are being executed by setting the
|
||||
MIRI_LOG=info cargo 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
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
```
|
||||
cargo install --path . --force
|
||||
```
|
||||
|
||||
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
|
||||
@ -216,18 +226,21 @@ rustup override set custom
|
||||
```
|
||||
|
||||
With this, you should now have a working development setup! See
|
||||
["Testing Miri"](#testing-miri) above for how to proceed.
|
||||
[above][testing-miri] for how to proceed working with the Miri driver. Notice
|
||||
that rustc's sysroot is already built for Miri in this case, so you can set
|
||||
`MIRI_SYSROOT=$(rustc --print sysroot)`.
|
||||
|
||||
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:
|
||||
binary you just created needs help to find the libraries it links against. On
|
||||
Linux, you can set the rpath to make this "just work":
|
||||
|
||||
```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
|
||||
export RUSTFLAGS="-C link-args=-Wl,-rpath,$(rustc --print sysroot)/lib/rustlib/x86_64-unknown-linux-gnu/lib"
|
||||
cargo install --path . --force
|
||||
```
|
||||
|
||||
### Miri `-Z` flags and environment variables
|
||||
[miri-flags]: #miri--z-flags-and-environment-variables
|
||||
|
||||
Several `-Z` flags are relevant for Miri:
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user