Skip to content

Commit

Permalink
Auto merge of rust-lang#110168 - saethlin:miri, r=RalfJung
Browse files Browse the repository at this point in the history
update Miri

Most importantly, this should ensure that the Miri test suite passes in this repo, when the issue is fixed.

r? `@oli-obk`
  • Loading branch information
bors committed Apr 11, 2023
2 parents 5072826 + d50fee9 commit 8e1162f
Show file tree
Hide file tree
Showing 23 changed files with 105 additions and 63 deletions.
7 changes: 6 additions & 1 deletion src/tools/miri/.github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,12 @@ jobs:
~/.local/bin/zulip-send --stream miri --subject "Cron Job Failure (miri, $(date -u +%Y-%m))" \
--message 'Dear @*T-miri*,
It would appear that the Miri cron job build failed. Would you mind investigating this issue?
It would appear that the [Miri cron job build]('"https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"') failed.
This likely means that rustc changed the miri directory and
we now need to do a [`./miri rustc-pull`](https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md#importing-changes-from-the-rustc-repo).
Would you mind investigating this issue?
Thanks in advance!
Sincerely,
Expand Down
8 changes: 4 additions & 4 deletions src/tools/miri/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -282,19 +282,19 @@ checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"

[[package]]
name = "libffi"
version = "3.0.1"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e454b3efb16fba3b17810ae5e41df02b649e564ab3c5a34b3b93ed07ad287e6"
checksum = "ce826c243048e3d5cec441799724de52e2d42f820468431fc3fceee2341871e2"
dependencies = [
"libc",
"libffi-sys",
]

[[package]]
name = "libffi-sys"
version = "2.0.1"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84e78d02e5a8eae9c24c38ce6e6026f80e16dff76adcdae4bc5c6c52c2de4a60"
checksum = "dc65067b78c0fc069771e8b9a9e02df71e08858bec92c1f101377c67b9dca7c7"
dependencies = [
"cc",
]
Expand Down
9 changes: 5 additions & 4 deletions src/tools/miri/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ for example:
or an invalid enum discriminant)
* **Experimental**: Violations of the [Stacked Borrows] rules governing aliasing
for reference types
* **Experimental**: Violations of the Tree Borrows aliasing rules, as an optional
* **Experimental**: Violations of the [Tree Borrows] aliasing rules, as an optional
alternative to [Stacked Borrows]
* **Experimental**: Data races

Expand Down Expand Up @@ -79,6 +79,7 @@ behavior** in your program, and cannot run all programs:
[`unreachable_unchecked`]: https://doc.rust-lang.org/stable/std/hint/fn.unreachable_unchecked.html
[`copy_nonoverlapping`]: https://doc.rust-lang.org/stable/std/ptr/fn.copy_nonoverlapping.html
[Stacked Borrows]: https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md
[Tree Borrows]: https://perso.crans.org/vanille/treebor/


## Using Miri
Expand Down Expand Up @@ -359,7 +360,7 @@ to Miri failing to detect cases of undefined behavior in a program.
* `-Zmiri-disable-data-race-detector` disables checking for data races. Using
this flag is **unsound**. This implies `-Zmiri-disable-weak-memory-emulation`.
* `-Zmiri-disable-stacked-borrows` disables checking the experimental
aliasing rules to track borrows ([Stacked Borrows] and Tree Borrows).
aliasing rules to track borrows ([Stacked Borrows] and [Tree Borrows]).
This can make Miri run faster, but it also means no aliasing violations will
be detected. Using this flag is **unsound** (but the affected soundness rules
are experimental). Later flags take precedence: borrow tracking can be reactivated
Expand Down Expand Up @@ -425,7 +426,7 @@ to Miri failing to detect cases of undefined behavior in a program.
* `-Zmiri-track-weak-memory-loads` shows a backtrace when weak memory emulation returns an outdated
value from a load. This can help diagnose problems that disappear under
`-Zmiri-disable-weak-memory-emulation`.
* `-Zmiri-tree-borrows` replaces [Stacked Borrows] with the Tree Borrows rules.
* `-Zmiri-tree-borrows` replaces [Stacked Borrows] with the [Tree Borrows] rules.
The soundness rules are already experimental without this flag, but even more
so with this flag.
* `-Zmiri-force-page-size=<num>` overrides the default page size for an architecture, in multiples of 1k.
Expand All @@ -442,7 +443,7 @@ Some native rustc `-Z` flags are also very relevant for Miri:
functions. This is needed so that Miri can execute such functions, so Miri
sets this flag per default.
* `-Zmir-emit-retag` controls whether `Retag` statements are emitted. Miri
enables this per default because it is needed for [Stacked Borrows] and Tree Borrows.
enables this per default because it is needed for [Stacked Borrows] and [Tree Borrows].

Moreover, Miri recognizes some environment variables:

Expand Down
4 changes: 3 additions & 1 deletion src/tools/miri/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ function run_tests {
# optimizations up all the way, too).
# Optimizations change diagnostics (mostly backtraces), so we don't check
# them. Also error locations change so we don't run the failing tests.
MIRIFLAGS="${MIRIFLAGS:-} -O -Zmir-opt-level=4" MIRI_SKIP_UI_CHECKS=1 ./miri test -- tests/{pass,panic}
# We explicitly enable debug-assertions here, they are disabled by -O but we have tests
# which exist to check that we panic on debug assertion failures.
MIRIFLAGS="${MIRIFLAGS:-} -O -Zmir-opt-level=4 -Cdebug-assertions=yes" MIRI_SKIP_UI_CHECKS=1 ./miri test -- tests/{pass,panic}

# Also run some many-seeds tests. 64 seeds means this takes around a minute per test.
for FILE in tests/many-seeds/*.rs; do
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
511364e7874dba9649a264100407e4bffe7b5425
d4be8efc6296bace5b1e165f1b34d3c6da76aa8e
19 changes: 18 additions & 1 deletion src/tools/miri/src/bin/miri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ use rustc_middle::{
middle::exported_symbols::{
ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel,
},
ty::{query::ExternProviders, TyCtxt},
query::LocalCrate,
ty::{query::ExternProviders, TyCtxt},
};
use rustc_session::config::OptLevel;

use rustc_session::{config::CrateType, search_paths::PathKind, CtfeBacktrace};

use miri::{BacktraceStyle, BorrowTrackerMethod, ProvenanceMode, RetagFields};
Expand Down Expand Up @@ -83,6 +85,21 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
env::set_current_dir(cwd).unwrap();
}

if tcx.sess.opts.optimize != OptLevel::No {
tcx.sess.warn("Miri does not support optimizations. If you have enabled optimizations \
by selecting a Cargo profile (such as --release) which changes other profile settings \
such as whether debug assertions and overflow checks are enabled, those settings are \
still applied.");
}
if tcx.sess.mir_opt_level() > 0 {
tcx.sess.warn("You have explicitly enabled MIR optimizations, overriding Miri's default \
which is to completely disable them. Any optimizations may hide UB that Miri would \
otherwise detect, and it is not necessarily possible to predict what kind of UB will \
be missed. If you are enabling optimizations to make Miri run faster, we advise using \
cfg(miri) to shrink your workload instead. The performance benefit of enabling MIR \
optimizations is usually marginal at best.");
}

if let Some(return_code) = miri::eval_entry(tcx, entry_def_id, entry_type, config) {
std::process::exit(
i32::try_from(return_code).expect("Return value was too large!"),
Expand Down
5 changes: 4 additions & 1 deletion src/tools/miri/src/clock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ use std::time::{Duration, Instant as StdInstant};

/// When using a virtual clock, this defines how many nanoseconds we pretend are passing for each
/// basic block.
const NANOSECONDS_PER_BASIC_BLOCK: u64 = 10;
/// This number is pretty random, but it has been shown to approximately cause
/// some sample programs to run within an order of magnitude of real time on desktop CPUs.
/// (See `tests/pass/shims/time-with-isolation*.rs`.)
const NANOSECONDS_PER_BASIC_BLOCK: u64 = 5000;

#[derive(Debug)]
pub struct Instant {
Expand Down
8 changes: 5 additions & 3 deletions src/tools/miri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,13 @@ pub use crate::tag_gc::{EvalContextExt as _, VisitTags};

/// Insert rustc arguments at the beginning of the argument list that Miri wants to be
/// set per default, for maximal validation power.
/// Also disable the MIR pass that inserts an alignment check on every pointer dereference. Miri
/// does that too, and with a better error message.
pub const MIRI_DEFAULT_ARGS: &[&str] = &[
"--cfg=miri",
"-Zalways-encode-mir",
"-Zextra-const-ub-checks",
"-Zmir-emit-retag",
"-Zmir-opt-level=0",
"--cfg=miri",
"-Cdebug-assertions=on",
"-Zextra-const-ub-checks",
"-Zmir-enable-passes=-CheckAlignment",
];
20 changes: 7 additions & 13 deletions src/tools/miri/src/shims/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
&[catch_unwind.data.into(), payload.into()],
None,
// Directly return to caller of `try`.
StackPopCleanup::Goto { ret: Some(catch_unwind.ret), unwind: mir::UnwindAction::Continue },
StackPopCleanup::Goto {
ret: Some(catch_unwind.ret),
unwind: mir::UnwindAction::Continue,
},
)?;

// We pushed a new stack frame, the engine should not do any jumping now!
Expand Down Expand Up @@ -211,10 +214,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
Abi::Rust,
&[index.into(), len.into()],
None,
StackPopCleanup::Goto {
ret: None,
unwind,
},
StackPopCleanup::Goto { ret: None, unwind },
)?;
}
MisalignedPointerDereference { required, found } => {
Expand All @@ -235,19 +235,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
Abi::Rust,
&[required.into(), found.into()],
None,
StackPopCleanup::Goto {
ret: None,
unwind,
},
StackPopCleanup::Goto { ret: None, unwind },
)?;
}

_ => {
// Forward everything else to `panic` lang item.
this.start_panic(
msg.description(),
unwind,
)?;
this.start_panic(msg.description(), unwind)?;
}
}
Ok(())
Expand Down
14 changes: 7 additions & 7 deletions src/tools/miri/src/shims/unix/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -628,13 +628,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
let fd = this.read_scalar(&args[0])?.to_i32()?;
let cmd = this.read_scalar(&args[1])?.to_i32()?;

// Reject if isolation is enabled.
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
this.reject_in_isolation("`fcntl`", reject_with)?;
this.set_last_error_from_io_error(ErrorKind::PermissionDenied)?;
return Ok(-1);
}

// We only support getting the flags for a descriptor.
if cmd == this.eval_libc_i32("F_GETFD") {
// Currently this is the only flag that `F_GETFD` returns. It is OK to just return the
Expand Down Expand Up @@ -677,6 +670,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
None => this.handle_not_found(),
}
} else if this.tcx.sess.target.os == "macos" && cmd == this.eval_libc_i32("F_FULLFSYNC") {
// Reject if isolation is enabled.
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
this.reject_in_isolation("`fcntl`", reject_with)?;
this.set_last_error_from_io_error(ErrorKind::PermissionDenied)?;
return Ok(-1);
}

if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
// FIXME: Support fullfsync for all FDs
let FileHandle { file, writable } =
Expand Down
4 changes: 3 additions & 1 deletion src/tools/miri/tests/fail/terminate-terminator.stderr
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
warning: You have explicitly enabled MIR optimizations, overriding Miri's default which is to completely disable them. Any optimizations may hide UB that Miri would otherwise detect, and it is not necessarily possible to predict what kind of UB will be missed. If you are enabling optimizations to make Miri run faster, we advise using cfg(miri) to shrink your workload instead. The performance benefit of enabling MIR optimizations is usually marginal at best.

thread 'main' panicked at 'explicit panic', $DIR/terminate-terminator.rs:LL:CC
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: abnormal termination: panic in a function that cannot unwind
Expand All @@ -23,5 +25,5 @@ LL | panic_abort();

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to previous error
error: aborting due to previous error; 1 warning emitted

9 changes: 0 additions & 9 deletions src/tools/miri/tests/panic/alignment-assertion.rs

This file was deleted.

2 changes: 0 additions & 2 deletions src/tools/miri/tests/panic/alignment-assertion.stderr

This file was deleted.

12 changes: 12 additions & 0 deletions src/tools/miri/tests/pass-dep/shims/fcntl_f-fullfsync_apple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//@only-target-apple: F_FULLFSYNC only on apple systems
//@compile-flags: -Zmiri-isolation-error=warn-nobacktrace

use std::io::Error;

fn main() {
// test `fcntl(F_FULLFSYNC)`
unsafe {
assert_eq!(libc::fcntl(1, libc::F_FULLFSYNC, 0), -1);
assert_eq!(Error::last_os_error().raw_os_error(), Some(libc::EPERM));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
warning: `fcntl` was made to return an error due to isolation

5 changes: 2 additions & 3 deletions src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ use std::fs;
use std::io::{Error, ErrorKind};

fn main() {
// test `fcntl`
// test `fcntl(F_DUPFD): should work even with isolation.`
unsafe {
assert_eq!(libc::fcntl(1, libc::F_DUPFD, 0), -1);
assert_eq!(Error::last_os_error().raw_os_error(), Some(libc::EPERM));
assert!(libc::fcntl(1, libc::F_DUPFD, 0) >= 0);
}

// test `readlink`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
warning: `fcntl` was made to return an error due to isolation

warning: `readlink` was made to return an error due to isolation

warning: `$STAT` was made to return an error due to isolation
Expand Down
6 changes: 2 additions & 4 deletions src/tools/miri/tests/pass-dep/tokio/sleep.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//@compile-flags: -Zmiri-disable-isolation -Zmiri-permissive-provenance -Zmiri-backtrace=full
//@compile-flags: -Zmiri-permissive-provenance -Zmiri-backtrace=full
//@only-target-x86_64-unknown-linux: support for tokio only on linux and x86

use tokio::time::{sleep, Duration, Instant};
Expand All @@ -7,8 +7,6 @@ use tokio::time::{sleep, Duration, Instant};
async fn main() {
let start = Instant::now();
sleep(Duration::from_secs(1)).await;
// It takes 96 millisecond to sleep for 1 millisecond
// It takes 1025 millisecond to sleep for 1 second
let time_elapsed = &start.elapsed().as_millis();
assert!(time_elapsed > &1000, "{}", time_elapsed);
assert!((1000..1100).contains(time_elapsed), "{}", time_elapsed);
}
2 changes: 1 addition & 1 deletion src/tools/miri/tests/pass-dep/tokio/tokio_mvp.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Need to disable preemption to stay on the supported MVP codepath in mio.
//@compile-flags: -Zmiri-disable-isolation -Zmiri-permissive-provenance
//@compile-flags: -Zmiri-permissive-provenance
//@only-target-x86_64-unknown-linux: support for tokio exists only on linux and x86

#[tokio::main]
Expand Down
4 changes: 2 additions & 2 deletions src/tools/miri/tests/pass/concurrency/thread_park_isolated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ fn main() {

thread::park_timeout(Duration::from_millis(200));

// Thanks to deterministic execution, this will wiat *exactly* 200ms (rounded to 1ms).
assert!((200..201).contains(&start.elapsed().as_millis()));
// Thanks to deterministic execution, this will wait *exactly* 200ms, plus the time for the surrounding code.
assert!((200..210).contains(&start.elapsed().as_millis()), "{}", start.elapsed().as_millis());
}
15 changes: 12 additions & 3 deletions src/tools/miri/tests/pass/shims/time-with-isolation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,23 @@ fn test_time_passes() {
let diff = now2.duration_since(now1);
assert_eq!(now1 + diff, now2);
assert_eq!(now2 - diff, now1);
// The virtual clock is deterministic and I got 29us on a 64-bit Linux machine. However, this
// The virtual clock is deterministic and I got 15ms on a 64-bit Linux machine. However, this
// changes according to the platform so we use an interval to be safe. This should be updated
// if `NANOSECONDS_PER_BASIC_BLOCK` changes.
assert!(diff.as_micros() > 10);
assert!(diff.as_micros() < 40);
assert!(diff.as_millis() > 5);
assert!(diff.as_millis() < 20);
}

fn test_block_for_one_second() {
let end = Instant::now() + Duration::from_secs(1);
// This takes a long time, as we only increment when statements are executed.
// When we sleep on all threads, we fast forward to the sleep duration, which we can't
// do with busy waiting.
while Instant::now() < end {}
}

fn main() {
test_time_passes();
test_block_for_one_second();
test_sleep();
}
8 changes: 8 additions & 0 deletions src/tools/miri/tests/pass/shims/time-with-isolation2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use std::time::Instant;

fn main() {
let begin = Instant::now();
for _ in 0..100_000 {}
let time = begin.elapsed();
println!("The loop took around {}s", time.as_secs());
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The loop took around 13s

0 comments on commit 8e1162f

Please sign in to comment.