Skip to content

Commit c50c62d

Browse files
committed
Auto merge of #109241 - saethlin:miri, r=oli-obk
update Miri r? `@oli-obk`
2 parents 2d64f22 + 3831a25 commit c50c62d

File tree

111 files changed

+3785
-203
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+3785
-203
lines changed

src/tools/miri/.github/workflows/ci.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ jobs:
5454
# contains package information of crates installed via `cargo install`.
5555
~/.cargo/.crates.toml
5656
~/.cargo/.crates2.json
57-
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
58-
restore-keys: ${{ runner.os }}-cargo
57+
key: ${{ runner.os }}-cargo-reset20230315-${{ hashFiles('**/Cargo.lock') }}
58+
restore-keys: ${{ runner.os }}-cargo-reset20230315
5959

6060
- name: Install rustup-toolchain-install-master
6161
if: ${{ steps.cache.outputs.cache-hit != 'true' }}
@@ -106,8 +106,8 @@ jobs:
106106
# contains package information of crates installed via `cargo install`.
107107
~/.cargo/.crates.toml
108108
~/.cargo/.crates2.json
109-
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
110-
restore-keys: ${{ runner.os }}-cargo
109+
key: ${{ runner.os }}-cargo-reset20230315-${{ hashFiles('**/Cargo.lock') }}
110+
restore-keys: ${{ runner.os }}-cargo-reset20230315
111111

112112
- name: Install rustup-toolchain-install-master
113113
if: ${{ steps.cache.outputs.cache-hit != 'true' }}

src/tools/miri/CONTRIBUTING.md

+4-7
Original file line numberDiff line numberDiff line change
@@ -129,18 +129,15 @@ development version of Miri using
129129
./miri install
130130
```
131131

132-
and then you can use it as if it was installed by `rustup`. Make sure you use
133-
the same toolchain when calling `cargo miri` that you used when installing Miri!
134-
Usually this means you have to write `cargo +miri miri ...` to select the `miri`
135-
toolchain that was installed by `./miri toolchain`.
132+
and then you can use it as if it was installed by `rustup` as a component of the
133+
`miri` toolchain. Note that the `miri` and `cargo-miri` executables are placed
134+
in the `miri` toolchain's sysroot to prevent conflicts with other toolchains.
135+
The Miri binaries in the `cargo` bin directory (usually `~/.cargo/bin`) are managed by rustup.
136136

137137
There's a test for the cargo wrapper in the `test-cargo-miri` directory; run
138138
`./run-test.py` in there to execute it. Like `./miri test`, this respects the
139139
`MIRI_TEST_TARGET` environment variable to execute the test for another target.
140140

141-
Note that installing Miri like this will "take away" Miri management from `rustup`.
142-
If you want to later go back to a rustup-installed Miri, run `rustup update`.
143-
144141
### Using a modified standard library
145142

146143
Miri re-builds the standard library into a custom sysroot, so it is fairly easy

src/tools/miri/README.md

+33-118
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ for example:
1515
or an invalid enum discriminant)
1616
* **Experimental**: Violations of the [Stacked Borrows] rules governing aliasing
1717
for reference types
18+
* **Experimental**: Violations of the Tree Borrows aliasing rules, as an optional
19+
alternative to [Stacked Borrows]
1820
* **Experimental**: Data races
1921

2022
On top of that, Miri will also tell you about memory leaks: when there is memory
@@ -225,6 +227,26 @@ degree documented below):
225227
reduced feature set. We might ship Miri with a nightly even when some features
226228
on these targets regress.
227229

230+
### Running tests in parallel
231+
232+
Though it implements Rust threading, Miri itself is a single-threaded interpreter.
233+
This means that when running `cargo miri test`, you will probably see a dramatic
234+
increase in the amount of time it takes to run your whole test suite due to the
235+
inherent interpreter slowdown and a loss of parallelism.
236+
237+
You can get your test suite's parallelism back by running `cargo miri nextest run -jN`
238+
(note that you will need [`cargo-nextest`](https://nexte.st) installed).
239+
This works because `cargo-nextest` collects a list of all tests then launches a
240+
separate `cargo miri run` for each test. You will need to specify a `-j` or `--test-threads`;
241+
by default `cargo miri nextest run` runs one test at a time. For more details, see the
242+
[`cargo-nextest` Miri documentation](https://nexte.st/book/miri.html).
243+
244+
Note: This one-test-per-process model means that `cargo miri test` is able to detect data
245+
races where two tests race on a shared resource, but `cargo miri nextest run` will not detect
246+
such races.
247+
248+
Note: `cargo-nextest` does not support doctests, see https://github.com/nextest-rs/nextest/issues/16
249+
228250
### Common Problems
229251

230252
When using the above instructions, you may encounter a number of confusing compiler
@@ -337,9 +359,11 @@ to Miri failing to detect cases of undefined behavior in a program.
337359
* `-Zmiri-disable-data-race-detector` disables checking for data races. Using
338360
this flag is **unsound**. This implies `-Zmiri-disable-weak-memory-emulation`.
339361
* `-Zmiri-disable-stacked-borrows` disables checking the experimental
340-
[Stacked Borrows] aliasing rules. This can make Miri run faster, but it also
341-
means no aliasing violations will be detected. Using this flag is **unsound**
342-
(but the affected soundness rules are experimental).
362+
aliasing rules to track borrows ([Stacked Borrows] and Tree Borrows).
363+
This can make Miri run faster, but it also means no aliasing violations will
364+
be detected. Using this flag is **unsound** (but the affected soundness rules
365+
are experimental). Later flags take precedence: borrow tracking can be reactivated
366+
by `-Zmiri-tree-borrows`.
343367
* `-Zmiri-disable-validation` disables enforcing validity invariants, which are
344368
enforced by default. This is mostly useful to focus on other failures (such
345369
as out-of-bounds accesses) first. Setting this flag means Miri can miss bugs
@@ -401,6 +425,9 @@ to Miri failing to detect cases of undefined behavior in a program.
401425
* `-Zmiri-track-weak-memory-loads` shows a backtrace when weak memory emulation returns an outdated
402426
value from a load. This can help diagnose problems that disappear under
403427
`-Zmiri-disable-weak-memory-emulation`.
428+
* `-Zmiri-tree-borrows` replaces [Stacked Borrows] with the Tree Borrows rules.
429+
The soundness rules are already experimental without this flag, but even more
430+
so with this flag.
404431
* `-Zmiri-force-page-size=<num>` overrides the default page size for an architecture, in multiples of 1k.
405432
`4` is default for most targets. This value should always be a power of 2 and nonzero.
406433

@@ -415,7 +442,7 @@ Some native rustc `-Z` flags are also very relevant for Miri:
415442
functions. This is needed so that Miri can execute such functions, so Miri
416443
sets this flag per default.
417444
* `-Zmir-emit-retag` controls whether `Retag` statements are emitted. Miri
418-
enables this per default because it is needed for [Stacked Borrows].
445+
enables this per default because it is needed for [Stacked Borrows] and Tree Borrows.
419446

420447
Moreover, Miri recognizes some environment variables:
421448

@@ -481,120 +508,8 @@ binaries, and as such worth documenting:
481508
## Miri `extern` functions
482509

483510
Miri provides some `extern` functions that programs can import to access
484-
Miri-specific functionality:
485-
486-
```rust
487-
#[cfg(miri)]
488-
extern "Rust" {
489-
/// Miri-provided extern function to mark the block `ptr` points to as a "root"
490-
/// for some static memory. This memory and everything reachable by it is not
491-
/// considered leaking even if it still exists when the program terminates.
492-
///
493-
/// `ptr` has to point to the beginning of an allocated block.
494-
fn miri_static_root(ptr: *const u8);
495-
496-
// Miri-provided extern function to get the amount of frames in the current backtrace.
497-
// The `flags` argument must be `0`.
498-
fn miri_backtrace_size(flags: u64) -> usize;
499-
500-
/// Miri-provided extern function to obtain a backtrace of the current call stack.
501-
/// This writes a slice of pointers into `buf` - each pointer is an opaque value
502-
/// that is only useful when passed to `miri_resolve_frame`.
503-
/// `buf` must have `miri_backtrace_size(0) * pointer_size` bytes of space.
504-
/// The `flags` argument must be `1`.
505-
fn miri_get_backtrace(flags: u64, buf: *mut *mut ());
506-
507-
/// Miri-provided extern function to resolve a frame pointer obtained
508-
/// from `miri_get_backtrace`. The `flags` argument must be `1`,
509-
/// and `MiriFrame` should be declared as follows:
510-
///
511-
/// ```rust
512-
/// #[repr(C)]
513-
/// struct MiriFrame {
514-
/// // The size of the name of the function being executed, encoded in UTF-8
515-
/// name_len: usize,
516-
/// // The size of filename of the function being executed, encoded in UTF-8
517-
/// filename_len: usize,
518-
/// // The line number currently being executed in `filename`, starting from '1'.
519-
/// lineno: u32,
520-
/// // The column number currently being executed in `filename`, starting from '1'.
521-
/// colno: u32,
522-
/// // The function pointer to the function currently being executed.
523-
/// // This can be compared against function pointers obtained by
524-
/// // casting a function (e.g. `my_fn as *mut ()`)
525-
/// fn_ptr: *mut ()
526-
/// }
527-
/// ```
528-
///
529-
/// The fields must be declared in exactly the same order as they appear in `MiriFrame` above.
530-
/// This function can be called on any thread (not just the one which obtained `frame`).
531-
fn miri_resolve_frame(frame: *mut (), flags: u64) -> MiriFrame;
532-
533-
/// Miri-provided extern function to get the name and filename of the frame provided by `miri_resolve_frame`.
534-
/// `name_buf` and `filename_buf` should be allocated with the `name_len` and `filename_len` fields of `MiriFrame`.
535-
/// The flags argument must be `0`.
536-
fn miri_resolve_frame_names(ptr: *mut (), flags: u64, name_buf: *mut u8, filename_buf: *mut u8);
537-
538-
/// Miri-provided extern function to begin unwinding with the given payload.
539-
///
540-
/// This is internal and unstable and should not be used; we give it here
541-
/// just to be complete.
542-
fn miri_start_panic(payload: *mut u8) -> !;
543-
544-
/// Miri-provided extern function to get the internal unique identifier for the allocation that a pointer
545-
/// points to. If this pointer is invalid (not pointing to an allocation), interpretation will abort.
546-
///
547-
/// This is only useful as an input to `miri_print_borrow_stacks`, and it is a separate call because
548-
/// getting a pointer to an allocation at runtime can change the borrow stacks in the allocation.
549-
/// This function should be considered unstable. It exists only to support `miri_print_borrow_stacks` and so
550-
/// inherits all of its instability.
551-
fn miri_get_alloc_id(ptr: *const ()) -> u64;
552-
553-
/// Miri-provided extern function to print (from the interpreter, not the program) the contents of all
554-
/// borrow stacks in an allocation. The leftmost tag is the bottom of the stack.
555-
/// The format of what this emits is unstable and may change at any time. In particular, users should be
556-
/// aware that Miri will periodically attempt to garbage collect the contents of all stacks. Callers of
557-
/// this function may wish to pass `-Zmiri-tag-gc=0` to disable the GC.
558-
///
559-
/// This function is extremely unstable. At any time the format of its output may change, its signature may
560-
/// change, or it may be removed entirely.
561-
fn miri_print_borrow_stacks(alloc_id: u64);
562-
563-
/// Miri-provided extern function to print (from the interpreter, not the
564-
/// program) the contents of a section of program memory, as bytes. Bytes
565-
/// written using this function will emerge from the interpreter's stdout.
566-
fn miri_write_to_stdout(bytes: &[u8]);
567-
568-
/// Miri-provided extern function to print (from the interpreter, not the
569-
/// program) the contents of a section of program memory, as bytes. Bytes
570-
/// written using this function will emerge from the interpreter's stderr.
571-
fn miri_write_to_stderr(bytes: &[u8]);
572-
573-
/// Miri-provided extern function to allocate memory from the interpreter.
574-
///
575-
/// This is useful when no fundamental way of allocating memory is
576-
/// available, e.g. when using `no_std` + `alloc`.
577-
fn miri_alloc(size: usize, align: usize) -> *mut u8;
578-
579-
/// Miri-provided extern function to deallocate memory.
580-
fn miri_dealloc(ptr: *mut u8, size: usize, align: usize);
581-
582-
/// Convert a path from the host Miri runs on to the target Miri interprets.
583-
/// Performs conversion of path separators as needed.
584-
///
585-
/// Usually Miri performs this kind of conversion automatically. However, manual conversion
586-
/// might be necessary when reading an environment variable that was set on the host
587-
/// (such as TMPDIR) and using it as a target path.
588-
///
589-
/// Only works with isolation disabled.
590-
///
591-
/// `in` must point to a null-terminated string, and will be read as the input host path.
592-
/// `out` must point to at least `out_size` many bytes, and the result will be stored there
593-
/// with a null terminator.
594-
/// Returns 0 if the `out` buffer was large enough, and the required size otherwise.
595-
fn miri_host_to_target_path(path: *const std::ffi::c_char, out: *mut std::ffi::c_char, out_size: usize) -> usize;
596-
}
597-
```
511+
Miri-specific functionality. They are declared in
512+
[/tests/utils/miri\_extern.rs](/tests/utils/miri_extern.rs).
598513

599514
## Contributing and getting help
600515

src/tools/miri/ci.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ function run_tests {
6262
if [ "$HOST_TARGET" = x86_64-unknown-linux-gnu ]; then
6363
# These act up on Windows (`which miri` produces a filename that does not exist?!?),
6464
# so let's do this only on Linux. Also makes sure things work without these set.
65-
export RUSTC=$(which rustc)
66-
export MIRI=$(which miri)
65+
export RUSTC=$(which rustc) # Produces a warning unless we also set MIRI
66+
export MIRI=$(rustc +miri --print sysroot)/bin/miri
6767
fi
6868
mkdir -p .cargo
6969
echo 'build.rustc-wrapper = "thisdoesnotexist"' > .cargo/config.toml

src/tools/miri/miri

+5-4
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ USAGE=$(cat <<"EOF"
66
./miri install <flags>:
77
Installs the miri driver and cargo-miri. <flags> are passed to `cargo
88
install`. Sets up the rpath such that the installed binary should work in any
9-
working directory. However, the rustup toolchain when invoking `cargo miri`
10-
needs to be the same one used for `./miri install`.
9+
working directory. Note that the binaries are placed in the `miri` toolchain
10+
sysroot, to prevent conflicts with other toolchains.
1111
1212
./miri build <flags>:
1313
Just build miri. <flags> are passed to `cargo build`.
@@ -281,8 +281,9 @@ find_sysroot() {
281281
case "$COMMAND" in
282282
install)
283283
# "--locked" to respect the Cargo.lock file if it exists.
284-
$CARGO install $CARGO_EXTRA_FLAGS --path "$MIRIDIR" --force --locked "$@"
285-
$CARGO install $CARGO_EXTRA_FLAGS --path "$MIRIDIR"/cargo-miri --force --locked "$@"
284+
# Install binaries to the miri toolchain's sysroot so they do not interact with other toolchains.
285+
$CARGO install $CARGO_EXTRA_FLAGS --path "$MIRIDIR" --force --locked --root "$SYSROOT" "$@"
286+
$CARGO install $CARGO_EXTRA_FLAGS --path "$MIRIDIR"/cargo-miri --force --locked --root "$SYSROOT" "$@"
286287
;;
287288
check)
288289
# Check, and let caller control flags.

src/tools/miri/rust-version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
c4e0cd966062ca67daed20775f4e8a60c28e57df
1+
511364e7874dba9649a264100407e4bffe7b5425

src/tools/miri/src/bin/miri.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use rustc_middle::{
3232
};
3333
use rustc_session::{config::CrateType, search_paths::PathKind, CtfeBacktrace};
3434

35-
use miri::{BacktraceStyle, ProvenanceMode, RetagFields};
35+
use miri::{BacktraceStyle, BorrowTrackerMethod, ProvenanceMode, RetagFields};
3636

3737
struct MiriCompilerCalls {
3838
miri_config: miri::MiriConfig,
@@ -317,6 +317,8 @@ fn main() {
317317
miri_config.validate = false;
318318
} else if arg == "-Zmiri-disable-stacked-borrows" {
319319
miri_config.borrow_tracker = None;
320+
} else if arg == "-Zmiri-tree-borrows" {
321+
miri_config.borrow_tracker = Some(BorrowTrackerMethod::TreeBorrows);
320322
} else if arg == "-Zmiri-disable-data-race-detector" {
321323
miri_config.data_race_detector = false;
322324
miri_config.weak_memory_emulation = false;

0 commit comments

Comments
 (0)