on Windows, use miri_static_root for TLS dtors

This commit is contained in:
Ralf Jung 2020-07-23 15:49:39 +02:00
parent 1b446cdbf0
commit c8229cdfc1
2 changed files with 20 additions and 2 deletions

View File

@ -716,7 +716,9 @@ fn write_allocation_track_relocs<'tcx, Tag: Copy + fmt::Debug, Extra>(
}
}
pub fn leak_report(&self) -> usize {
/// Print leaked memory. Allocations reachable from `static_roots` or a `Global` allocation
/// are not considered leaked. Leaks whose kind `may_leak()` returns true are not reported.
pub fn leak_report(&self, static_roots: &[AllocId]) -> usize {
// Collect the set of allocations that are *reachable* from `Global` allocations.
let reachable = {
let mut reachable = FxHashSet::default();
@ -724,6 +726,7 @@ pub fn leak_report(&self) -> usize {
let mut todo: Vec<_> = self.alloc_map.filter_map_collect(move |&id, &(kind, _)| {
if Some(kind) == global_kind { Some(id) } else { None }
});
todo.extend(static_roots);
while let Some(id) = todo.pop() {
if reachable.insert(id) {
// This is a new allocation, add its relocations to `todo`.

View File

@ -110,6 +110,16 @@ struct Node {
next: *mut Node,
}
#[cfg(miri)]
extern "Rust" {
/// Miri-provided extern function to mark the block `ptr` points to as a "root"
/// for some static memory. This memory and everything reachable by it is not
/// considered leaking even if it still exists when the program terminates.
///
/// `ptr` has to point to the beginning of an allocated block.
fn miri_static_root(ptr: *const u8);
}
unsafe fn register_dtor(key: Key, dtor: Dtor) {
let mut node = Box::new(Node { key, dtor, next: ptr::null_mut() });
@ -117,7 +127,12 @@ unsafe fn register_dtor(key: Key, dtor: Dtor) {
loop {
node.next = head;
match DTORS.compare_exchange(head, &mut *node, SeqCst, SeqCst) {
Ok(_) => return mem::forget(node),
Ok(_) => {
#[cfg(miri)]
miri_static_root(&*node as *const _ as *const u8);
return mem::forget(node);
}
Err(cur) => head = cur,
}
}