Description
Global allocator is a special piece of code because it runs before main()
. Parts of standard library are not available at this time and it’s (as far as I know) not documented in safety contract of GlobalAlloc
, or, for that matter, anywhere else.
It seems like some sort of a doc specifying which functions are “before-main-safe” (so can be used in GlobalAlloc
and #[ctor]
) would be really useful. On top of that, I think that identifying the current thread should be allowed in the global allocator.
I tried this code (playground):
use std::alloc::{GlobalAlloc, Layout, System};
struct MyGlobalAlloc;
unsafe impl GlobalAlloc for MyGlobalAlloc {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
std::panic::catch_unwind(|| std::thread::current()).ok();
System.alloc(layout)
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
System.dealloc(ptr, layout)
}
}
#[global_allocator]
static _ALLOCATOR: MyGlobalAlloc = MyGlobalAlloc;
fn main() {}
I expected to see this happen: nothing at all, it should just work.
Instead, this happened:
thread panicked while processing panic. aborting.
I’ve also seen:
fatal runtime error: assertion failed: thread_info.is_none()
but I can’t reliably reproduce it.
Meta
rustc --version --verbose
:
rustc 1.73.0-nightly (08d00b40a 2023-08-09)
binary: rustc
commit-hash: 08d00b40aef2017fe6dba3ff7d6476efa0c10888
commit-date: 2023-08-09
host: x86_64-unknown-linux-gnu
release: 1.73.0-nightly
LLVM version: 17.0.0
but it reproduces on stable, beta and nightly.
I’m not actually sure if this is a bug, but I think one of the following must be true:
- Either global allocator should be able to call
std::thread::current().id()
without crashing the program, - or its inability to do so should be documented in docs for
GlobalAlloc
,#[global_allocator]
, orstd::thread::current()
, preferably all of them.