summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrancis Ricci <francisjricci@gmail.com>2017-04-11 19:57:12 +0000
committerFrancis Ricci <francisjricci@gmail.com>2017-04-11 19:57:12 +0000
commit84f17f32ad3561a0be9717733e320ecb8592b92f (patch)
treed33e6e917c80ea7a8bdcdf8f5fb4330a0b1cc007
parent4bb0d78c843e8940b377b641d834d715774097e9 (diff)
downloadbcm5719-llvm-84f17f32ad3561a0be9717733e320ecb8592b92f.tar.gz
bcm5719-llvm-84f17f32ad3561a0be9717733e320ecb8592b92f.zip
Don't delete lsan thread-local data until it's no longer required
Summary: The routines for thread destruction in the thread registry require the lsan thread index, which is stored in pthread tls on OS X. This means that we need to make sure that the lsan tls isn't destroyed until after the thread registry tls. This change ensures that we don't delete the lsan tls until we've finished destroying the thread in the registry, ensuring that the destructor for the lsan tls runs after the destructor for the thread registry tls. This patch also adds a check to ensure that the thread ID is valid before returning it in GetThreadID(), to ensure that the above behavior is working correctly. Reviewers: dvyukov, kubamracek, kcc Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D31884 llvm-svn: 299978
-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