I need the patch below on FreeBSD/amd64, otherwise trace cache pool is not initialized, and e.g. Gtest-bt loops infinitely in mempool.c:add_memory() due to obj_size == 0.
commit 6d904047253827a047907a45b67694c17df2c65d Author: Konstantin Belousov <[email protected]> Date: Sat Sep 17 00:47:23 2011 +0300 On FreeBSD, as well as on the Solaris < 10, weak pthread_once stub is always exported from libc. But it does nothing, which means that if threaded library is not loaded, then pthread_once() call do not actually call the initializer finction. The construct if (likely (pthread_once != 0)) { pthread_once(&trace_cache_once, &trace_cache_init_once); then fails to initialize the trace cache on x86_64. Work around by checking that the initializer was indeed called. Note that this can break if libthr is loaded dynamically, but my belief is that there is no platforms which allow dynamic loading of the threading library. diff --git a/src/x86_64/Gtrace.c b/src/x86_64/Gtrace.c index 4a5b583..4e8b8af 100644 --- a/src/x86_64/Gtrace.c +++ b/src/x86_64/Gtrace.c @@ -50,6 +50,7 @@ typedef struct static const unw_tdep_frame_t empty_frame = { 0, UNW_X86_64_FRAME_OTHER, -1, -1, 0, -1, -1 }; static pthread_mutex_t trace_init_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_once_t trace_cache_once = PTHREAD_ONCE_INIT; +static sig_atomic_t trace_cache_once_happen; static pthread_key_t trace_cache_key; static struct mempool trace_cache_pool; @@ -69,6 +70,7 @@ trace_cache_init_once (void) { pthread_key_create (&trace_cache_key, &trace_cache_free); mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); + trace_cache_once_happen = 1; } static unw_tdep_frame_t * @@ -137,6 +139,24 @@ trace_cache_expand (unw_trace_cache_t *cache) static __thread unw_trace_cache_t *tls_cache; +static unw_trace_cache_t * +trace_cache_get_unthreaded (void) +{ + unw_trace_cache_t *cache; + intrmask_t saved_mask; + static unw_trace_cache_t *global_cache = 0; + lock_acquire (&trace_init_lock, saved_mask); + if (! global_cache) + { + mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); + global_cache = trace_cache_create (); + } + cache = global_cache; + lock_release (&trace_init_lock, saved_mask); + Debug(5, "using cache %p\n", cache); + return cache; +} + /* Get the frame cache for the current thread. Create it if there is none. */ static unw_trace_cache_t * trace_cache_get (void) @@ -145,6 +165,10 @@ trace_cache_get (void) if (likely (pthread_once != 0)) { pthread_once(&trace_cache_once, &trace_cache_init_once); + if (!trace_cache_once_happen) + { + return trace_cache_get_unthreaded(); + } if (! (cache = tls_cache)) { cache = trace_cache_create(); @@ -156,18 +180,7 @@ trace_cache_get (void) } else { - intrmask_t saved_mask; - static unw_trace_cache_t *global_cache = 0; - lock_acquire (&trace_init_lock, saved_mask); - if (! global_cache) - { - mempool_init (&trace_cache_pool, sizeof (unw_trace_cache_t), 0); - global_cache = trace_cache_create (); - } - cache = global_cache; - lock_release (&trace_init_lock, saved_mask); - Debug(5, "using cache %p\n", cache); - return cache; + return trace_cache_get_unthreaded(); } }
pgp8vFTw4UR5F.pgp
Description: PGP signature
_______________________________________________ Libunwind-devel mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/libunwind-devel
