summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler-rt/lib/lsan/lsan_common_mac.cc18
-rw-r--r--compiler-rt/lib/lsan/lsan_thread.cc1
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() {
OpenPOWER on IntegriCloud