[llvm-commits] [compiler-rt] r147910 - in /compiler-rt/trunk/lib/asan: asan_interceptors.cc asan_mac.cc asan_thread.cc asan_thread_registry.cc asan_thread_registry.h

Kostya Serebryany kcc at google.com
Tue Jan 10 18:03:16 PST 2012


Author: kcc
Date: Tue Jan 10 20:03:16 2012
New Revision: 147910

URL: http://llvm.org/viewvc/llvm-project?rev=147910&view=rev
Log:
[asan] get rid of the scary TSD destructor code. Now, we store the leaky AsanThreadSummary in TSD and never remove it from there.

Modified:
    compiler-rt/trunk/lib/asan/asan_interceptors.cc
    compiler-rt/trunk/lib/asan/asan_mac.cc
    compiler-rt/trunk/lib/asan/asan_thread.cc
    compiler-rt/trunk/lib/asan/asan_thread_registry.cc
    compiler-rt/trunk/lib/asan/asan_thread_registry.h

Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=147910&r1=147909&r2=147910&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Tue Jan 10 20:03:16 2012
@@ -230,8 +230,6 @@
 int WRAP(pthread_create)(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg) {
   GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false);
-  AsanThread *curr_thread = asanThreadRegistry().GetCurrent();
-  CHECK(curr_thread || asanThreadRegistry().IsCurrentThreadDying());
   int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne();
   AsanThread *t = AsanThread::Create(current_tid, start_routine, arg);
   asanThreadRegistry().RegisterThread(t, current_tid, &stack);

Modified: compiler-rt/trunk/lib/asan/asan_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_mac.cc?rev=147910&r1=147909&r2=147910&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_mac.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_mac.cc Tue Jan 10 20:03:16 2012
@@ -191,22 +191,8 @@
            block, pthread_self());
   }
   AsanThread *t = asanThreadRegistry().GetCurrent();
-  if (t) {
-    // We've already executed a job on this worker thread. Let's reuse the
-    // AsanThread object.
-    if (t != asanThreadRegistry().GetMain()) {
-      // Flush the statistics and update the current thread's tid.
-      asanThreadRegistry().UnregisterThread(t);
-      asanThreadRegistry().RegisterThread(t, context->parent_tid, &stack);
-    }
-    // Otherwise the worker is being executed on the main thread -- we are
-    // draining the dispatch queue.
-    // TODO(glider): any checks for that?
-  } else {
-    // It's incorrect to assert that the current thread is not dying: at least
-    // the callbacks from dispatch_sync() are sometimes called after the TSD is
-    // destroyed.
-    AsanThread *t = AsanThread::Create(context->parent_tid, NULL, NULL);
+  if (!t) {
+    t = AsanThread::Create(context->parent_tid, NULL, NULL);
     asanThreadRegistry().RegisterThread(t, context->parent_tid, &stack);
     t->Init();
     asanThreadRegistry().SetCurrent(t);
@@ -229,17 +215,6 @@
       (asan_block_context_t*) asan_malloc(sizeof(asan_block_context_t), stack);
   asan_ctxt->block = ctxt;
   asan_ctxt->func = func;
-  AsanThread *curr_thread = asanThreadRegistry().GetCurrent();
-  if (FLAG_debug) {
-    // Sometimes at Chromium teardown this assertion is violated:
-    //  -- a task is created via dispatch_async() on the "CFMachPort"
-    //     thread while doing _dispatch_queue_drain();
-    //  -- a task is created via dispatch_async_f() on the
-    //     "com.apple.root.default-overcommit-priority" thread while doing
-    //     _dispatch_dispose().
-    // TODO(glider): find out what's going on.
-    CHECK(curr_thread || asanThreadRegistry().IsCurrentThreadDying());
-  }
   asan_ctxt->parent_tid = asanThreadRegistry().GetCurrentTidOrMinusOne();
   return asan_ctxt;
 }

Modified: compiler-rt/trunk/lib/asan/asan_thread.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_thread.cc?rev=147910&r1=147909&r2=147910&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_thread.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_thread.cc Tue Jan 10 20:03:16 2012
@@ -15,6 +15,7 @@
 #include "asan_interceptors.h"
 #include "asan_procmaps.h"
 #include "asan_thread.h"
+#include "asan_thread_registry.h"
 #include "asan_mapping.h"
 
 namespace __asan {
@@ -83,6 +84,9 @@
     Report("T%d exited\n", tid());
   }
 
+  asanThreadRegistry().UnregisterThread(this);
+  this->Destroy();
+
   return res;
 }
 

Modified: compiler-rt/trunk/lib/asan/asan_thread_registry.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_thread_registry.cc?rev=147910&r1=147909&r2=147910&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_thread_registry.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_thread_registry.cc Tue Jan 10 20:03:16 2012
@@ -28,49 +28,6 @@
   return asan_thread_registry;
 }
 
-#ifdef ANDROID
-#ifndef PTHREAD_DESTRUCTOR_ITERATIONS
-#define PTHREAD_DESTRUCTOR_ITERATIONS 4
-#endif
-#endif
-
-// Dark magic below. In order to be able to notice that we're not handling
-// some thread creation routines (e.g. on Mac OS) we want to distinguish the
-// thread that used to have a corresponding AsanThread object from the thread
-// that never had one. That's why upon AsanThread destruction we set the
-// pthread_key value to some odd number (that's not a valid pointer), instead
-// of NULL.
-// Because the TSD destructor for a non-NULL key value is called iteratively,
-// we increase the value by two, keeping it an invalid pointer.
-// Because the TSD implementations are allowed to call such a destructor
-// infinitely (see
-// http://pubs.opengroup.org/onlinepubs/009604499/functions/pthread_key_create.html
-// ), we exit the program after a certain number of iterations.
-static void DestroyAsanTsd(void *tsd) {
-  intptr_t iter = (intptr_t)tsd;
-  if (iter % 2 == 0) {
-    // The pointer is valid.
-    AsanThread *t = (AsanThread*)tsd;
-    if (t != asanThreadRegistry().GetMain()) {
-      asanThreadRegistry().UnregisterThread(t);
-      t->Destroy();
-    }
-    iter = 1;
-  } else {
-    // The pointer is invalid -- we've already destroyed the TSD before.
-    // If |iter| is too big, we're in the infinite loop. This should be
-    // impossible on the systems AddressSanitizer was tested on.
-    CHECK(iter < 4 * PTHREAD_DESTRUCTOR_ITERATIONS);
-    iter += 2;
-  }
-  CHECK(0 == pthread_setspecific(asanThreadRegistry().GetTlsKey(),
-                                 (void*)iter));
-  if (FLAG_v >= 2) {
-    Report("DestroyAsanTsd: writing %p to the TSD slot of thread %p\n",
-           (void*)iter, pthread_self());
-  }
-}
-
 AsanThreadRegistry::AsanThreadRegistry(LinkerInitialized x)
     : main_thread_(x),
       main_thread_summary_(x),
@@ -78,11 +35,11 @@
       mu_(x) { }
 
 void AsanThreadRegistry::Init() {
-  CHECK(0 == pthread_key_create(&tls_key_, DestroyAsanTsd));
+  CHECK(0 == pthread_key_create(&tls_key_, 0));
   tls_key_created_ = true;
-  SetCurrent(&main_thread_);
   main_thread_.set_summary(&main_thread_summary_);
   main_thread_summary_.set_thread(&main_thread_);
+  SetCurrent(&main_thread_);
   thread_summaries_[0] = &main_thread_summary_;
   n_threads_ = 1;
 }
@@ -114,46 +71,28 @@
 
 AsanThread *AsanThreadRegistry::GetCurrent() {
   CHECK(tls_key_created_);
-  AsanThread *thread = (AsanThread*)pthread_getspecific(tls_key_);
-  if ((!thread || (intptr_t)thread % 2) && FLAG_v >= 2) {
-    Report("GetCurrent: %p for thread %p\n", thread, pthread_self());
-  }
-  if ((intptr_t)thread % 2) {
-    // Invalid pointer -- we've deleted the AsanThread already. Return NULL as
-    // if the TSD was empty.
-    // TODO(glider): if the code in the client TSD destructor calls
-    // pthread_create(), we'll set the parent tid of the spawned thread to NULL,
-    // although the creation stack will belong to the current thread. This may
-    // confuse the user, but is quite unlikely.
-    return NULL;
-  } else {
-    // NULL or valid pointer to AsanThread.
-    return thread;
-  }
+  AsanThreadSummary *summary =
+      (AsanThreadSummary *)pthread_getspecific(tls_key_);
+  if (!summary) return 0;
+  return summary->thread();
 }
 
 void AsanThreadRegistry::SetCurrent(AsanThread *t) {
-  if (FLAG_v >=2) {
-    Report("SetCurrent: %p for thread %p\n", t, pthread_self());
+  CHECK(t->summary());
+  if (FLAG_v >= 2) {
+    Report("SetCurrent: %p for thread %p\n", t->summary(), pthread_self());
   }
   // Make sure we do not reset the current AsanThread.
   intptr_t old_key = (intptr_t)pthread_getspecific(tls_key_);
-  CHECK(!old_key || old_key % 2);
-  CHECK(0 == pthread_setspecific(tls_key_, t));
-  CHECK(pthread_getspecific(tls_key_) == t);
+  CHECK(!old_key);
+  CHECK(0 == pthread_setspecific(tls_key_, t->summary()));
+  CHECK(pthread_getspecific(tls_key_) == t->summary());
 }
 
 pthread_key_t AsanThreadRegistry::GetTlsKey() {
   return tls_key_;
 }
 
-// Returns true iff DestroyAsanTsd() was already called for this thread.
-bool AsanThreadRegistry::IsCurrentThreadDying() {
-  CHECK(tls_key_created_);
-  intptr_t thread = (intptr_t)pthread_getspecific(tls_key_);
-  return (bool)(thread % 2);
-}
-
 AsanStats &AsanThreadRegistry::GetCurrentThreadStats() {
   AsanThread *t = GetCurrent();
   return (t) ? t->stats() : main_thread_.stats();

Modified: compiler-rt/trunk/lib/asan/asan_thread_registry.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_thread_registry.h?rev=147910&r1=147909&r2=147910&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_thread_registry.h (original)
+++ compiler-rt/trunk/lib/asan/asan_thread_registry.h Tue Jan 10 20:03:16 2012
@@ -39,7 +39,6 @@
   AsanThread *GetCurrent();
   void SetCurrent(AsanThread *t);
   pthread_key_t GetTlsKey();
-  bool IsCurrentThreadDying();
 
   int GetCurrentTidOrMinusOne() {
     AsanThread *t = GetCurrent();





More information about the llvm-commits mailing list