@@ -15,6 +15,8 @@ for example:
15
15
or an invalid enum discriminant)
16
16
* ** Experimental** : Violations of the [ Stacked Borrows] rules governing aliasing
17
17
for reference types
18
+ * ** Experimental** : Violations of the Tree Borrows aliasing rules, as an optional
19
+ alternative to [ Stacked Borrows]
18
20
* ** Experimental** : Data races
19
21
20
22
On top of that, Miri will also tell you about memory leaks: when there is memory
@@ -225,6 +227,26 @@ degree documented below):
225
227
reduced feature set. We might ship Miri with a nightly even when some features
226
228
on these targets regress.
227
229
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
+
228
250
# ## Common Problems
229
251
230
252
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.
337
359
* `-Zmiri-disable-data-race-detector` disables checking for data races. Using
338
360
this flag is **unsound**. This implies `-Zmiri-disable-weak-memory-emulation`.
339
361
* `-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`.
343
367
* `-Zmiri-disable-validation` disables enforcing validity invariants, which are
344
368
enforced by default. This is mostly useful to focus on other failures (such
345
369
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.
401
425
* `-Zmiri-track-weak-memory-loads` shows a backtrace when weak memory emulation returns an outdated
402
426
value from a load. This can help diagnose problems that disappear under
403
427
` -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.
404
431
* `-Zmiri-force-page-size=<num>` overrides the default page size for an architecture, in multiples of 1k.
405
432
` 4` is default for most targets. This value should always be a power of 2 and nonzero.
406
433
@@ -415,7 +442,7 @@ Some native rustc `-Z` flags are also very relevant for Miri:
415
442
functions. This is needed so that Miri can execute such functions, so Miri
416
443
sets this flag per default.
417
444
* `-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 .
419
446
420
447
Moreover, Miri recognizes some environment variables :
421
448
@@ -481,120 +508,8 @@ binaries, and as such worth documenting:
481
508
# # Miri `extern` functions
482
509
483
510
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).
598
513
599
514
# # Contributing and getting help
600
515
0 commit comments