Skip to content

Commit 80f17ca

Browse files
committed
leak_tls param for terminate_active_thread()
1 parent 94c74de commit 80f17ca

File tree

2 files changed

+17
-21
lines changed

2 files changed

+17
-21
lines changed

src/concurrency/thread.rs

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
10511051
// See if this thread can do something else.
10521052
match this.run_on_stack_empty()? {
10531053
Poll::Pending => {} // keep going
1054-
Poll::Ready(()) => this.terminate_active_thread()?,
1054+
Poll::Ready(()) => this.terminate_active_thread(false)?,
10551055
}
10561056
}
10571057
}
@@ -1066,11 +1066,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
10661066
}
10671067

10681068
/// Handles thread termination of the active thread: wakes up threads joining on this one,
1069-
/// and deallocated thread-local statics.
1069+
/// and deallocates thread-local statics (unless `leak_tls` is set, in which case the thread's
1070+
/// TLS are marked as static roots for leakage analysis).
10701071
///
10711072
/// This is called by the eval loop when a thread's on_stack_empty returns `Ready`.
10721073
#[inline]
1073-
fn terminate_active_thread(&mut self) -> InterpResult<'tcx> {
1074+
fn terminate_active_thread(&mut self, leak_tls: bool) -> InterpResult<'tcx> {
10741075
let this = self.eval_context_mut();
10751076
let thread = this.active_thread_mut();
10761077
assert!(thread.stack.is_empty(), "only threads with an empty stack can be terminated");
@@ -1079,24 +1080,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
10791080
let current_span = this.machine.current_span();
10801081
let thread_local_allocations =
10811082
this.machine.threads.thread_terminated(this.machine.data_race.as_mut(), current_span);
1082-
match this.get_active_thread() {
1083-
// For main thread, add thread-local statics to static roots and skip deallocating
1084-
// backing memory
1085-
ThreadId(0) =>
1086-
for ptr in thread_local_allocations {
1087-
if let Some(alloc) = ptr.provenance.get_alloc_id() {
1088-
trace!(
1089-
"Main thread thread-local static stored as static root: {:?}",
1090-
alloc
1091-
);
1092-
this.machine.static_roots.push(alloc);
1093-
}
1094-
},
1083+
if leak_tls {
1084+
// Add thread-local statics to static roots and skip deallocating backing memory
1085+
for ptr in thread_local_allocations {
1086+
if let Some(alloc) = ptr.provenance.get_alloc_id() {
1087+
trace!("Thread-local static leaked and stored as static root: {:?}", alloc);
1088+
this.machine.static_roots.push(alloc);
1089+
}
1090+
}
1091+
} else {
10951092
// Deallocate backing memory of thread-local statics
1096-
ThreadId(_) =>
1097-
for ptr in thread_local_allocations {
1098-
this.deallocate_ptr(ptr.into(), None, MiriMemoryKind::Tls.into())?;
1099-
},
1093+
for ptr in thread_local_allocations {
1094+
this.deallocate_ptr(ptr.into(), None, MiriMemoryKind::Tls.into())?;
1095+
}
11001096
}
11011097
Ok(())
11021098
}

src/eval.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ impl MainThreadState {
246246
let exit_code = this.read_target_isize(&ret_place)?;
247247
// Need to call this ourselves since we are not going to return to the scheduler
248248
// loop, and we want the main thread TLS to not show up as memory leaks.
249-
this.terminate_active_thread()?;
249+
this.terminate_active_thread(true)?;
250250
// Stop interpreter loop.
251251
throw_machine_stop!(TerminationInfo::Exit { code: exit_code, leak_check: true });
252252
}

0 commit comments

Comments
 (0)