Repository navigation
Description
Thread::new tries to avoid invoking the global allocator for re-entrancy reasons (https://doc.rust-lang.org/nightly/std/alloc/trait.GlobalAlloc.html#re-entrance), but CString::new invoked indirectly here will reserve an extra byte of memory in the passed String using the Global, not System, allocator. I think we don't actually have a problem here because Thread::new isn't called with a name from thread::current(), but it's probably worth adding some comments for that.
Separately from those comments, I also noticed while poking at this that the PR adding those guarantees (#144465) didn't add tests confirming that the functions in question didn't invoke the global allocator when called. I don't recall seeing a subsequent PR with tests but cutting this to track adding some. I think we wouldn't be able to easily write a unit test since those run concurrently, but it seems doable to put together a UI test or run-make test (we may need to use a C / raw pthread spawned thread, not sure).
cc @orlp
Activity
valentynkit commentedon Aug 12, 2026
I was going through this code, and the thread name doesn't look like a problem on the creation path. But when the name is freed it does call the global allocator.
Creation:
Builder::new().name("worker").spawn()->Thread::new(id, Some(name))->CStringWhen the last handle is dropped:
MyAlloc::dealloc()->drop(last Thread handle)->drop Inner.name (CString)->__rust_dealloc->MyAlloc::deallocSo an allocator that keeps a handle around can end up dropping the last ref. I tried this with an allocator that registers threads and releases the handle from inside dealloc, and it does re-enter (only when the thread was named).
I may be missing something, just wanted to share some findings in case it may be helpful.
zanville commentedon Oct 3, 2026
@rustbot claim
Rollup merge of rust-lang#163730 - zanville:global-alloc-reentry-test…
Unrolled build for #163730 in rollup 164928
Rollup merge of #163730 - zanville:global-alloc-reentry-tests, r=Mark…