[compiler-rt] r182854 - [asan] Make ASan report the correct thread address ranges to LSan.

Sergey Matveev earthdok at google.com
Wed May 29 06:09:44 PDT 2013


Author: smatveev
Date: Wed May 29 08:09:44 2013
New Revision: 182854

URL: http://llvm.org/viewvc/llvm-project?rev=182854&view=rev
Log:
[asan] Make ASan report the correct thread address ranges to LSan.

This CL enables thread support in LSan when used on top of ASan.

Added:
    compiler-rt/trunk/lib/asan/lit_tests/unpoison_tls.cc
Modified:
    compiler-rt/trunk/lib/asan/asan_rtl.cc
    compiler-rt/trunk/lib/asan/asan_thread.cc
    compiler-rt/trunk/lib/asan/asan_thread.h

Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=182854&r1=182853&r2=182854&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Wed May 29 08:09:44 2013
@@ -547,6 +547,8 @@ void __asan_init() {
   asan_inited = 1;
   asan_init_is_running = false;
 
+  InitTlsSize();
+
   // Create main thread.
   AsanTSDInit(AsanThread::TSDDtor);
   AsanThread *main_thread = AsanThread::Create(0, 0);

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=182854&r1=182853&r2=182854&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_thread.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_thread.cc Wed May 29 08:09:44 2013
@@ -100,17 +100,17 @@ void AsanThread::Destroy() {
   // We also clear the shadow on thread destruction because
   // some code may still be executing in later TSD destructors
   // and we don't want it to have any poisoned stack.
-  ClearShadowForThreadStack();
+  ClearShadowForThreadStackAndTLS();
   fake_stack().Cleanup();
   uptr size = RoundUpTo(sizeof(AsanThread), GetPageSizeCached());
   UnmapOrDie(this, size);
 }
 
 void AsanThread::Init() {
-  SetThreadStackTopAndBottom();
+  SetThreadStackAndTls();
   CHECK(AddrIsInMem(stack_bottom_));
   CHECK(AddrIsInMem(stack_top_ - 1));
-  ClearShadowForThreadStack();
+  ClearShadowForThreadStackAndTLS();
   if (flags()->verbosity >= 1) {
     int local = 0;
     Report("T%d: stack [%p,%p) size 0x%zx; local=%p\n",
@@ -143,14 +143,21 @@ thread_return_t AsanThread::ThreadStart(
   return res;
 }
 
-void AsanThread::SetThreadStackTopAndBottom() {
-  GetThreadStackTopAndBottom(tid() == 0, &stack_top_, &stack_bottom_);
+void AsanThread::SetThreadStackAndTls() {
+  uptr stack_size = 0, tls_size = 0;
+  GetThreadStackAndTls(tid() == 0, &stack_bottom_, &stack_size, &tls_begin_,
+                       &tls_size);
+  stack_top_ = stack_bottom_ + stack_size;
+  tls_end_ = tls_begin_ + tls_size;
+
   int local;
   CHECK(AddrIsInStack((uptr)&local));
 }
 
-void AsanThread::ClearShadowForThreadStack() {
+void AsanThread::ClearShadowForThreadStackAndTLS() {
   PoisonShadow(stack_bottom_, stack_top_ - stack_bottom_, 0);
+  if (tls_begin_ != tls_end_)
+    PoisonShadow(tls_begin_, tls_end_ - tls_begin_, 0);
 }
 
 const char *AsanThread::GetFrameNameByAddr(uptr addr, uptr *offset,
@@ -251,8 +258,19 @@ namespace __lsan {
 bool GetThreadRangesLocked(uptr os_id, uptr *stack_begin, uptr *stack_end,
                            uptr *tls_begin, uptr *tls_end,
                            uptr *cache_begin, uptr *cache_end) {
-  // FIXME: Stub.
-  return false;
+  __asan::AsanThreadContext *context = static_cast<__asan::AsanThreadContext *>(
+      __asan::asanThreadRegistry().FindThreadContextByOsIDLocked(os_id));
+  if (!context) return false;
+  __asan::AsanThread *t = context->thread;
+  if (!t) return false;
+  *stack_begin = t->stack_bottom();
+  *stack_end = t->stack_top();
+  *tls_begin = t->tls_begin();
+  *tls_end = t->tls_end();
+  // ASan doesn't keep allocator caches in TLS, so these are unused.
+  *cache_begin = 0;
+  *cache_end = 0;
+  return true;
 }
 
 void LockThreadRegistry() {

Modified: compiler-rt/trunk/lib/asan/asan_thread.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_thread.h?rev=182854&r1=182853&r2=182854&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_thread.h (original)
+++ compiler-rt/trunk/lib/asan/asan_thread.h Wed May 29 08:09:44 2013
@@ -63,6 +63,8 @@ class AsanThread {
   uptr stack_top() { return stack_top_; }
   uptr stack_bottom() { return stack_bottom_; }
   uptr stack_size() { return stack_top_ - stack_bottom_; }
+  uptr tls_begin() { return tls_begin_; }
+  uptr tls_end() { return tls_end_; }
   u32 tid() { return context_->tid; }
   AsanThreadContext *context() { return context_; }
   void set_context(AsanThreadContext *context) { context_ = context; }
@@ -79,13 +81,15 @@ class AsanThread {
 
  private:
   AsanThread() {}
-  void SetThreadStackTopAndBottom();
-  void ClearShadowForThreadStack();
+  void SetThreadStackAndTls();
+  void ClearShadowForThreadStackAndTLS();
   AsanThreadContext *context_;
   thread_callback_t start_routine_;
   void *arg_;
   uptr  stack_top_;
   uptr  stack_bottom_;
+  uptr tls_begin_;
+  uptr tls_end_;
 
   FakeStack fake_stack_;
   AsanThreadLocalMallocStorage malloc_storage_;

Added: compiler-rt/trunk/lib/asan/lit_tests/unpoison_tls.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/lit_tests/unpoison_tls.cc?rev=182854&view=auto
==============================================================================
--- compiler-rt/trunk/lib/asan/lit_tests/unpoison_tls.cc (added)
+++ compiler-rt/trunk/lib/asan/lit_tests/unpoison_tls.cc Wed May 29 08:09:44 2013
@@ -0,0 +1,40 @@
+// Test that TLS is unpoisoned on thread death.
+// REQUIRES: x86_64-supported-target,i386-supported-target
+
+// RUN: %clangxx_asan -m64 -O1 %p/SharedLibs/dlclose-test-so.cc \
+// RUN:     -fPIC -shared -o %t-so.so
+// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1
+// RUN: %clangxx_asan -m32 -O1 %p/SharedLibs/dlclose-test-so.cc \
+// RUN:     -fPIC -shared -o %t-so.so
+// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1
+
+#include <assert.h>
+#include <pthread.h>
+#include <stdio.h>
+
+#include <sanitizer/asan_interface.h>
+
+__thread int64_t tls_var[2];
+
+volatile int64_t *p_tls_var;
+
+void *first(void *arg) {
+  ASAN_POISON_MEMORY_REGION(&tls_var, sizeof(tls_var));
+  p_tls_var = tls_var;
+  return 0;
+}
+
+void *second(void *arg) {
+  assert(tls_var == p_tls_var);
+  *p_tls_var = 1;
+  return 0;
+}
+
+int main(int argc, char *argv[]) {
+  pthread_t p;
+  assert(0 == pthread_create(&p, 0, first, 0));
+  assert(0 == pthread_join(p, 0));
+  assert(0 == pthread_create(&p, 0, second, 0));
+  assert(0 == pthread_join(p, 0));
+  return 0;
+}





More information about the llvm-commits mailing list