Skip to content

Commit c8229cd

Browse files
committed
on Windows, use miri_static_root for TLS dtors
1 parent 1b446cd commit c8229cd

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

src/librustc_mir/interpret/memory.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -716,14 +716,17 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
716716
}
717717
}
718718

719-
pub fn leak_report(&self) -> usize {
719+
/// Print leaked memory. Allocations reachable from `static_roots` or a `Global` allocation
720+
/// are not considered leaked. Leaks whose kind `may_leak()` returns true are not reported.
721+
pub fn leak_report(&self, static_roots: &[AllocId]) -> usize {
720722
// Collect the set of allocations that are *reachable* from `Global` allocations.
721723
let reachable = {
722724
let mut reachable = FxHashSet::default();
723725
let global_kind = M::GLOBAL_KIND.map(MemoryKind::Machine);
724726
let mut todo: Vec<_> = self.alloc_map.filter_map_collect(move |&id, &(kind, _)| {
725727
if Some(kind) == global_kind { Some(id) } else { None }
726728
});
729+
todo.extend(static_roots);
727730
while let Some(id) = todo.pop() {
728731
if reachable.insert(id) {
729732
// This is a new allocation, add its relocations to `todo`.

src/libstd/sys/windows/thread_local_key.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,29 @@ struct Node {
110110
next: *mut Node,
111111
}
112112

113+
#[cfg(miri)]
114+
extern "Rust" {
115+
/// Miri-provided extern function to mark the block `ptr` points to as a "root"
116+
/// for some static memory. This memory and everything reachable by it is not
117+
/// considered leaking even if it still exists when the program terminates.
118+
///
119+
/// `ptr` has to point to the beginning of an allocated block.
120+
fn miri_static_root(ptr: *const u8);
121+
}
122+
113123
unsafe fn register_dtor(key: Key, dtor: Dtor) {
114124
let mut node = Box::new(Node { key, dtor, next: ptr::null_mut() });
115125

116126
let mut head = DTORS.load(SeqCst);
117127
loop {
118128
node.next = head;
119129
match DTORS.compare_exchange(head, &mut *node, SeqCst, SeqCst) {
120-
Ok(_) => return mem::forget(node),
130+
Ok(_) => {
131+
#[cfg(miri)]
132+
miri_static_root(&*node as *const _ as *const u8);
133+
134+
return mem::forget(node);
135+
}
121136
Err(cur) => head = cur,
122137
}
123138
}

0 commit comments

Comments
 (0)