blob: d54e666ba9e15201a5e6af49fb9c8eed8cc06c47 [file] [log] [blame]
commit 17df56c50e9bacebeabe69d0cad35b3247163f03
Author: Todd Lipcon <todd@cloudera.com>
Date: Mon Mar 26 17:06:51 2018 -0700
trace_cache: free on second-to-last destructor invocation
Freeing a trace cache requires acquiring a mutex, and when running in
ThreadSanitizer, TSAN itself unhooks from a thread in the last
destructor iteration. So, if we try to free the trace cache in the last
destructor iteration, we end up crashing TSAN because the mutex
acquisition attempts to use already-destructed TSAN context info
for the thread.
diff --git a/src/x86_64/Gtrace.c b/src/x86_64/Gtrace.c
index 7412271..6cd8aee 100644
--- a/src/x86_64/Gtrace.c
+++ b/src/x86_64/Gtrace.c
@@ -58,12 +58,12 @@ static void
trace_cache_free (void *arg)
{
unw_trace_cache_t *cache = arg;
- if (++cache->dtor_count < PTHREAD_DESTRUCTOR_ITERATIONS)
+ if (++cache->dtor_count < PTHREAD_DESTRUCTOR_ITERATIONS - 1)
{
/* Not yet our turn to get destroyed. Re-install ourselves into the key. */
pthread_setspecific(trace_cache_key, cache);
Debug(5, "delayed freeing cache %p (%zx to go)\n", cache,
- PTHREAD_DESTRUCTOR_ITERATIONS - cache->dtor_count);
+ PTHREAD_DESTRUCTOR_ITERATIONS - 1 - cache->dtor_count);
return;
}
tls_cache_destroyed = 1;