stop using process-wide state, now that we are running multiple interpreters in the same thread
This commit is contained in:
parent
d04b972f72
commit
0f49f0ffdf
6 changed files with 47 additions and 47 deletions
|
|
@ -9,7 +9,6 @@ use std::cmp::max;
|
|||
use rand::Rng;
|
||||
use rustc_abi::{Align, Size};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_span::Span;
|
||||
|
||||
use self::reuse_pool::ReusePool;
|
||||
use crate::concurrency::VClock;
|
||||
|
|
@ -319,17 +318,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
match global_state.provenance_mode {
|
||||
ProvenanceMode::Default => {
|
||||
// The first time this happens at a particular location, print a warning.
|
||||
thread_local! {
|
||||
// `Span` is non-`Send`, so we use a thread-local instead.
|
||||
static PAST_WARNINGS: RefCell<FxHashSet<Span>> = RefCell::default();
|
||||
let mut int2ptr_warned = this.machine.int2ptr_warned.borrow_mut();
|
||||
let first = int2ptr_warned.is_empty();
|
||||
if int2ptr_warned.insert(this.cur_span()) {
|
||||
// Newly inserted, so first time we see this span.
|
||||
this.emit_diagnostic(NonHaltingDiagnostic::Int2Ptr { details: first });
|
||||
}
|
||||
PAST_WARNINGS.with_borrow_mut(|past_warnings| {
|
||||
let first = past_warnings.is_empty();
|
||||
if past_warnings.insert(this.cur_span()) {
|
||||
// Newly inserted, so first time we see this span.
|
||||
this.emit_diagnostic(NonHaltingDiagnostic::Int2Ptr { details: first });
|
||||
}
|
||||
});
|
||||
}
|
||||
ProvenanceMode::Strict => {
|
||||
throw_machine_stop!(TerminationInfo::Int2PtrWithStrictProvenance);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ pub mod diagnostics;
|
|||
mod item;
|
||||
mod stack;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::fmt::Write;
|
||||
use std::{cmp, mem};
|
||||
|
||||
|
|
@ -822,16 +821,9 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
|
|||
let size = match size {
|
||||
Some(size) => size,
|
||||
None => {
|
||||
// The first time this happens, show a warning.
|
||||
thread_local! { static WARNING_SHOWN: RefCell<bool> = const { RefCell::new(false) }; }
|
||||
WARNING_SHOWN.with_borrow_mut(|shown| {
|
||||
if *shown {
|
||||
return;
|
||||
}
|
||||
// Not yet shown. Show it!
|
||||
*shown = true;
|
||||
if !this.machine.sb_extern_type_warned.replace(true) {
|
||||
this.emit_diagnostic(NonHaltingDiagnostic::ExternTypeReborrow);
|
||||
});
|
||||
}
|
||||
return interp_ok(place.clone());
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
use std::collections::BTreeSet;
|
||||
use std::num::NonZero;
|
||||
use std::sync::Mutex;
|
||||
use std::time::Duration;
|
||||
use std::{cmp, iter};
|
||||
|
||||
|
|
@ -641,11 +639,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
match reject_with {
|
||||
RejectOpWith::Abort => isolation_abort_error(op_name),
|
||||
RejectOpWith::WarningWithoutBacktrace => {
|
||||
// This exists to reduce verbosity; make sure we emit the warning at most once per
|
||||
// operation.
|
||||
static EMITTED_WARNINGS: Mutex<BTreeSet<String>> = Mutex::new(BTreeSet::new());
|
||||
|
||||
let mut emitted_warnings = EMITTED_WARNINGS.lock().unwrap();
|
||||
let mut emitted_warnings = this.machine.reject_in_isolation_warned.borrow_mut();
|
||||
if !emitted_warnings.contains(op_name) {
|
||||
// First time we are seeing this.
|
||||
emitted_warnings.insert(op_name.to_owned());
|
||||
|
|
@ -653,6 +647,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
.dcx()
|
||||
.warn(format!("{op_name} was made to return an error due to isolation"));
|
||||
}
|
||||
|
||||
interp_ok(())
|
||||
}
|
||||
RejectOpWith::Warning => {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
use std::any::Any;
|
||||
use std::borrow::Cow;
|
||||
use std::cell::RefCell;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::path::Path;
|
||||
use std::{fmt, process};
|
||||
|
|
@ -595,6 +595,21 @@ pub struct MiriMachine<'tcx> {
|
|||
|
||||
/// A cache of "data range" computations for unions (i.e., the offsets of non-padding bytes).
|
||||
union_data_ranges: FxHashMap<Ty<'tcx>, RangeSet>,
|
||||
|
||||
/// Caches the sanity-checks for various pthread primitives.
|
||||
pub(crate) pthread_mutex_sanity: Cell<bool>,
|
||||
pub(crate) pthread_rwlock_sanity: Cell<bool>,
|
||||
pub(crate) pthread_condvar_sanity: Cell<bool>,
|
||||
|
||||
/// Remembers whether we already warned about an extern type with Stacked Borrows.
|
||||
pub(crate) sb_extern_type_warned: Cell<bool>,
|
||||
/// Remember whether we already warned about sharing memory with a native call.
|
||||
#[cfg(unix)]
|
||||
pub(crate) native_call_mem_warned: Cell<bool>,
|
||||
/// Remembers which shims have already shown the warning about erroring in isolation.
|
||||
pub(crate) reject_in_isolation_warned: RefCell<FxHashSet<String>>,
|
||||
/// Remembers which int2ptr casts we have already warned about.
|
||||
pub(crate) int2ptr_warned: RefCell<FxHashSet<Span>>,
|
||||
}
|
||||
|
||||
impl<'tcx> MiriMachine<'tcx> {
|
||||
|
|
@ -732,6 +747,14 @@ impl<'tcx> MiriMachine<'tcx> {
|
|||
const_cache: RefCell::new(FxHashMap::default()),
|
||||
symbolic_alignment: RefCell::new(FxHashMap::default()),
|
||||
union_data_ranges: FxHashMap::default(),
|
||||
pthread_mutex_sanity: Cell::new(false),
|
||||
pthread_rwlock_sanity: Cell::new(false),
|
||||
pthread_condvar_sanity: Cell::new(false),
|
||||
sb_extern_type_warned: Cell::new(false),
|
||||
#[cfg(unix)]
|
||||
native_call_mem_warned: Cell::new(false),
|
||||
reject_in_isolation_warned: Default::default(),
|
||||
int2ptr_warned: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -844,6 +867,14 @@ impl VisitProvenance for MiriMachine<'_> {
|
|||
const_cache: _,
|
||||
symbolic_alignment: _,
|
||||
union_data_ranges: _,
|
||||
pthread_mutex_sanity: _,
|
||||
pthread_rwlock_sanity: _,
|
||||
pthread_condvar_sanity: _,
|
||||
sb_extern_type_warned: _,
|
||||
#[cfg(unix)]
|
||||
native_call_mem_warned: _,
|
||||
reject_in_isolation_warned: _,
|
||||
int2ptr_warned: _,
|
||||
} = self;
|
||||
|
||||
threads.visit_provenance(visit);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
//! Implements calling functions from a native library.
|
||||
use std::cell::RefCell;
|
||||
use std::ops::Deref;
|
||||
|
||||
use libffi::high::call as ffi;
|
||||
|
|
@ -174,16 +173,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
continue;
|
||||
};
|
||||
// The first time this happens, print a warning.
|
||||
thread_local! {
|
||||
static HAVE_WARNED: RefCell<bool> = const { RefCell::new(false) };
|
||||
if !this.machine.native_call_mem_warned.replace(true) {
|
||||
// Newly set, so first time we get here.
|
||||
this.emit_diagnostic(NonHaltingDiagnostic::NativeCallSharedMem);
|
||||
}
|
||||
HAVE_WARNED.with_borrow_mut(|have_warned| {
|
||||
if !*have_warned {
|
||||
// Newly inserted, so first time we see this span.
|
||||
this.emit_diagnostic(NonHaltingDiagnostic::NativeCallSharedMem);
|
||||
*have_warned = true;
|
||||
}
|
||||
});
|
||||
|
||||
this.prepare_for_native_call(alloc_id, prov)?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use rustc_abi::Size;
|
||||
|
||||
use crate::concurrency::sync::LAZY_INIT_COOKIE;
|
||||
|
|
@ -136,8 +134,7 @@ fn mutex_init_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, Size>
|
|||
|
||||
// Sanity-check this against PTHREAD_MUTEX_INITIALIZER (but only once):
|
||||
// the `init` field must start out not equal to INIT_COOKIE.
|
||||
static SANITY: AtomicBool = AtomicBool::new(false);
|
||||
if !SANITY.swap(true, Ordering::Relaxed) {
|
||||
if !ecx.machine.pthread_mutex_sanity.replace(true) {
|
||||
let check_static_initializer = |name| {
|
||||
let static_initializer = ecx.eval_path(&["libc", name]);
|
||||
let init_field =
|
||||
|
|
@ -248,8 +245,7 @@ fn rwlock_init_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, Size
|
|||
|
||||
// Sanity-check this against PTHREAD_RWLOCK_INITIALIZER (but only once):
|
||||
// the `init` field must start out not equal to LAZY_INIT_COOKIE.
|
||||
static SANITY: AtomicBool = AtomicBool::new(false);
|
||||
if !SANITY.swap(true, Ordering::Relaxed) {
|
||||
if !ecx.machine.pthread_rwlock_sanity.replace(true) {
|
||||
let static_initializer = ecx.eval_path(&["libc", "PTHREAD_RWLOCK_INITIALIZER"]);
|
||||
let init_field = static_initializer.offset(offset, ecx.machine.layouts.u32, ecx).unwrap();
|
||||
let init = ecx.read_scalar(&init_field).unwrap().to_u32().unwrap();
|
||||
|
|
@ -357,8 +353,7 @@ fn cond_init_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, Size>
|
|||
|
||||
// Sanity-check this against PTHREAD_COND_INITIALIZER (but only once):
|
||||
// the `init` field must start out not equal to LAZY_INIT_COOKIE.
|
||||
static SANITY: AtomicBool = AtomicBool::new(false);
|
||||
if !SANITY.swap(true, Ordering::Relaxed) {
|
||||
if !ecx.machine.pthread_condvar_sanity.replace(true) {
|
||||
let static_initializer = ecx.eval_path(&["libc", "PTHREAD_COND_INITIALIZER"]);
|
||||
let init_field = static_initializer.offset(offset, ecx.machine.layouts.u32, ecx).unwrap();
|
||||
let init = ecx.read_scalar(&init_field).unwrap().to_u32().unwrap();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue