[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