@@ -1051,7 +1051,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
1051
1051
// See if this thread can do something else.
1052
1052
match this. run_on_stack_empty ( ) ? {
1053
1053
Poll :: Pending => { } // keep going
1054
- Poll :: Ready ( ( ) ) => this. terminate_active_thread ( ) ?,
1054
+ Poll :: Ready ( ( ) ) => this. terminate_active_thread ( false ) ?,
1055
1055
}
1056
1056
}
1057
1057
}
@@ -1066,11 +1066,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
1066
1066
}
1067
1067
1068
1068
/// 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).
1070
1071
///
1071
1072
/// This is called by the eval loop when a thread's on_stack_empty returns `Ready`.
1072
1073
#[ inline]
1073
- fn terminate_active_thread ( & mut self ) -> InterpResult < ' tcx > {
1074
+ fn terminate_active_thread ( & mut self , leak_tls : bool ) -> InterpResult < ' tcx > {
1074
1075
let this = self . eval_context_mut ( ) ;
1075
1076
let thread = this. active_thread_mut ( ) ;
1076
1077
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> {
1079
1080
let current_span = this. machine . current_span ( ) ;
1080
1081
let thread_local_allocations =
1081
1082
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 {
1095
1092
// 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
+ }
1100
1096
}
1101
1097
Ok ( ( ) )
1102
1098
}
0 commit comments