From ccddcbc6f5e300693e5eb21c09ce971b50f91d9f Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Tue, 19 Mar 2024 08:07:03 +0300 Subject: [PATCH] Fix ADD_CALL_CHAIN() placement to follow GC_store_debug_info_inner call (a cherry-pick of commit f4f943bcd from 'master') Issue #613 (bdwgc). This might be important for the case of malloc redirection as backtrace() need to be called without the allocator lock held. * dbg_mlc.c (store_debug_info, GC_debug_generic_malloc_inner, GC_debug_generic_malloc_inner_ignore_off_page): Call ADD_CALL_CHAIN() right after GC_store_debug_info_inner() call (instead of before it). * gcj_mlc.c (GC_debug_gcj_malloc): Likewise. * dbg_mlc.c (GC_debug_generic_malloc_inner, GC_debug_generic_malloc_inner_ignore_off_page): Define base local variable. * gcj_mlc.c (GC_debug_gcj_malloc): Likewise. --- dbg_mlc.c | 24 +++++++++++++----------- gcj_mlc.c | 14 +++++++------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/dbg_mlc.c b/dbg_mlc.c index dc94de004..c05e96e41 100644 --- a/dbg_mlc.c +++ b/dbg_mlc.c @@ -299,8 +299,8 @@ static void *store_debug_info(void *p, size_t lb, LOCK(); if (!GC_debugging_started) GC_start_debugging_inner(); - ADD_CALL_CHAIN(p, ra); result = GC_store_debug_info_inner(p, (word)lb, s, i); + ADD_CALL_CHAIN(p, ra); UNLOCK(); return result; } @@ -574,11 +574,11 @@ STATIC void * GC_debug_generic_malloc(size_t lb, int knd, GC_EXTRA_PARAMS) /* case, we need to make sure that all objects have debug headers. */ GC_INNER void * GC_debug_generic_malloc_inner(size_t lb, int k) { - void * result; + void *base, *result; GC_ASSERT(I_HOLD_LOCK()); - result = GC_generic_malloc_inner(SIZET_SAT_ADD(lb, DEBUG_BYTES), k); - if (NULL == result) { + base = GC_generic_malloc_inner(SIZET_SAT_ADD(lb, DEBUG_BYTES), k); + if (NULL == base) { GC_err_printf("GC internal allocation (%lu bytes) returning NULL\n", (unsigned long) lb); return(0); @@ -586,19 +586,20 @@ STATIC void * GC_debug_generic_malloc(size_t lb, int knd, GC_EXTRA_PARAMS) if (!GC_debugging_started) { GC_start_debugging_inner(); } - ADD_CALL_CHAIN(result, GC_RETURN_ADDR); - return (GC_store_debug_info_inner(result, (word)lb, "INTERNAL", 0)); + result = GC_store_debug_info_inner(base, (word)lb, "INTERNAL", 0); + ADD_CALL_CHAIN(base, GC_RETURN_ADDR); + return result; } GC_INNER void * GC_debug_generic_malloc_inner_ignore_off_page(size_t lb, int k) { - void * result; + void *base, *result; GC_ASSERT(I_HOLD_LOCK()); - result = GC_generic_malloc_inner_ignore_off_page( + base = GC_generic_malloc_inner_ignore_off_page( SIZET_SAT_ADD(lb, DEBUG_BYTES), k); - if (NULL == result) { + if (NULL == base) { GC_err_printf("GC internal allocation (%lu bytes) returning NULL\n", (unsigned long) lb); return(0); @@ -606,8 +607,9 @@ STATIC void * GC_debug_generic_malloc(size_t lb, int knd, GC_EXTRA_PARAMS) if (!GC_debugging_started) { GC_start_debugging_inner(); } - ADD_CALL_CHAIN(result, GC_RETURN_ADDR); - return (GC_store_debug_info_inner(result, (word)lb, "INTERNAL", 0)); + result = GC_store_debug_info_inner(base, (word)lb, "INTERNAL", 0); + ADD_CALL_CHAIN(base, GC_RETURN_ADDR); + return result; } #endif /* DBG_HDRS_ALL */ diff --git a/gcj_mlc.c b/gcj_mlc.c index 478206fbe..10525d21d 100644 --- a/gcj_mlc.c +++ b/gcj_mlc.c @@ -192,28 +192,28 @@ static void maybe_finalize(void) GC_API GC_ATTR_MALLOC void * GC_CALL GC_debug_gcj_malloc(size_t lb, void * ptr_to_struct_containing_descr, GC_EXTRA_PARAMS) { - void * result; + void *base, *result; DCL_LOCK_STATE; /* We're careful to avoid extra calls, which could */ /* confuse the backtrace. */ LOCK(); maybe_finalize(); - result = GC_generic_malloc_inner(SIZET_SAT_ADD(lb, DEBUG_BYTES), - GC_gcj_debug_kind); - if (result == 0) { + base = GC_generic_malloc_inner(SIZET_SAT_ADD(lb, DEBUG_BYTES), + GC_gcj_debug_kind); + if (NULL == base) { GC_oom_func oom_fn = GC_oom_fn; UNLOCK(); GC_err_printf("GC_debug_gcj_malloc(%lu, %p) returning NULL (%s:%d)\n", (unsigned long)lb, ptr_to_struct_containing_descr, s, i); return((*oom_fn)(lb)); } - *((void **)((ptr_t)result + sizeof(oh))) = ptr_to_struct_containing_descr; + *((void **)((ptr_t)base + sizeof(oh))) = ptr_to_struct_containing_descr; if (!GC_debugging_started) { GC_start_debugging_inner(); } - ADD_CALL_CHAIN(result, ra); - result = GC_store_debug_info_inner(result, (word)lb, s, i); + result = GC_store_debug_info_inner(base, (word)lb, s, i); + ADD_CALL_CHAIN(base, ra); UNLOCK(); GC_dirty(result); REACHABLE_AFTER_DIRTY(ptr_to_struct_containing_descr);