diff options
-rw-r--r-- | compiler-rt/lib/lsan/lsan_common_mac.cc | 18 | ||||
-rw-r--r-- | compiler-rt/lib/lsan/lsan_thread.cc | 1 |
2 files changed, 17 insertions, 2 deletions
diff --git a/compiler-rt/lib/lsan/lsan_common_mac.cc b/compiler-rt/lib/lsan/lsan_common_mac.cc index 5fd2b89afd8..549595da51b 100644 --- a/compiler-rt/lib/lsan/lsan_common_mac.cc +++ b/compiler-rt/lib/lsan/lsan_common_mac.cc @@ -33,7 +33,17 @@ typedef struct { static pthread_key_t key; static pthread_once_t key_once = PTHREAD_ONCE_INIT; -static void make_tls_key() { CHECK_EQ(pthread_key_create(&key, NULL), 0); } +// The main thread destructor requires the current thread id, +// so we can't destroy it until it's been used and reset to invalid tid +void restore_tid_data(void *ptr) { + thread_local_data_t *data = (thread_local_data_t *)ptr; + if (data->current_thread_id != kInvalidTid) + pthread_setspecific(key, data); +} + +static void make_tls_key() { + CHECK_EQ(pthread_key_create(&key, restore_tid_data), 0); +} static thread_local_data_t *get_tls_val(bool alloc) { pthread_once(&key_once, make_tls_key); @@ -65,7 +75,11 @@ void EnableInThisThread() { --*disable_counter; } -u32 GetCurrentThread() { return get_tls_val(true)->current_thread_id; } +u32 GetCurrentThread() { + thread_local_data_t *data = get_tls_val(false); + CHECK(data); + return data->current_thread_id; +} void SetCurrentThread(u32 tid) { get_tls_val(true)->current_thread_id = tid; } diff --git a/compiler-rt/lib/lsan/lsan_thread.cc b/compiler-rt/lib/lsan/lsan_thread.cc index ebec6cdbf14..09eeb9c2498 100644 --- a/compiler-rt/lib/lsan/lsan_thread.cc +++ b/compiler-rt/lib/lsan/lsan_thread.cc @@ -92,6 +92,7 @@ void ThreadStart(u32 tid, uptr os_id) { void ThreadFinish() { thread_registry->FinishThread(GetCurrentThread()); + SetCurrentThread(kInvalidTid); } ThreadContext *CurrentThreadContext() { |