-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Calling std::thread::current()
in global allocator results in non-obvious error
#115209
Comments
std::thread::current()
in global allocator results in non-obvious error
std::thread::current()
in global allocator results in non-obvious errorstd::thread::current()
in global allocator results in non-obvious error
In macos result is always Meta
|
Pre-main behaviour was also discussed in #110708. The feeling was that in general we should endeavour to make as much of the std work as possible and document where it doesn't. The complicating factor is that this is highly platform specific and there are likely to always be caveats and shifting behaviour as implementations evolve. But yes, documenting it is definitely worth doing if someone wants to help with that. |
I’d help with documenting, but I’m not sure where this should be documented. I’m also not sure whether it should be documented as “you can use these APIs pre-main” or “you can’t use these other APIs pre-main”. A separate question is why |
Also, this code hangs in macos, so maybe not related to pre-main: use std::alloc::{GlobalAlloc, Layout, System};
use std::sync::atomic::AtomicBool;
use std::thread;
static IS_MAIN_STARED: AtomicBool = AtomicBool::new(false);
struct MyGlobalAlloc;
unsafe impl GlobalAlloc for MyGlobalAlloc {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
if IS_MAIN_STARED.load(std::sync::atomic::Ordering::SeqCst) {
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() {
IS_MAIN_STARED.store(true, std::sync::atomic::Ordering::SeqCst);
let e = thread::spawn(|| {});
e.join().unwrap();
} If you remove
|
Oh hm, yeah it seems more likely that the issue is |
it seems that it allocates because it uses |
With #127912 merged, this now triggers an abort with a hopefully clearer message:
|
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 ofGlobalAlloc
, 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):
I expected to see this happen: nothing at all, it should just work.
Instead, this happened:
I’ve also seen:
but I can’t reliably reproduce it.
Meta
rustc --version --verbose
: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:
std::thread::current().id()
without crashing the program,GlobalAlloc
,#[global_allocator]
, orstd::thread::current()
, preferably all of them.The text was updated successfully, but these errors were encountered: