about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2024-12-23 12:44:54 +0100
committerRalf Jung <post@ralfj.de>2024-12-23 14:50:26 +0100
commit0f49f0ffdfec05ca7d7f6435444c2683720f6c43 (patch)
tree5b7ed302290a5a45132b2cacf8eb75487652707b
parentd04b972f728a9d7088108983c53f669a0a8530d6 (diff)
downloadrust-0f49f0ffdfec05ca7d7f6435444c2683720f6c43.tar.gz
rust-0f49f0ffdfec05ca7d7f6435444c2683720f6c43.zip
stop using process-wide state, now that we are running multiple interpreters in the same thread
-rw-r--r--src/tools/miri/src/alloc_addresses/mod.rs16
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs12
-rw-r--r--src/tools/miri/src/helpers.rs9
-rw-r--r--src/tools/miri/src/machine.rs33
-rw-r--r--src/tools/miri/src/shims/native_lib.rs13
-rw-r--r--src/tools/miri/src/shims/unix/sync.rs11
6 files changed, 47 insertions, 47 deletions
diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs
index f7295fd7d8a..3d0fc5590eb 100644
--- a/src/tools/miri/src/alloc_addresses/mod.rs
+++ b/src/tools/miri/src/alloc_addresses/mod.rs
@@ -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);
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
index ea75131078e..bcc8668dbc1 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
@@ -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());
             }
         };
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index 690cb7a5b33..adfec33beac 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -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 => {
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 33cefd60764..5e8f616a37e 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -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);
diff --git a/src/tools/miri/src/shims/native_lib.rs b/src/tools/miri/src/shims/native_lib.rs
index 92cca88bc96..87be5a521d1 100644
--- a/src/tools/miri/src/shims/native_lib.rs
+++ b/src/tools/miri/src/shims/native_lib.rs
@@ -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)?;
             }
diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs
index 416cf020dcc..5b0a9398b4b 100644
--- a/src/tools/miri/src/shims/unix/sync.rs
+++ b/src/tools/miri/src/shims/unix/sync.rs
@@ -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();