diff --git a/src/machine.rs b/src/machine.rs index 2f0aa915753..a7d62897b8f 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -27,7 +27,7 @@ use rustc_target::abi::{LayoutOf, Size}; use crate::*; -pub use crate::threads::{ThreadId, ThreadSet, ThreadLocalStorage}; +pub use crate::threads::{ThreadId, ThreadSet, ThreadState, ThreadLocalStorage}; // Some global facts about the emulated machine. pub const PAGE_SIZE: u64 = 4 * 1024; // FIXME: adjust to target architecture diff --git a/src/shims/tls.rs b/src/shims/tls.rs index d16acb75003..ec8c31fe2c1 100644 --- a/src/shims/tls.rs +++ b/src/shims/tls.rs @@ -9,7 +9,7 @@ use rustc_middle::ty; use rustc_target::abi::{Size, HasDataLayout}; use crate::{HelpersEvalContextExt, ThreadsEvalContextExt, InterpResult, MPlaceTy, Scalar, StackPopCleanup, Tag}; -use crate::machine::ThreadId; +use crate::machine::{ThreadId, ThreadState}; pub type TlsKey = u128; @@ -174,7 +174,7 @@ impl<'tcx> TlsData<'tcx> { impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {} pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> { - /// Run TLS destructors for the currently active thread. + /// Run TLS destructors for all threads. fn run_tls_dtors(&mut self) -> InterpResult<'tcx> { let this = self.eval_context_mut(); assert!(!this.machine.tls.dtors_running, "running TLS dtors twice"); @@ -223,7 +223,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx } // Now run the "keyed" destructors. - for thread_id in this.get_all_thread_ids() { + for (thread_id, thread_state) in this.get_all_thread_ids_with_states() { + assert!(thread_state == ThreadState::Terminated, + "TLS destructors should be executed after all threads terminated."); this.set_active_thread(thread_id)?; let mut dtor = this.machine.tls.fetch_tls_dtor(None, thread_id); while let Some((instance, thread_id, ptr, key)) = dtor { diff --git a/src/threads.rs b/src/threads.rs index 9d982359bfb..4458f4410e4 100644 --- a/src/threads.rs +++ b/src/threads.rs @@ -97,10 +97,7 @@ impl<'mir, 'tcx> Default for ThreadSet<'mir, 'tcx> { fn default() -> Self { let mut threads = IndexVec::new(); threads.push(Default::default()); - Self { - active_thread: ThreadId::new(0), - threads: threads, - } + Self { active_thread: ThreadId::new(0), threads: threads } } } @@ -156,8 +153,8 @@ impl<'mir, 'tcx: 'mir> ThreadSet<'mir, 'tcx> { } } /// Get ids of all threads ever allocated. - fn get_all_thread_ids(&mut self) -> Vec { - (0..self.threads.len()).map(ThreadId::new).collect() + fn get_all_thread_ids_with_states(&self) -> Vec<(ThreadId, ThreadState)> { + self.threads.iter_enumerated().map(|(id, thread)| (id, thread.state)).collect() } /// Decide which thread to run next. /// @@ -283,9 +280,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx let this = self.eval_context_mut(); this.machine.threads.active_thread_stack_mut() } - fn get_all_thread_ids(&mut self) -> Vec { + fn get_all_thread_ids_with_states(&mut self) -> Vec<(ThreadId, ThreadState)> { let this = self.eval_context_mut(); - this.machine.threads.get_all_thread_ids() + this.machine.threads.get_all_thread_ids_with_states() } /// Decide which thread to run next. ///