Fix recursive malloc during bootstrap on QNX
pthread_key_create on QNX triggers recursive allocation during tsd bootstrapping. Using tsd_init_check_recursion to detect that. Before pthread_key_create, the address of tsd_boot_wrapper is returned from tsd_get_wrapper instead of using TLS to store the pointer. tsd_set_wrapper becomes a no-op. After that, the address of tsd_boot_wrapper is written to TLS and bootstrap continues as before. Signed-off-by: Jin Qian <jqian@aurora.tech>
This commit is contained in:
parent
986cbe4881
commit
96a59c3bb5
@ -52,6 +52,9 @@ tsd_cleanup_wrapper(void *arg) {
|
|||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE void
|
JEMALLOC_ALWAYS_INLINE void
|
||||||
tsd_wrapper_set(tsd_wrapper_t *wrapper) {
|
tsd_wrapper_set(tsd_wrapper_t *wrapper) {
|
||||||
|
if (unlikely(!tsd_booted)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (pthread_setspecific(tsd_tsd, (void *)wrapper) != 0) {
|
if (pthread_setspecific(tsd_tsd, (void *)wrapper) != 0) {
|
||||||
malloc_write("<jemalloc>: Error setting TSD\n");
|
malloc_write("<jemalloc>: Error setting TSD\n");
|
||||||
abort();
|
abort();
|
||||||
@ -60,7 +63,13 @@ tsd_wrapper_set(tsd_wrapper_t *wrapper) {
|
|||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE tsd_wrapper_t *
|
JEMALLOC_ALWAYS_INLINE tsd_wrapper_t *
|
||||||
tsd_wrapper_get(bool init) {
|
tsd_wrapper_get(bool init) {
|
||||||
tsd_wrapper_t *wrapper = (tsd_wrapper_t *)pthread_getspecific(tsd_tsd);
|
tsd_wrapper_t *wrapper;
|
||||||
|
|
||||||
|
if (unlikely(!tsd_booted)) {
|
||||||
|
return &tsd_boot_wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
wrapper = (tsd_wrapper_t *)pthread_getspecific(tsd_tsd);
|
||||||
|
|
||||||
if (init && unlikely(wrapper == NULL)) {
|
if (init && unlikely(wrapper == NULL)) {
|
||||||
tsd_init_block_t block;
|
tsd_init_block_t block;
|
||||||
@ -91,11 +100,21 @@ tsd_wrapper_get(bool init) {
|
|||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE bool
|
JEMALLOC_ALWAYS_INLINE bool
|
||||||
tsd_boot0(void) {
|
tsd_boot0(void) {
|
||||||
|
tsd_wrapper_t *wrapper;
|
||||||
|
tsd_init_block_t block;
|
||||||
|
|
||||||
|
wrapper = (tsd_wrapper_t *)
|
||||||
|
tsd_init_check_recursion(&tsd_init_head, &block);
|
||||||
|
if (wrapper) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
block.data = &tsd_boot_wrapper;
|
||||||
if (pthread_key_create(&tsd_tsd, tsd_cleanup_wrapper) != 0) {
|
if (pthread_key_create(&tsd_tsd, tsd_cleanup_wrapper) != 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
tsd_wrapper_set(&tsd_boot_wrapper);
|
|
||||||
tsd_booted = true;
|
tsd_booted = true;
|
||||||
|
tsd_wrapper_set(&tsd_boot_wrapper);
|
||||||
|
tsd_init_finish(&tsd_init_head, &block);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user