Skip to content

Commit 0f49f0f

Browse files
committed
stop using process-wide state, now that we are running multiple interpreters in the same thread
1 parent d04b972 commit 0f49f0f

File tree

6 files changed

+47
-47
lines changed

6 files changed

+47
-47
lines changed

src/tools/miri/src/alloc_addresses/mod.rs

+5-11
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use std::cmp::max;
99
use rand::Rng;
1010
use rustc_abi::{Align, Size};
1111
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
12-
use rustc_span::Span;
1312

1413
use self::reuse_pool::ReusePool;
1514
use crate::concurrency::VClock;
@@ -319,17 +318,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
319318
match global_state.provenance_mode {
320319
ProvenanceMode::Default => {
321320
// The first time this happens at a particular location, print a warning.
322-
thread_local! {
323-
// `Span` is non-`Send`, so we use a thread-local instead.
324-
static PAST_WARNINGS: RefCell<FxHashSet<Span>> = RefCell::default();
321+
let mut int2ptr_warned = this.machine.int2ptr_warned.borrow_mut();
322+
let first = int2ptr_warned.is_empty();
323+
if int2ptr_warned.insert(this.cur_span()) {
324+
// Newly inserted, so first time we see this span.
325+
this.emit_diagnostic(NonHaltingDiagnostic::Int2Ptr { details: first });
325326
}
326-
PAST_WARNINGS.with_borrow_mut(|past_warnings| {
327-
let first = past_warnings.is_empty();
328-
if past_warnings.insert(this.cur_span()) {
329-
// Newly inserted, so first time we see this span.
330-
this.emit_diagnostic(NonHaltingDiagnostic::Int2Ptr { details: first });
331-
}
332-
});
333327
}
334328
ProvenanceMode::Strict => {
335329
throw_machine_stop!(TerminationInfo::Int2PtrWithStrictProvenance);

src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs

+2-10
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ pub mod diagnostics;
55
mod item;
66
mod stack;
77

8-
use std::cell::RefCell;
98
use std::fmt::Write;
109
use std::{cmp, mem};
1110

@@ -822,16 +821,9 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
822821
let size = match size {
823822
Some(size) => size,
824823
None => {
825-
// The first time this happens, show a warning.
826-
thread_local! { static WARNING_SHOWN: RefCell<bool> = const { RefCell::new(false) }; }
827-
WARNING_SHOWN.with_borrow_mut(|shown| {
828-
if *shown {
829-
return;
830-
}
831-
// Not yet shown. Show it!
832-
*shown = true;
824+
if !this.machine.sb_extern_type_warned.replace(true) {
833825
this.emit_diagnostic(NonHaltingDiagnostic::ExternTypeReborrow);
834-
});
826+
}
835827
return interp_ok(place.clone());
836828
}
837829
};

src/tools/miri/src/helpers.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
use std::collections::BTreeSet;
21
use std::num::NonZero;
3-
use std::sync::Mutex;
42
use std::time::Duration;
53
use std::{cmp, iter};
64

@@ -641,18 +639,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
641639
match reject_with {
642640
RejectOpWith::Abort => isolation_abort_error(op_name),
643641
RejectOpWith::WarningWithoutBacktrace => {
644-
// This exists to reduce verbosity; make sure we emit the warning at most once per
645-
// operation.
646-
static EMITTED_WARNINGS: Mutex<BTreeSet<String>> = Mutex::new(BTreeSet::new());
647-
648-
let mut emitted_warnings = EMITTED_WARNINGS.lock().unwrap();
642+
let mut emitted_warnings = this.machine.reject_in_isolation_warned.borrow_mut();
649643
if !emitted_warnings.contains(op_name) {
650644
// First time we are seeing this.
651645
emitted_warnings.insert(op_name.to_owned());
652646
this.tcx
653647
.dcx()
654648
.warn(format!("{op_name} was made to return an error due to isolation"));
655649
}
650+
656651
interp_ok(())
657652
}
658653
RejectOpWith::Warning => {

src/tools/miri/src/machine.rs

+32-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
44
use std::any::Any;
55
use std::borrow::Cow;
6-
use std::cell::RefCell;
6+
use std::cell::{Cell, RefCell};
77
use std::collections::hash_map::Entry;
88
use std::path::Path;
99
use std::{fmt, process};
@@ -595,6 +595,21 @@ pub struct MiriMachine<'tcx> {
595595

596596
/// A cache of "data range" computations for unions (i.e., the offsets of non-padding bytes).
597597
union_data_ranges: FxHashMap<Ty<'tcx>, RangeSet>,
598+
599+
/// Caches the sanity-checks for various pthread primitives.
600+
pub(crate) pthread_mutex_sanity: Cell<bool>,
601+
pub(crate) pthread_rwlock_sanity: Cell<bool>,
602+
pub(crate) pthread_condvar_sanity: Cell<bool>,
603+
604+
/// Remembers whether we already warned about an extern type with Stacked Borrows.
605+
pub(crate) sb_extern_type_warned: Cell<bool>,
606+
/// Remember whether we already warned about sharing memory with a native call.
607+
#[cfg(unix)]
608+
pub(crate) native_call_mem_warned: Cell<bool>,
609+
/// Remembers which shims have already shown the warning about erroring in isolation.
610+
pub(crate) reject_in_isolation_warned: RefCell<FxHashSet<String>>,
611+
/// Remembers which int2ptr casts we have already warned about.
612+
pub(crate) int2ptr_warned: RefCell<FxHashSet<Span>>,
598613
}
599614

600615
impl<'tcx> MiriMachine<'tcx> {
@@ -732,6 +747,14 @@ impl<'tcx> MiriMachine<'tcx> {
732747
const_cache: RefCell::new(FxHashMap::default()),
733748
symbolic_alignment: RefCell::new(FxHashMap::default()),
734749
union_data_ranges: FxHashMap::default(),
750+
pthread_mutex_sanity: Cell::new(false),
751+
pthread_rwlock_sanity: Cell::new(false),
752+
pthread_condvar_sanity: Cell::new(false),
753+
sb_extern_type_warned: Cell::new(false),
754+
#[cfg(unix)]
755+
native_call_mem_warned: Cell::new(false),
756+
reject_in_isolation_warned: Default::default(),
757+
int2ptr_warned: Default::default(),
735758
}
736759
}
737760

@@ -844,6 +867,14 @@ impl VisitProvenance for MiriMachine<'_> {
844867
const_cache: _,
845868
symbolic_alignment: _,
846869
union_data_ranges: _,
870+
pthread_mutex_sanity: _,
871+
pthread_rwlock_sanity: _,
872+
pthread_condvar_sanity: _,
873+
sb_extern_type_warned: _,
874+
#[cfg(unix)]
875+
native_call_mem_warned: _,
876+
reject_in_isolation_warned: _,
877+
int2ptr_warned: _,
847878
} = self;
848879

849880
threads.visit_provenance(visit);

src/tools/miri/src/shims/native_lib.rs

+3-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
//! Implements calling functions from a native library.
2-
use std::cell::RefCell;
32
use std::ops::Deref;
43

54
use libffi::high::call as ffi;
@@ -174,16 +173,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
174173
continue;
175174
};
176175
// The first time this happens, print a warning.
177-
thread_local! {
178-
static HAVE_WARNED: RefCell<bool> = const { RefCell::new(false) };
176+
if !this.machine.native_call_mem_warned.replace(true) {
177+
// Newly set, so first time we get here.
178+
this.emit_diagnostic(NonHaltingDiagnostic::NativeCallSharedMem);
179179
}
180-
HAVE_WARNED.with_borrow_mut(|have_warned| {
181-
if !*have_warned {
182-
// Newly inserted, so first time we see this span.
183-
this.emit_diagnostic(NonHaltingDiagnostic::NativeCallSharedMem);
184-
*have_warned = true;
185-
}
186-
});
187180

188181
this.prepare_for_native_call(alloc_id, prov)?;
189182
}

src/tools/miri/src/shims/unix/sync.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::sync::atomic::{AtomicBool, Ordering};
2-
31
use rustc_abi::Size;
42

53
use crate::concurrency::sync::LAZY_INIT_COOKIE;
@@ -136,8 +134,7 @@ fn mutex_init_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, Size>
136134

137135
// Sanity-check this against PTHREAD_MUTEX_INITIALIZER (but only once):
138136
// the `init` field must start out not equal to INIT_COOKIE.
139-
static SANITY: AtomicBool = AtomicBool::new(false);
140-
if !SANITY.swap(true, Ordering::Relaxed) {
137+
if !ecx.machine.pthread_mutex_sanity.replace(true) {
141138
let check_static_initializer = |name| {
142139
let static_initializer = ecx.eval_path(&["libc", name]);
143140
let init_field =
@@ -248,8 +245,7 @@ fn rwlock_init_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, Size
248245

249246
// Sanity-check this against PTHREAD_RWLOCK_INITIALIZER (but only once):
250247
// the `init` field must start out not equal to LAZY_INIT_COOKIE.
251-
static SANITY: AtomicBool = AtomicBool::new(false);
252-
if !SANITY.swap(true, Ordering::Relaxed) {
248+
if !ecx.machine.pthread_rwlock_sanity.replace(true) {
253249
let static_initializer = ecx.eval_path(&["libc", "PTHREAD_RWLOCK_INITIALIZER"]);
254250
let init_field = static_initializer.offset(offset, ecx.machine.layouts.u32, ecx).unwrap();
255251
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>
357353

358354
// Sanity-check this against PTHREAD_COND_INITIALIZER (but only once):
359355
// the `init` field must start out not equal to LAZY_INIT_COOKIE.
360-
static SANITY: AtomicBool = AtomicBool::new(false);
361-
if !SANITY.swap(true, Ordering::Relaxed) {
356+
if !ecx.machine.pthread_condvar_sanity.replace(true) {
362357
let static_initializer = ecx.eval_path(&["libc", "PTHREAD_COND_INITIALIZER"]);
363358
let init_field = static_initializer.offset(offset, ecx.machine.layouts.u32, ecx).unwrap();
364359
let init = ecx.read_scalar(&init_field).unwrap().to_u32().unwrap();

0 commit comments

Comments
 (0)