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:
parent
d8f565f239
commit
a0bf242230
@ -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 */
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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>",
|
||||||
|
Loading…
Reference in New Issue
Block a user