Fix bootstrapping crash.

If a custom small_size2bin table was required due to non-default size
class settings, memory allocation prior to initializing chunk parameters
would cause a crash due to division by 0.  The fix re-orders the various
*_boot() function calls.

Bootstrapping is simpler now than it was before the base allocator
started just using the chunk allocator directly.  This allows
arena_boot[01]() to be combined.

Add error detection for pthread_atfork() and atexit() function calls.
This commit is contained in:
Jason Evans 2010-01-29 14:30:41 -08:00
parent d8f565f239
commit a0bf242230
4 changed files with 30 additions and 22 deletions

View File

@ -412,8 +412,7 @@ void arena_stats_merge(arena_t *arena, size_t *nactive, size_t *ndirty,
#endif #endif
void *arena_ralloc(void *ptr, size_t size, size_t oldsize); void *arena_ralloc(void *ptr, size_t size, size_t oldsize);
bool arena_new(arena_t *arena, unsigned ind); bool arena_new(arena_t *arena, unsigned ind);
bool arena_boot0(void); bool arena_boot(void);
void arena_boot1(void);
#endif /* JEMALLOC_H_EXTERNS */ #endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/ /******************************************************************************/

View File

@ -702,6 +702,15 @@ MALLOC_OUT:
} }
} }
/* Register fork handlers. */
if (pthread_atfork(jemalloc_prefork, jemalloc_postfork,
jemalloc_postfork) != 0) {
malloc_write4("<jemalloc>", ": Error in pthread_atfork()\n", "",
"");
if (opt_abort)
abort();
}
if (ctl_boot()) { if (ctl_boot()) {
malloc_mutex_unlock(&init_lock); malloc_mutex_unlock(&init_lock);
return (true); return (true);
@ -717,18 +726,25 @@ MALLOC_OUT:
#endif #endif
if (opt_stats_print) { if (opt_stats_print) {
/* Print statistics at exit. */ /* Print statistics at exit. */
atexit(stats_print_atexit); if (atexit(stats_print_atexit) != 0) {
malloc_write4("<jemalloc>", ": Error in atexit()\n", "",
"");
if (opt_abort)
abort();
}
} }
/* Register fork handlers. */ if (chunk_boot()) {
pthread_atfork(jemalloc_prefork, jemalloc_postfork, jemalloc_postfork); malloc_mutex_unlock(&init_lock);
return (true);
}
if (base_boot()) { if (base_boot()) {
malloc_mutex_unlock(&init_lock); malloc_mutex_unlock(&init_lock);
return (true); return (true);
} }
if (arena_boot0()) { if (arena_boot()) {
malloc_mutex_unlock(&init_lock); malloc_mutex_unlock(&init_lock);
return (true); return (true);
} }
@ -737,12 +753,6 @@ MALLOC_OUT:
tcache_boot(); tcache_boot();
#endif #endif
if (chunk_boot()) {
malloc_mutex_unlock(&init_lock);
return (true);
}
arena_boot1();
if (huge_boot()) { if (huge_boot()) {
malloc_mutex_unlock(&init_lock); malloc_mutex_unlock(&init_lock);
return (true); return (true);

View File

@ -2156,8 +2156,9 @@ small_size2bin_init_hard(void)
} }
bool bool
arena_boot0(void) arena_boot(void)
{ {
size_t header_size;
/* Set variables according to the value of opt_lg_[qc]space_max. */ /* Set variables according to the value of opt_lg_[qc]space_max. */
qspace_max = (1U << opt_lg_qspace_max); qspace_max = (1U << opt_lg_qspace_max);
@ -2214,14 +2215,6 @@ arena_boot0(void)
if (small_size2bin_init()) if (small_size2bin_init())
return (true); return (true);
return (false);
}
void
arena_boot1(void)
{
size_t header_size;
/* /*
* Compute the header size such that it is large enough to contain the * Compute the header size such that it is large enough to contain the
* page map. * page map.
@ -2231,4 +2224,6 @@ arena_boot1(void)
arena_chunk_header_npages = (header_size >> PAGE_SHIFT) + arena_chunk_header_npages = (header_size >> PAGE_SHIFT) +
((header_size & PAGE_MASK) != 0); ((header_size & PAGE_MASK) != 0);
arena_maxclass = chunksize - (arena_chunk_header_npages << PAGE_SHIFT); arena_maxclass = chunksize - (arena_chunk_header_npages << PAGE_SHIFT);
return (false);
} }

View File

@ -262,7 +262,11 @@ trace_boot(void)
return (true); return (true);
/* Flush trace buffers at exit. */ /* Flush trace buffers at exit. */
atexit(malloc_trace_flush_all); if (atexit(malloc_trace_flush_all) != 0) {
malloc_write4("<jemalloc>", ": Error in atexit()\n", "", "");
if (opt_abort)
abort();
}
/* Receive thread exit notifications. */ /* Receive thread exit notifications. */
if (pthread_key_create(&trace_tsd, trace_thread_cleanup) != 0) { if (pthread_key_create(&trace_tsd, trace_thread_cleanup) != 0) {
malloc_write4("<jemalloc>", malloc_write4("<jemalloc>",