_pt_thread_death_internal(), which is part of Linux's nptl pthreads
implementation, calls free() after calling TSD destructors. This was causing a crash during thread exit, since the magazine rack was no longer valid for the thread. Fix this by using a special mag_rack value to indicate that deallocation should bypass the magazine machinery.
This commit is contained in:
parent
6f89d4b806
commit
d3068c3f46
@ -3977,18 +3977,33 @@ arena_dalloc(arena_t *arena, arena_chunk_t *chunk, void *ptr)
|
|||||||
#ifdef JEMALLOC_MAG
|
#ifdef JEMALLOC_MAG
|
||||||
if (opt_mag) {
|
if (opt_mag) {
|
||||||
mag_rack_t *rack = mag_rack;
|
mag_rack_t *rack = mag_rack;
|
||||||
|
if ((uintptr_t)rack > (uintptr_t)1)
|
||||||
|
mag_rack_dalloc(rack, ptr);
|
||||||
|
else {
|
||||||
if (rack == NULL) {
|
if (rack == NULL) {
|
||||||
rack = mag_rack_create(arena);
|
rack = mag_rack_create(arena);
|
||||||
if (rack == NULL) {
|
if (rack == NULL) {
|
||||||
|
malloc_spin_lock(&arena->lock);
|
||||||
|
arena_dalloc_small(arena,
|
||||||
|
chunk, ptr, mapelm);
|
||||||
|
malloc_spin_unlock(
|
||||||
|
&arena->lock);
|
||||||
|
}
|
||||||
|
mag_rack = rack;
|
||||||
|
pthread_setspecific(mag_rack_tsd, rack);
|
||||||
|
mag_rack_dalloc(rack, ptr);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* This thread is currently exiting, so
|
||||||
|
* directly deallocate.
|
||||||
|
*/
|
||||||
|
assert(rack == (void *)(uintptr_t)1);
|
||||||
malloc_spin_lock(&arena->lock);
|
malloc_spin_lock(&arena->lock);
|
||||||
arena_dalloc_small(arena, chunk, ptr,
|
arena_dalloc_small(arena, chunk, ptr,
|
||||||
mapelm);
|
mapelm);
|
||||||
malloc_spin_unlock(&arena->lock);
|
malloc_spin_unlock(&arena->lock);
|
||||||
}
|
}
|
||||||
mag_rack = rack;
|
|
||||||
pthread_setspecific(mag_rack_tsd, rack);
|
|
||||||
}
|
}
|
||||||
mag_rack_dalloc(rack, ptr);
|
|
||||||
} else {
|
} else {
|
||||||
#endif
|
#endif
|
||||||
malloc_spin_lock(&arena->lock);
|
malloc_spin_lock(&arena->lock);
|
||||||
@ -5759,11 +5774,9 @@ thread_cleanup(void *arg)
|
|||||||
#ifdef JEMALLOC_MAG
|
#ifdef JEMALLOC_MAG
|
||||||
assert((mag_rack_t *)arg == mag_rack);
|
assert((mag_rack_t *)arg == mag_rack);
|
||||||
if (mag_rack != NULL) {
|
if (mag_rack != NULL) {
|
||||||
assert(mag_rack != (void *)-1);
|
assert(mag_rack != (void *)(uintptr_t)1);
|
||||||
mag_rack_destroy(mag_rack);
|
mag_rack_destroy(mag_rack);
|
||||||
#ifdef JEMALLOC_DEBUG
|
mag_rack = (void *)(uintptr_t)1;
|
||||||
mag_rack = (void *)-1;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user