Closed
Description
Apologies if this has been raised before, but I've been playing around with trying to track where allocations happen with something like so:
use libc_print::libc_println;
use std::alloc::{GlobalAlloc, Layout};
use std::panic::Location;
pub struct TracedAlloc<T: GlobalAlloc> {
pub allocator: T,
}
unsafe impl<T> GlobalAlloc for TracedAlloc<T>
where
T: GlobalAlloc,
{
#[track_caller]
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
libc_println!("Alloc {:?} at {:?}", layout, Location::caller());
self.allocator.alloc(layout)
}
#[track_caller]
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
libc_println!("Dealloc {:?} at {:?}", layout, Location::caller());
self.allocator.dealloc(ptr, layout)
}
}
However the caller location is always the line I've put #[global_allocator]
which makes #[track_caller]
useless in this context.
Originally posted by @xd009642 in #47809 (comment)
note from @anp: I'm not sure how the global allocator hooks in but this might be possible?
Activity
jdm commentedon Jul 25, 2020
I'm not sure if this will work, given the indirection in
rust/src/liballoc/alloc.rs
Lines 77 to 81 in 8cb94fc
#[global_alloc]
, per this comment.anp commentedon Jul 25, 2020
Yeah, the only way to carry
#[track_caller]
through anextern "Rust"
block is if both sides have it declared. It's technically possible but it would be a new (breaking) requirement on all allocators so I don't think that's feasible.lqd commentedon Jul 26, 2020
cc #74433