-
Notifications
You must be signed in to change notification settings - Fork 990
Description
The _mi_heap_done
function first checks if the default heap is initialized. If it's not initialized, the function exits early without abandoning the thread's default heap.
Lines 232 to 234 in e946d56
static bool _mi_heap_done(void) { | |
mi_heap_t* heap = _mi_heap_default; | |
if (!mi_heap_is_initialized(heap)) return true; |
The problem is roughly that the thread-local variables have already been destroyed by the time _mi_heap_done is called. The access to _mi_heap_default
resets it to _mi_heap_empty
so the mi_heap_is_initialized
check always returns false.
It's a little confusing because I think the __thread
variables are handled by libdyld while the pthread-specific variables are managed by libpthread. Source code for both are at https://opensource.apple.com/release/macos-10145.html. The __thread variables (libdyld) are managed by pthread_key_t under the hood. The order of destruction is unspecified, but it appears that the __thread
variables are destroyed before thread_done is called. (I'm not sure if this is deterministic).
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
macOS Mojave 10.14.6
For simplicity I'm linking to the static libmalloc-debug.a and building with -DMI_OVERRIDE=OFF
.
Test program:
https://gist.github.com/colesbury/1e3e2600e6ea5b71717fb9bfc4285d44
Instrument _mi_heap_done
e.g.:
static bool _mi_heap_done(void) {
mi_heap_t* heap = _mi_heap_default;
if (!mi_heap_is_initialized(heap)) {
printf("heap not initialized\n");
return true;
}
printf("heap done\n"); // This doesn't get called!
...
}