only do env var cleanup if all threads have stopped

This commit is contained in:
Ralf Jung 2022-07-19 21:44:45 -04:00
parent 9e37c488f3
commit 5fbf036670
2 changed files with 45 additions and 46 deletions

View File

@ -436,45 +436,6 @@ fn write_race_detect(
/// Evaluation context extensions. /// Evaluation context extensions.
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for MiriEvalContext<'mir, 'tcx> {} impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> { pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> {
/// Temporarily allow data-races to occur. This should only be used in
/// one of these cases:
/// - One of the appropriate `validate_atomic` functions will be called to
/// to treat a memory access as atomic.
/// - The memory being accessed should be treated as internal state, that
/// cannot be accessed by the interpreted program.
/// - Execution of the interpreted program execution has halted.
#[inline]
fn allow_data_races_ref<R>(&self, op: impl FnOnce(&MiriEvalContext<'mir, 'tcx>) -> R) -> R {
let this = self.eval_context_ref();
if let Some(data_race) = &this.machine.data_race {
data_race.ongoing_action_data_race_free.set(true);
}
let result = op(this);
if let Some(data_race) = &this.machine.data_race {
data_race.ongoing_action_data_race_free.set(false);
}
result
}
/// Same as `allow_data_races_ref`, this temporarily disables any data-race detection and
/// so should only be used for atomic operations or internal state that the program cannot
/// access.
#[inline]
fn allow_data_races_mut<R>(
&mut self,
op: impl FnOnce(&mut MiriEvalContext<'mir, 'tcx>) -> R,
) -> R {
let this = self.eval_context_mut();
if let Some(data_race) = &this.machine.data_race {
data_race.ongoing_action_data_race_free.set(true);
}
let result = op(this);
if let Some(data_race) = &this.machine.data_race {
data_race.ongoing_action_data_race_free.set(false);
}
result
}
/// Atomic variant of read_scalar_at_offset. /// Atomic variant of read_scalar_at_offset.
fn read_scalar_at_offset_atomic( fn read_scalar_at_offset_atomic(
&self, &self,
@ -1044,6 +1005,45 @@ pub fn deallocate<'tcx>(
impl<'mir, 'tcx: 'mir> EvalContextPrivExt<'mir, 'tcx> for MiriEvalContext<'mir, 'tcx> {} impl<'mir, 'tcx: 'mir> EvalContextPrivExt<'mir, 'tcx> for MiriEvalContext<'mir, 'tcx> {}
trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> { trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> {
/// Temporarily allow data-races to occur. This should only be used in
/// one of these cases:
/// - One of the appropriate `validate_atomic` functions will be called to
/// to treat a memory access as atomic.
/// - The memory being accessed should be treated as internal state, that
/// cannot be accessed by the interpreted program.
/// - Execution of the interpreted program execution has halted.
#[inline]
fn allow_data_races_ref<R>(&self, op: impl FnOnce(&MiriEvalContext<'mir, 'tcx>) -> R) -> R {
let this = self.eval_context_ref();
if let Some(data_race) = &this.machine.data_race {
data_race.ongoing_action_data_race_free.set(true);
}
let result = op(this);
if let Some(data_race) = &this.machine.data_race {
data_race.ongoing_action_data_race_free.set(false);
}
result
}
/// Same as `allow_data_races_ref`, this temporarily disables any data-race detection and
/// so should only be used for atomic operations or internal state that the program cannot
/// access.
#[inline]
fn allow_data_races_mut<R>(
&mut self,
op: impl FnOnce(&mut MiriEvalContext<'mir, 'tcx>) -> R,
) -> R {
let this = self.eval_context_mut();
if let Some(data_race) = &this.machine.data_race {
data_race.ongoing_action_data_race_free.set(true);
}
let result = op(this);
if let Some(data_race) = &this.machine.data_race {
data_race.ongoing_action_data_race_free.set(false);
}
result
}
/// Generic atomic operation implementation /// Generic atomic operation implementation
fn validate_atomic_op<A: Debug + Copy>( fn validate_atomic_op<A: Debug + Copy>(
&self, &self,

View File

@ -363,13 +363,12 @@ pub fn eval_entry<'tcx>(
panic::resume_unwind(panic_payload) panic::resume_unwind(panic_payload)
}); });
// Machine cleanup. // Machine cleanup. Only do this if all threads have terminated; threads that are still running
// Execution of the program has halted so any memory access we do here // might cause data races (https://github.com/rust-lang/miri/issues/2020) or Stacked Borrows
// cannot produce a real data race. If we do not do something to disable // errors (https://github.com/rust-lang/miri/issues/2396) if we deallocate here.
// data race detection here, some uncommon combination of errors will if ecx.have_all_terminated() {
// cause a data race to be detected: EnvVars::cleanup(&mut ecx).unwrap();
// https://github.com/rust-lang/miri/issues/2020 }
ecx.allow_data_races_mut(|ecx| EnvVars::cleanup(ecx).unwrap());
// Process the result. // Process the result.
match res { match res {