Call malloc_test_boot0() from malloc_init_hard_recursible().

When using LinuxThreads, malloc bootstrapping deadlocks, since
malloc_tsd_boot0() ends up calling pthread_setspecific(), which causes
recursive allocation.  Fix it by moving the malloc_tsd_boot0() call to
malloc_init_hard_recursible().

The deadlock was introduced by 8bb3198f72
(Refactor/fix arenas manipulation.), when tsd_boot() was split and the
top half, tsd_boot0(), got an extra tsd_wrapper_set() call.
This commit is contained in:
Cosmin Paraschiv 2016-01-11 11:05:00 -08:00 committed by Jason Evans
parent 43de1b3ebc
commit 9cb481a73f

View File

@ -1276,26 +1276,37 @@ malloc_init_hard_a0(void)
* *
* init_lock must be held. * init_lock must be held.
*/ */
static void static bool
malloc_init_hard_recursible(void) malloc_init_hard_recursible(void)
{ {
bool ret = false;
malloc_init_state = malloc_init_recursible; malloc_init_state = malloc_init_recursible;
malloc_mutex_unlock(&init_lock); malloc_mutex_unlock(&init_lock);
/* LinuxThreads' pthread_setspecific() allocates. */
if (malloc_tsd_boot0()) {
ret = true;
goto label_return;
}
ncpus = malloc_ncpus(); ncpus = malloc_ncpus();
#if (!defined(JEMALLOC_MUTEX_INIT_CB) && !defined(JEMALLOC_ZONE) \ #if (!defined(JEMALLOC_MUTEX_INIT_CB) && !defined(JEMALLOC_ZONE) \
&& !defined(_WIN32) && !defined(__native_client__)) && !defined(_WIN32) && !defined(__native_client__))
/* LinuxThreads's pthread_atfork() allocates. */ /* LinuxThreads' pthread_atfork() allocates. */
if (pthread_atfork(jemalloc_prefork, jemalloc_postfork_parent, if (pthread_atfork(jemalloc_prefork, jemalloc_postfork_parent,
jemalloc_postfork_child) != 0) { jemalloc_postfork_child) != 0) {
ret = true;
malloc_write("<jemalloc>: Error in pthread_atfork()\n"); malloc_write("<jemalloc>: Error in pthread_atfork()\n");
if (opt_abort) if (opt_abort)
abort(); abort();
} }
#endif #endif
label_return:
malloc_mutex_lock(&init_lock); malloc_mutex_lock(&init_lock);
return (ret);
} }
/* init_lock must be held. */ /* init_lock must be held. */
@ -1365,16 +1376,16 @@ malloc_init_hard(void)
malloc_mutex_unlock(&init_lock); malloc_mutex_unlock(&init_lock);
return (true); return (true);
} }
if (malloc_tsd_boot0()) {
malloc_mutex_unlock(&init_lock); if (malloc_init_hard_recursible()) {
return (true);
}
if (config_prof && prof_boot2()) {
malloc_mutex_unlock(&init_lock); malloc_mutex_unlock(&init_lock);
return (true); return (true);
} }
malloc_init_hard_recursible(); if (config_prof && prof_boot2()) {
malloc_mutex_unlock(&init_lock);
return (true);
}
if (malloc_init_hard_finish()) { if (malloc_init_hard_finish()) {
malloc_mutex_unlock(&init_lock); malloc_mutex_unlock(&init_lock);