From a0bf242230be117a3e54a7d1fc3f11e5a83606ec Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Fri, 29 Jan 2010 14:30:41 -0800 Subject: [PATCH] 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. --- jemalloc/src/internal/jemalloc_arena.h | 3 +-- jemalloc/src/jemalloc.c | 30 +++++++++++++++++--------- jemalloc/src/jemalloc_arena.c | 13 ++++------- jemalloc/src/jemalloc_trace.c | 6 +++++- 4 files changed, 30 insertions(+), 22 deletions(-) diff --git a/jemalloc/src/internal/jemalloc_arena.h b/jemalloc/src/internal/jemalloc_arena.h index 3c1947d4..610735dc 100644 --- a/jemalloc/src/internal/jemalloc_arena.h +++ b/jemalloc/src/internal/jemalloc_arena.h @@ -412,8 +412,7 @@ void arena_stats_merge(arena_t *arena, size_t *nactive, size_t *ndirty, #endif void *arena_ralloc(void *ptr, size_t size, size_t oldsize); bool arena_new(arena_t *arena, unsigned ind); -bool arena_boot0(void); -void arena_boot1(void); +bool arena_boot(void); #endif /* JEMALLOC_H_EXTERNS */ /******************************************************************************/ diff --git a/jemalloc/src/jemalloc.c b/jemalloc/src/jemalloc.c index 885209bd..55c77ed0 100644 --- a/jemalloc/src/jemalloc.c +++ b/jemalloc/src/jemalloc.c @@ -702,6 +702,15 @@ MALLOC_OUT: } } + /* Register fork handlers. */ + if (pthread_atfork(jemalloc_prefork, jemalloc_postfork, + jemalloc_postfork) != 0) { + malloc_write4("", ": Error in pthread_atfork()\n", "", + ""); + if (opt_abort) + abort(); + } + if (ctl_boot()) { malloc_mutex_unlock(&init_lock); return (true); @@ -717,18 +726,25 @@ MALLOC_OUT: #endif if (opt_stats_print) { /* Print statistics at exit. */ - atexit(stats_print_atexit); + if (atexit(stats_print_atexit) != 0) { + malloc_write4("", ": Error in atexit()\n", "", + ""); + if (opt_abort) + abort(); + } } - /* Register fork handlers. */ - pthread_atfork(jemalloc_prefork, jemalloc_postfork, jemalloc_postfork); + if (chunk_boot()) { + malloc_mutex_unlock(&init_lock); + return (true); + } if (base_boot()) { malloc_mutex_unlock(&init_lock); return (true); } - if (arena_boot0()) { + if (arena_boot()) { malloc_mutex_unlock(&init_lock); return (true); } @@ -737,12 +753,6 @@ MALLOC_OUT: tcache_boot(); #endif - if (chunk_boot()) { - malloc_mutex_unlock(&init_lock); - return (true); - } - arena_boot1(); - if (huge_boot()) { malloc_mutex_unlock(&init_lock); return (true); diff --git a/jemalloc/src/jemalloc_arena.c b/jemalloc/src/jemalloc_arena.c index e1e1b8f6..e1970c8c 100644 --- a/jemalloc/src/jemalloc_arena.c +++ b/jemalloc/src/jemalloc_arena.c @@ -2156,8 +2156,9 @@ small_size2bin_init_hard(void) } bool -arena_boot0(void) +arena_boot(void) { + size_t header_size; /* Set variables according to the value of opt_lg_[qc]space_max. */ qspace_max = (1U << opt_lg_qspace_max); @@ -2214,14 +2215,6 @@ arena_boot0(void) if (small_size2bin_init()) 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 * page map. @@ -2231,4 +2224,6 @@ arena_boot1(void) arena_chunk_header_npages = (header_size >> PAGE_SHIFT) + ((header_size & PAGE_MASK) != 0); arena_maxclass = chunksize - (arena_chunk_header_npages << PAGE_SHIFT); + + return (false); } diff --git a/jemalloc/src/jemalloc_trace.c b/jemalloc/src/jemalloc_trace.c index 89d30a73..f1e2a617 100644 --- a/jemalloc/src/jemalloc_trace.c +++ b/jemalloc/src/jemalloc_trace.c @@ -262,7 +262,11 @@ trace_boot(void) return (true); /* Flush trace buffers at exit. */ - atexit(malloc_trace_flush_all); + if (atexit(malloc_trace_flush_all) != 0) { + malloc_write4("", ": Error in atexit()\n", "", ""); + if (opt_abort) + abort(); + } /* Receive thread exit notifications. */ if (pthread_key_create(&trace_tsd, trace_thread_cleanup) != 0) { malloc_write4("",