Skip to content

Commit d9950aa

Browse files
authored
Merge pull request #19826 from lnicola/sync-from-rust
minor: Sync from downstream
2 parents 17f4962 + be12fb7 commit d9950aa

File tree

270 files changed

+2128
-1879
lines changed

Some content is hidden

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

270 files changed

+2128
-1879
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ tex/*/out
99
*.mm_profdata
1010
perf.data
1111
perf.data.old
12-
flamegraph.svg
12+
flamegraph*.svg
13+
rustc-ice*.txt
1314
tests/native-lib/libtestlib.so
1415
.auto-*
16+
17+
/genmc/

CONTRIBUTING.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,10 @@ When you get a review, please take care of the requested changes in new commits.
1919
existing commits. Generally avoid force-pushing. The only time you should force push is when there
2020
is a conflict with the master branch (in that case you should rebase across master, not merge), and
2121
all the way at the end of the review process when the reviewer tells you that the PR is done and you
22-
should squash the commits. For the latter case, use `git rebase --keep-base ...` to squash without
23-
changing the base commit your PR branches off of. Use your own judgment and the reviewer's guidance
24-
to decide whether the PR should be squashed into a single commit or multiple logically separate
25-
commits. (All this is to work around the fact that Github is quite bad at dealing with force pushes
26-
and does not support `git range-diff`. Maybe one day Github will be good at git and then life can
27-
become easier.)
22+
should squash the commits. If you are unsure how to use `git rebase` to squash commits, use `./miri
23+
squash` which automates the process but leaves little room for customization. (All this is to work
24+
around the fact that Github is quite bad at dealing with force pushes and does not support `git
25+
range-diff`. Maybe one day Github will be good at git and then life can become easier.)
2826

2927
Most PRs bounce back and forth between the reviewer and the author several times, so it is good to
3028
keep track of who is expected to take the next step. We are using the `S-waiting-for-review` and

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ name = "miri"
66
repository = "https://github.com/rust-lang/miri"
77
version = "0.1.0"
88
default-run = "miri"
9-
edition = "2021"
9+
edition = "2024"
1010

1111
[lib]
1212
test = true # we have unit tests
@@ -65,6 +65,7 @@ harness = false
6565

6666
[features]
6767
default = ["stack-cache"]
68+
genmc = []
6869
stack-cache = []
6970
stack-cache-consistency-check = ["stack-cache"]
7071

README.md

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -277,22 +277,15 @@ Try running `cargo miri clean`.
277277
Miri adds its own set of `-Z` flags, which are usually set via the `MIRIFLAGS`
278278
environment variable. We first document the most relevant and most commonly used flags:
279279

280-
* `-Zmiri-address-reuse-rate=<rate>` changes the probability that a freed *non-stack* allocation
281-
will be added to the pool for address reuse, and the probability that a new *non-stack* allocation
282-
will be taken from the pool. Stack allocations never get added to or taken from the pool. The
283-
default is `0.5`.
284-
* `-Zmiri-address-reuse-cross-thread-rate=<rate>` changes the probability that an allocation which
285-
attempts to reuse a previously freed block of memory will also consider blocks freed by *other
286-
threads*. The default is `0.1`, which means by default, in 90% of the cases where an address reuse
287-
attempt is made, only addresses from the same thread will be considered. Reusing an address from
288-
another thread induces synchronization between those threads, which can mask data races and weak
289-
memory bugs.
290-
* `-Zmiri-compare-exchange-weak-failure-rate=<rate>` changes the failure rate of
291-
`compare_exchange_weak` operations. The default is `0.8` (so 4 out of 5 weak ops will fail).
292-
You can change it to any value between `0.0` and `1.0`, where `1.0` means it
293-
will always fail and `0.0` means it will never fail. Note that setting it to
294-
`1.0` will likely cause hangs, since it means programs using
295-
`compare_exchange_weak` cannot make progress.
280+
* `-Zmiri-deterministic-concurrency` makes Miri's concurrency-related behavior fully deterministic.
281+
Strictly speaking, Miri is always fully deterministic when isolation is enabled (the default
282+
mode), but this determinism is achieved by using an RNG with a fixed seed. Seemingly harmless
283+
changes to the program, or just running it for a different target architecture, can thus lead to
284+
completely different program behavior down the line. This flag disables the use of an RNG for
285+
concurrency-related decisions. Therefore, Miri cannot find bugs that only occur under some
286+
specific circumstances, but Miri's behavior will also be more stable across versions and targets.
287+
This is equivalent to `-Zmiri-fixed-schedule -Zmiri-compare-exchange-weak-failure-rate=0.0
288+
-Zmiri-address-reuse-cross-thread-rate=0.0 -Zmiri-disable-weak-memory-emulation`.
296289
* `-Zmiri-disable-isolation` disables host isolation. As a consequence,
297290
the program has access to host resources such as environment variables, file
298291
systems, and randomness.
@@ -334,9 +327,6 @@ environment variable. We first document the most relevant and most commonly used
334327
This will necessarily miss some bugs as those operations are not efficiently and accurately
335328
implementable in a sanitizer, but it will only miss bugs that concern memory/pointers which is
336329
subject to these operations.
337-
* `-Zmiri-preemption-rate` configures the probability that at the end of a basic block, the active
338-
thread will be preempted. The default is `0.01` (i.e., 1%). Setting this to `0` disables
339-
preemption.
340330
* `-Zmiri-report-progress` makes Miri print the current stacktrace every now and then, so you can
341331
tell what it is doing when a program just keeps running. You can customize how frequently the
342332
report is printed via `-Zmiri-report-progress=<blocks>`, which prints the report every N basic
@@ -365,6 +355,22 @@ The remaining flags are for advanced use only, and more likely to change or be r
365355
Some of these are **unsound**, which means they can lead
366356
to Miri failing to detect cases of undefined behavior in a program.
367357

358+
* `-Zmiri-address-reuse-rate=<rate>` changes the probability that a freed *non-stack* allocation
359+
will be added to the pool for address reuse, and the probability that a new *non-stack* allocation
360+
will be taken from the pool. Stack allocations never get added to or taken from the pool. The
361+
default is `0.5`.
362+
* `-Zmiri-address-reuse-cross-thread-rate=<rate>` changes the probability that an allocation which
363+
attempts to reuse a previously freed block of memory will also consider blocks freed by *other
364+
threads*. The default is `0.1`, which means by default, in 90% of the cases where an address reuse
365+
attempt is made, only addresses from the same thread will be considered. Reusing an address from
366+
another thread induces synchronization between those threads, which can mask data races and weak
367+
memory bugs.
368+
* `-Zmiri-compare-exchange-weak-failure-rate=<rate>` changes the failure rate of
369+
`compare_exchange_weak` operations. The default is `0.8` (so 4 out of 5 weak ops will fail).
370+
You can change it to any value between `0.0` and `1.0`, where `1.0` means it
371+
will always fail and `0.0` means it will never fail. Note that setting it to
372+
`1.0` will likely cause hangs, since it means programs using
373+
`compare_exchange_weak` cannot make progress.
368374
* `-Zmiri-disable-alignment-check` disables checking pointer alignment, so you
369375
can focus on other failures, but it means Miri can miss bugs in your program.
370376
Using this flag is **unsound**.
@@ -383,6 +389,13 @@ to Miri failing to detect cases of undefined behavior in a program.
383389
this flag is **unsound**.
384390
* `-Zmiri-disable-weak-memory-emulation` disables the emulation of some C++11 weak
385391
memory effects.
392+
* `-Zmiri-fixed-schedule` disables preemption (like `-Zmiri-preemption-rate=0.0`) and furthermore
393+
disables the randomization of the next thread to be picked, instead fixing a round-robin schedule.
394+
Note however that other aspects of Miri's concurrency behavior are still randomize; use
395+
`-Zmiri-deterministic-concurrency` to disable them all.
396+
* `-Zmiri-force-intrinsic-fallback` forces the use of the "fallback" body for all intrinsics that
397+
have one. This is useful to test the fallback bodies, but should not be used otherwise. It is
398+
**unsound** since the fallback body might not be checking for all UB.
386399
* `-Zmiri-native-lib=<path to a shared object file>` is an experimental flag for providing support
387400
for calling native functions from inside the interpreter via FFI. The flag is supported only on
388401
Unix systems. Functions not provided by that file are still executed via the usual Miri shims.
@@ -412,6 +425,10 @@ to Miri failing to detect cases of undefined behavior in a program.
412425
without an explicit value), `none` means it never recurses, `scalar` means it only recurses for
413426
types where we would also emit `noalias` annotations in the generated LLVM IR (types passed as
414427
individual scalars or pairs of scalars). Setting this to `none` is **unsound**.
428+
* `-Zmiri-preemption-rate` configures the probability that at the end of a basic block, the active
429+
thread will be preempted. The default is `0.01` (i.e., 1%). Setting this to `0` disables
430+
preemption. Note that even without preemption, the schedule is still non-deterministic:
431+
if a thread blocks or yields, the next thread is chosen randomly.
415432
* `-Zmiri-provenance-gc=<blocks>` configures how often the pointer provenance garbage collector runs.
416433
The default is to search for and remove unreachable provenance once every `10000` basic blocks. Setting
417434
this to `0` disables the garbage collector, which causes some programs to have explosive memory
@@ -443,9 +460,6 @@ to Miri failing to detect cases of undefined behavior in a program.
443460
casts are not supported in this mode, but that may change in the future.
444461
* `-Zmiri-force-page-size=<num>` overrides the default page size for an architecture, in multiples of 1k.
445462
`4` is default for most targets. This value should always be a power of 2 and nonzero.
446-
* `-Zmiri-unique-is-unique` performs additional aliasing checks for `core::ptr::Unique` to ensure
447-
that it could theoretically be considered `noalias`. This flag is experimental and has
448-
an effect only when used with `-Zmiri-tree-borrows`.
449463

450464
[function ABI]: https://doc.rust-lang.org/reference/items/functions.html#extern-function-qualifier
451465

@@ -566,6 +580,7 @@ Definite bugs found:
566580
* [Weak-memory-induced memory leak in Windows thread-local storage](https://github.com/rust-lang/rust/pull/124281)
567581
* [A bug in the new `RwLock::downgrade` implementation](https://rust-lang.zulipchat.com/#narrow/channel/269128-miri/topic/Miri.20error.20library.20test) (caught by Miri before it landed in the Rust repo)
568582
* [Mockall reading unintialized memory when mocking `std::io::Read::read`, even if all expectations are satisfied](https://github.com/asomers/mockall/issues/647) (caught by Miri running Tokio's test suite)
583+
* [`ReentrantLock` not correctly dealing with reuse of addresses for TLS storage of different threads](https://github.com/rust-lang/rust/pull/141248)
569584

570585
Violations of [Stacked Borrows] found that are likely bugs (but Stacked Borrows is currently just an experiment):
571586

bench-cargo-miri/big-allocs/src/main.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@ fn main() {
77
// We can't use too big of an allocation or this code will encounter an allocation failure in
88
// CI. Since the allocation can't be huge, we need to do a few iterations so that the effect
99
// we're trying to measure is clearly visible above the interpreter's startup time.
10-
// FIXME (https://github.com/rust-lang/miri/issues/4253): On 32bit targets, we can run out of
11-
// usable addresses if we don't reuse, leading to random test failures.
12-
let count = if cfg!(target_pointer_width = "32") { 8 } else { 12 };
13-
for _ in 0..count {
10+
for _ in 0..20 {
1411
drop(Vec::<u8>::with_capacity(512 * 1024 * 1024));
1512
}
1613
}

cargo-miri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ license = "MIT OR Apache-2.0"
55
name = "cargo-miri"
66
repository = "https://github.com/rust-lang/miri"
77
version = "0.1.0"
8-
edition = "2021"
8+
edition = "2024"
99

1010
[[bin]]
1111
name = "cargo-miri"

cargo-miri/src/main.rs

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,27 +63,37 @@ fn main() {
6363
return;
6464
}
6565

66+
let Some(first) = args.next() else {
67+
show_error!(
68+
"`cargo-miri` called without first argument; please only invoke this binary through `cargo miri`"
69+
)
70+
};
71+
6672
// The way rustdoc invokes rustc is indistinguishable from the way cargo invokes rustdoc by the
6773
// arguments alone. `phase_cargo_rustdoc` sets this environment variable to let us disambiguate.
6874
if env::var_os("MIRI_CALLED_FROM_RUSTDOC").is_some() {
6975
// ...however, we then also see this variable when rustdoc invokes us as the testrunner!
70-
// The runner is invoked as `$runtool ($runtool-arg)* output_file`;
71-
// since we don't specify any runtool-args, and rustdoc supplies multiple arguments to
72-
// the test-builder unconditionally, we can just check the number of remaining arguments:
73-
if args.len() == 1 {
74-
phase_runner(args, RunnerPhase::Rustdoc);
75-
} else {
76-
phase_rustc(args, RustcPhase::Rustdoc);
76+
// In that case the first argument is `runner` and there are no more arguments.
77+
match first.as_str() {
78+
"runner" => phase_runner(args, RunnerPhase::Rustdoc),
79+
flag if flag.starts_with("--") || flag.starts_with("@") => {
80+
// This is probably rustdoc invoking us to build the test. But we need to get `first`
81+
// "back onto the iterator", it is some part of the rustc invocation.
82+
phase_rustc(iter::once(first).chain(args), RustcPhase::Rustdoc);
83+
}
84+
_ => {
85+
show_error!(
86+
"`cargo-miri` failed to recognize which phase of the build process this is, please report a bug.\n\
87+
We are inside MIRI_CALLED_FROM_RUSTDOC.\n\
88+
The command-line arguments were: {:#?}",
89+
Vec::from_iter(env::args()),
90+
);
91+
}
7792
}
7893

7994
return;
8095
}
8196

82-
let Some(first) = args.next() else {
83-
show_error!(
84-
"`cargo-miri` called without first argument; please only invoke this binary through `cargo miri`"
85-
)
86-
};
8797
match first.as_str() {
8898
"miri" => phase_cargo_miri(args),
8999
"runner" => phase_runner(args, RunnerPhase::Cargo),

cargo-miri/src/phases.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,11 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
176176
// Set `--target-dir` to `miri` inside the original target directory.
177177
let target_dir = get_target_dir(&metadata);
178178
cmd.arg("--target-dir").arg(target_dir);
179+
// Only when running in x.py (where we are running with beta cargo): set `RUSTC_STAGE`.
180+
// Will have to be removed on next bootstrap bump. tag: cfg(bootstrap).
181+
if env::var_os("RUSTC_STAGE").is_some() {
182+
cmd.arg("-Zdoctest-xcompile");
183+
}
179184

180185
// *After* we set all the flags that need setting, forward everything else. Make sure to skip
181186
// `--target-dir` (which would otherwise be set twice).
@@ -666,11 +671,6 @@ pub fn phase_rustdoc(mut args: impl Iterator<Item = String>) {
666671
if arg == "--extern" {
667672
// Patch --extern arguments to use *.rmeta files, since phase_cargo_rustc only creates stub *.rlib files.
668673
forward_patched_extern_arg(&mut args, &mut cmd);
669-
} else if arg == "--test-runtool" {
670-
// An existing --test-runtool flag indicates cargo is running in cross-target mode, which we don't support.
671-
// Note that this is only passed when cargo is run with the unstable -Zdoctest-xcompile flag;
672-
// otherwise, we won't be called as rustdoc at all.
673-
show_error!("cross-interpreting doctests is not currently supported by Miri.");
674674
} else {
675675
cmd.arg(arg);
676676
}
@@ -702,10 +702,10 @@ pub fn phase_rustdoc(mut args: impl Iterator<Item = String>) {
702702
// make sure the 'miri' flag is set for rustdoc
703703
cmd.arg("--cfg").arg("miri");
704704

705-
// Make rustdoc call us back.
705+
// Make rustdoc call us back for the build.
706+
// (cargo already sets `--test-runtool` to us since we are the cargo test runner.)
706707
let cargo_miri_path = env::current_exe().expect("current executable path invalid");
707708
cmd.arg("--test-builder").arg(&cargo_miri_path); // invoked by forwarding most arguments
708-
cmd.arg("--test-runtool").arg(&cargo_miri_path); // invoked with just a single path argument
709709

710710
debug_cmd("[cargo-miri rustdoc]", verbose, &cmd);
711711
exec(cmd)

cargo-miri/src/setup.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,9 @@ pub fn setup(
2424
let ask_user = !only_setup;
2525
let print_sysroot = only_setup && has_arg_flag("--print-sysroot"); // whether we just print the sysroot path
2626
let show_setup = only_setup && !print_sysroot;
27-
if !only_setup {
28-
if let Some(sysroot) = std::env::var_os("MIRI_SYSROOT") {
29-
// Skip setup step if MIRI_SYSROOT is explicitly set, *unless* we are `cargo miri setup`.
30-
return sysroot.into();
31-
}
27+
if !only_setup && let Some(sysroot) = std::env::var_os("MIRI_SYSROOT") {
28+
// Skip setup step if MIRI_SYSROOT is explicitly set, *unless* we are `cargo miri setup`.
29+
return sysroot.into();
3230
}
3331

3432
// Determine where the rust sources are located. The env var trumps auto-detection.

miri-script/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ name = "miri-script"
66
repository = "https://github.com/rust-lang/miri"
77
version = "0.1.0"
88
default-run = "miri-script"
9-
edition = "2021"
9+
edition = "2024"
1010

1111
[workspace]
1212
# We make this a workspace root so that cargo does not go looking in ../Cargo.toml for the workspace root.

0 commit comments

Comments
 (0)