@@ -105,6 +105,13 @@ You may be running `cargo miri` with a different compiler version than the one
105
105
used to build the custom libstd that Miri uses, and Miri failed to detect that.
106
106
Try deleting ` ~/.cache/miri ` .
107
107
108
+ #### "no mir for ` std::rt::lang_start_internal ` "
109
+
110
+ This means the sysroot you are using was not compiled with Miri in mind. This
111
+ should never happen when you use ` cargo miri ` because that takes care of setting
112
+ up the sysroot. If you are using ` miri ` (the Miri driver) directly, see
113
+ [ below] [ testing-miri ] for how to set up the sysroot.
114
+
108
115
## Development and Debugging
109
116
110
117
If you want to hack on miri yourself, great! Here are some resources you might
@@ -113,90 +120,100 @@ find useful.
113
120
### Using a nightly rustc
114
121
115
122
Miri heavily relies on internal rustc interfaces to execute MIR. Still, some
116
- things (like adding support for a new intrinsic) can be done by working just on
117
- the Miri side.
118
-
119
- To prepare, make sure you are using a nightly Rust compiler. The most
120
- convenient way is to install Miri using cargo, then you can easily run it on
121
- other projects:
122
-
123
- ``` sh
124
- rustup component remove miri # avoid having Miri installed twice
125
- cargo +nightly install --path " $DIR " --force
126
- cargo +nightly miri setup
127
- ```
123
+ things (like adding support for a new intrinsic or a shim for an external
124
+ function being called) can be done by working just on the Miri side.
128
125
129
- (We are giving ` +nightly ` explicitly here all the time because it is important
130
- that all of these commands get executed with the same toolchain.)
126
+ To prepare, make sure you are using a nightly Rust compiler. Then you should be
127
+ able to just ` cargo build ` Miri.
131
128
132
129
In case this fails, your nightly might be incompatible with Miri master. The
133
130
` rust-version ` file contains the commit hash of rustc that Miri is currently
134
131
tested against; you can use that to find a nightly that works or you might have
135
132
to wait for the next nightly to get released.
136
133
137
- If you want to use a different libstd (not the one that comes with the
138
- nightly), you can do that by running
134
+ ### Testing the Miri driver
135
+ [ testing-miri ] : #testing-the-miri-driver
136
+
137
+ The Miri driver in the ` miri ` binary is the "heart" of Miri: it is basically a
138
+ version of ` rustc ` that, instead of compiling your code, runs it. It accepts
139
+ all the same flags as ` rustc ` (though the ones only affecting code generation
140
+ and linking obviously will have no effect) [ and more] [ miri-flags ] .
141
+
142
+ To run the Miri driver, you need to have the ` MIRI_SYSROOT ` environment variable
143
+ set to an appropriate sysroot. You can generate such a sysroot with the
144
+ following incantation:
139
145
140
- ``` sh
141
- XARGO_RUST_SRC= ~ /src/rust/rustc/src/ cargo +nightly miri setup
146
+ ```
147
+ cargo run --bin cargo-miri -- miri setup
142
148
```
143
149
144
- Either way, you can now do ` cargo +nightly miri run ` to run Miri with your
145
- local changes on whatever project you are debugging.
150
+ This basically runs the ` cargo-miri ` binary (which backs the ` cargo miri `
151
+ subcommand) with ` cargo ` , and asks it to ` setup ` . It should in the end print
152
+ the directory where the libstd was built. In the following, we will assume it
153
+ is ` ~/.cache/miri/HOST ` ; you may have to adjust that if you are not using Linux.
146
154
147
- ` cargo miri setup ` should end in printing the directory where the libstd was
148
- built. For the next step to work, set that as your ` MIRI_SYSROOT ` environment
149
- variable:
155
+ Now you can run the driver directly using
150
156
151
157
``` sh
152
- export MIRI_SYSROOT=~ /.cache/miri/HOST # or whatever the previous command said
158
+ MIRI_SYSROOT=~ /.cache/miri/HOST cargo run tests/run-pass/format.rs # or whatever test you like
153
159
```
154
160
155
- ### Testing Miri
156
-
157
- Instead of running an entire project using ` cargo miri ` , you can also use the
158
- Miri "driver" directly to run just a single file. That can be easier during
159
- debugging.
161
+ and you can run the test suite using
160
162
161
- ``` sh
162
- cargo run tests/run-pass/format.rs # or whatever test you like
163
163
```
164
+ cargo test
165
+ ```
166
+
167
+ We recommend adding the ` --release ` flag to make tests run faster.
164
168
165
- You can also run the test suite with ` cargo test --release ` . `cargo test
166
- --release FILTER` only runs those tests that contain ` FILTER` in their filename
167
- (including the base directory, e.g. ` cargo test --release fail ` will run all
168
- compile-fail tests). We recommend using ` --release ` to make test running take
169
- less time.
169
+ ` cargo test --release FILTER ` only runs those tests that contain ` FILTER ` in
170
+ their filename (including the base directory, e.g. ` cargo test --release fail `
171
+ will run all compile-fail tests).
170
172
171
- Now you are set up! You can write a failing test case, and tweak miri until it
172
- fails no more.
173
173
You can get a trace of which MIR statements are being executed by setting the
174
174
` MIRI_LOG ` environment variable. For example:
175
175
176
176
``` sh
177
177
MIRI_LOG=info cargo run tests/run-pass/vecs.rs
178
178
```
179
179
180
- Setting ` MIRI_LOG ` like this will configure logging for miri itself as well as
180
+ Setting ` MIRI_LOG ` like this will configure logging for Miri itself as well as
181
181
the ` rustc::mir::interpret ` and ` rustc_mir::interpret ` modules in rustc. You
182
- can also do more targeted configuration, e.g. to debug the stacked borrows
183
- implementation:
182
+ can also do more targeted configuration, e.g. the following helps debug the
183
+ stacked borrows implementation:
184
+
184
185
``` sh
185
186
MIRI_LOG=rustc_mir::interpret=info,miri::stacked_borrows cargo run tests/run-pass/vecs.rs
186
187
```
187
188
188
189
In addition, you can set ` MIRI_BACKTRACE=1 ` to get a backtrace of where an
189
- evaluation error was originally created.
190
+ evaluation error was originally raised.
191
+
192
+ ### Testing ` cargo miri `
193
+
194
+ Working with the driver directly gives you full control, but you also lose all
195
+ the convenience provided by cargo. Once your test case depends on a crate, it
196
+ is probably easier to test it with the cargo wrapper. You can install your
197
+ development version of Miri using
198
+
199
+ ```
200
+ cargo install --path . --force
201
+ ```
202
+
203
+ and then you can use it as if it was installed by ` rustup ` . Make sure you use
204
+ the same toolchain when calling ` cargo miri ` that you used when installing Miri!
190
205
206
+ There's a test for the cargo wrapper in the ` test-cargo-miri ` directory; run
207
+ ` ./run-test.py ` in there to execute it.
191
208
192
209
### Using a locally built rustc
193
210
194
- Since the heart of Miri ( the main interpreter engine) lives in rustc, working on
195
- Miri will often require using a locally built rustc. The bug you want to fix
196
- may actually be on the rustc side, or you just need to get more detailed trace
197
- of the execution than what is possible with release builds -- in both cases, you
198
- should develop miri against a rustc you compiled yourself, with debug assertions
199
- (and hence tracing) enabled.
211
+ A big part of the Miri driver lives in rustc, so working on Miri will sometimes
212
+ require using a locally built rustc. The bug you want to fix may actually be on
213
+ the rustc side, or you just need to get more detailed trace of the execution
214
+ than what is possible with release builds -- in both cases, you should develop
215
+ miri against a rustc you compiled yourself, with debug assertions (and hence
216
+ tracing) enabled.
200
217
201
218
The setup for a local rustc works as follows:
202
219
``` sh
@@ -216,18 +233,21 @@ rustup override set custom
216
233
```
217
234
218
235
With this, you should now have a working development setup! See
219
- [ "Testing Miri"] ( #testing-miri ) above for how to proceed.
236
+ [ above] [ testing-miri ] for how to proceed working with the Miri driver. Notice
237
+ that rustc's sysroot is already built for Miri in this case, so you can set
238
+ ` MIRI_SYSROOT=$(rustc --print sysroot) ` .
220
239
221
240
Running ` cargo miri ` in this setup is a bit more complicated, because the Miri
222
- binary you just created does not actually run without some environment variables.
223
- But you can contort cargo into calling ` cargo miri ` the right way for you :
241
+ binary you just created needs help to find the libraries it links against. On
242
+ Linux, you can set the rpath to make this "just work" :
224
243
225
244
``` sh
226
- # in some other project's directory, to run `cargo miri test`:
227
- MIRI_SYSROOT= $( rustc +custom --print sysroot ) cargo +custom run --manifest- path /path/to/miri/Cargo.toml --bin cargo-miri --release -- miri test
245
+ export RUSTFLAGS= " -C link-args=-Wl,-rpath, $( rustc --print sysroot ) /lib/rustlib/x86_64-unknown-linux-gnu/lib "
246
+ cargo install -- path . --force
228
247
```
229
248
230
249
### Miri ` -Z ` flags and environment variables
250
+ [ miri-flags ] : #miri--z-flags-and-environment-variables
231
251
232
252
Several ` -Z ` flags are relevant for Miri:
233
253
0 commit comments