Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit d58abab

Browse files
committed
Auto merge of rust-lang#2142 - saethlin:cleanup-data-race-ice, r=oli-obk
Make allow_data_races_* public and use it during EnvVars::cleanup Fixes rust-lang/miri#2020 I've tried for hours now to come up with a test case for this ICE with no luck. I suspect there's something about the way the data race detection works under these conditions that I just don't understand 😩. But I tried this change out on a handful of crates and I don't see any more ICEs of this form. For whatever reason it seems like `bastion==0.4.5` is a good way to run into this, with the flags ``` MIRIFLAGS="-Zmiri-tag-raw-pointers -Zmiri-panic-on-unsupported -Zmiri-disable-isolation" cargo +miri miri test --no-fail-fast --doc ``` I think all the cases I've run into with this involve both `-Zmiri-panic-on-unsupported` and `-Zmiri-tag-raw-pointers`, so it could be that the combination of an unexpected panic and a machine halt is required.
2 parents b5fc544 + 3cfce6f commit d58abab

File tree

2 files changed

+49
-42
lines changed

2 files changed

+49
-42
lines changed

src/data_race.rs

Lines changed: 43 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,49 @@ impl MemoryCellClocks {
437437
/// Evaluation context extensions.
438438
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for MiriEvalContext<'mir, 'tcx> {}
439439
pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> {
440+
/// Temporarily allow data-races to occur. This should only be used in
441+
/// one of these cases:
442+
/// - One of the appropriate `validate_atomic` functions will be called to
443+
/// to treat a memory access as atomic.
444+
/// - The memory being accessed should be treated as internal state, that
445+
/// cannot be accessed by the interpreted program.
446+
/// - Execution of the interpreted program execution has halted.
447+
#[inline]
448+
fn allow_data_races_ref<R>(&self, op: impl FnOnce(&MiriEvalContext<'mir, 'tcx>) -> R) -> R {
449+
let this = self.eval_context_ref();
450+
let old = if let Some(data_race) = &this.machine.data_race {
451+
data_race.multi_threaded.replace(false)
452+
} else {
453+
false
454+
};
455+
let result = op(this);
456+
if let Some(data_race) = &this.machine.data_race {
457+
data_race.multi_threaded.set(old);
458+
}
459+
result
460+
}
461+
462+
/// Same as `allow_data_races_ref`, this temporarily disables any data-race detection and
463+
/// so should only be used for atomic operations or internal state that the program cannot
464+
/// access.
465+
#[inline]
466+
fn allow_data_races_mut<R>(
467+
&mut self,
468+
op: impl FnOnce(&mut MiriEvalContext<'mir, 'tcx>) -> R,
469+
) -> R {
470+
let this = self.eval_context_mut();
471+
let old = if let Some(data_race) = &this.machine.data_race {
472+
data_race.multi_threaded.replace(false)
473+
} else {
474+
false
475+
};
476+
let result = op(this);
477+
if let Some(data_race) = &this.machine.data_race {
478+
data_race.multi_threaded.set(old);
479+
}
480+
result
481+
}
482+
440483
/// Atomic variant of read_scalar_at_offset.
441484
fn read_scalar_at_offset_atomic(
442485
&self,
@@ -927,47 +970,6 @@ impl VClockAlloc {
927970

928971
impl<'mir, 'tcx: 'mir> EvalContextPrivExt<'mir, 'tcx> for MiriEvalContext<'mir, 'tcx> {}
929972
trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> {
930-
// Temporarily allow data-races to occur, this should only be
931-
// used if either one of the appropriate `validate_atomic` functions
932-
// will be called to treat a memory access as atomic or if the memory
933-
// being accessed should be treated as internal state, that cannot be
934-
// accessed by the interpreted program.
935-
#[inline]
936-
fn allow_data_races_ref<R>(&self, op: impl FnOnce(&MiriEvalContext<'mir, 'tcx>) -> R) -> R {
937-
let this = self.eval_context_ref();
938-
let old = if let Some(data_race) = &this.machine.data_race {
939-
data_race.multi_threaded.replace(false)
940-
} else {
941-
false
942-
};
943-
let result = op(this);
944-
if let Some(data_race) = &this.machine.data_race {
945-
data_race.multi_threaded.set(old);
946-
}
947-
result
948-
}
949-
950-
/// Same as `allow_data_races_ref`, this temporarily disables any data-race detection and
951-
/// so should only be used for atomic operations or internal state that the program cannot
952-
/// access.
953-
#[inline]
954-
fn allow_data_races_mut<R>(
955-
&mut self,
956-
op: impl FnOnce(&mut MiriEvalContext<'mir, 'tcx>) -> R,
957-
) -> R {
958-
let this = self.eval_context_mut();
959-
let old = if let Some(data_race) = &this.machine.data_race {
960-
data_race.multi_threaded.replace(false)
961-
} else {
962-
false
963-
};
964-
let result = op(this);
965-
if let Some(data_race) = &this.machine.data_race {
966-
data_race.multi_threaded.set(old);
967-
}
968-
result
969-
}
970-
971973
/// Generic atomic operation implementation
972974
fn validate_atomic_op<A: Debug + Copy>(
973975
&self,

src/eval.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,12 @@ pub fn eval_entry<'tcx>(
344344
})();
345345

346346
// Machine cleanup.
347-
EnvVars::cleanup(&mut ecx).unwrap();
347+
// Execution of the program has halted so any memory access we do here
348+
// cannot produce a real data race. If we do not do something to disable
349+
// data race detection here, some uncommon combination of errors will
350+
// cause a data race to be detected:
351+
// https://github.com/rust-lang/miri/issues/2020
352+
ecx.allow_data_races_mut(|ecx| EnvVars::cleanup(ecx).unwrap());
348353

349354
// Process the result.
350355
match res {

0 commit comments

Comments
 (0)