-
Notifications
You must be signed in to change notification settings - Fork 900
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
Thread heaps aren't abandoned on MacOS #164
Comments
Here is an another example that leaks memory, in case it's easier to reproduce: #include <thread>
#include <mimalloc.h>
#include <stdio.h>
void t1main() {
void *p = mi_malloc(1024);
if (!p) {
printf("out of memory");
abort();
}
mi_free(p);
}
int main() {
while (1) {
auto t1 = std::thread(t1main);
t1.join();
}
return 0;
} |
One fix is to have |
colesbury
added a commit
to colesbury/mimalloc
that referenced
this issue
Oct 24, 2019
On Mac OS, the thread-local _mi_default_heap may get reset before _mi_thread_done is called, leaking the default heap on non-main threads. Now the current default heap is also stored in mi_pthread_key (or mi_fls_key on Windows). The _mi_thread_done function is called with this value. See microsoft#164
Hi Sam -- Awesome for finding this -- I cannot test it today but I will merge early next week! Thanks! |
daanx
added a commit
that referenced
this issue
Nov 14, 2019
On Mac OS, the thread-local _mi_default_heap may get reset before _mi_thread_done is called, leaking the default heap on non-main threads. Now the current default heap is also stored in mi_pthread_key (or mi_fls_key on Windows). The _mi_thread_done function is called with this value.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.mimalloc/src/init.c
Lines 232 to 234 in e946d56
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 themi_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.:The text was updated successfully, but these errors were encountered: