[compiler-rt] r341005 - [hwasan] add basic ThreadRegistry plumbing, also rename HwasanThread to Thread

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 29 17:13:20 PDT 2018


Author: kcc
Date: Wed Aug 29 17:13:20 2018
New Revision: 341005

URL: http://llvm.org/viewvc/llvm-project?rev=341005&view=rev
Log:
[hwasan] add basic ThreadRegistry plumbing, also rename HwasanThread to Thread

Modified:
    compiler-rt/trunk/lib/hwasan/hwasan.cc
    compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc
    compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc
    compiler-rt/trunk/lib/hwasan/hwasan_linux.cc
    compiler-rt/trunk/lib/hwasan/hwasan_report.cc
    compiler-rt/trunk/lib/hwasan/hwasan_thread.cc
    compiler-rt/trunk/lib/hwasan/hwasan_thread.h

Modified: compiler-rt/trunk/lib/hwasan/hwasan.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan.cc?rev=341005&r1=341004&r2=341005&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan.cc Wed Aug 29 17:13:20 2018
@@ -36,17 +36,17 @@ using namespace __sanitizer;
 namespace __hwasan {
 
 void EnterSymbolizer() {
-  HwasanThread *t = GetCurrentThread();
+  Thread *t = GetCurrentThread();
   CHECK(t);
   t->EnterSymbolizer();
 }
 void ExitSymbolizer() {
-  HwasanThread *t = GetCurrentThread();
+  Thread *t = GetCurrentThread();
   CHECK(t);
   t->LeaveSymbolizer();
 }
 bool IsInSymbolizer() {
-  HwasanThread *t = GetCurrentThread();
+  Thread *t = GetCurrentThread();
   return t && t->InSymbolizer();
 }
 
@@ -132,7 +132,7 @@ static void InitializeFlags() {
 
 void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
                    void *context, bool request_fast_unwind) {
-  HwasanThread *t = GetCurrentThread();
+  Thread *t = GetCurrentThread();
   if (!t || !StackTrace::WillUseFastUnwind(request_fast_unwind)) {
     // Block reports from our interceptors during _Unwind_Backtrace.
     SymbolizerScope sym_scope;
@@ -178,6 +178,7 @@ void __hwasan_init() {
   if (hwasan_inited) return;
   hwasan_init_is_running = 1;
   SanitizerToolName = "HWAddressSanitizer";
+  GetThreadRegistry();
 
   InitTlsSize();
 
@@ -208,7 +209,7 @@ void __hwasan_init() {
 
   HwasanAllocatorInit();
 
-  HwasanThread *main_thread = HwasanThread::Create(nullptr, nullptr);
+  Thread *main_thread = Thread::Create(nullptr, nullptr);
   SetCurrentThread(main_thread);
   main_thread->Init();
 
@@ -428,7 +429,7 @@ void __hwasan_handle_longjmp(const void
 static const u8 kFallbackTag = 0xBB;
 
 u8 __hwasan_generate_tag() {
-  HwasanThread *t = GetCurrentThread();
+  Thread *t = GetCurrentThread();
   if (!t) return kFallbackTag;
   return t->GenerateRandomTag();
 }

Modified: compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc?rev=341005&r1=341004&r2=341005&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc Wed Aug 29 17:13:20 2018
@@ -136,7 +136,7 @@ static void *HwasanAllocate(StackTrace *
     }
     ReportAllocationSizeTooBig(size, kMaxAllowedMallocSize, stack);
   }
-  HwasanThread *t = GetCurrentThread();
+  Thread *t = GetCurrentThread();
   void *allocated;
   if (t) {
     AllocatorCache *cache = GetAllocatorCache(&t->malloc_storage());
@@ -199,7 +199,7 @@ void HwasanDeallocate(StackTrace *stack,
   meta->free_context_id = free_context_id;
   // This memory will not be reused by anyone else, so we are free to keep it
   // poisoned.
-  HwasanThread *t = GetCurrentThread();
+  Thread *t = GetCurrentThread();
   if (flags()->max_free_fill_size > 0) {
     uptr fill_size = Min(size, (uptr)flags()->max_free_fill_size);
     internal_memset(untagged_ptr, flags()->free_fill_byte, fill_size);

Modified: compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc?rev=341005&r1=341004&r2=341005&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc Wed Aug 29 17:13:20 2018
@@ -50,18 +50,18 @@ DECLARE_REAL(void *, memcpy, void *dest,
 DECLARE_REAL(void *, memset, void *dest, int c, uptr n)
 
 bool IsInInterceptorScope() {
-  HwasanThread *t = GetCurrentThread();
+  Thread *t = GetCurrentThread();
   return t && t->InInterceptorScope();
 }
 
 struct InterceptorScope {
   InterceptorScope() {
-    HwasanThread *t = GetCurrentThread();
+    Thread *t = GetCurrentThread();
     if (t)
       t->EnterInterceptorScope();
   }
   ~InterceptorScope() {
-    HwasanThread *t = GetCurrentThread();
+    Thread *t = GetCurrentThread();
     if (t)
       t->LeaveInterceptorScope();
   }
@@ -294,7 +294,7 @@ extern "C" int pthread_attr_destroy(void
 
 static void *HwasanThreadStartFunc(void *arg) {
   __hwasan_thread_enter();
-  return ((HwasanThread *)arg)->ThreadStart();
+  return ((Thread *)arg)->ThreadStart();
 }
 
 INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),
@@ -308,7 +308,7 @@ INTERCEPTOR(int, pthread_create, void *t
 
   AdjustStackSize(attr);
 
-  HwasanThread *t = HwasanThread::Create(callback, param);
+  Thread *t = Thread::Create(callback, param);
 
   int res = REAL(pthread_create)(th, attr, HwasanThreadStartFunc, t);
 

Modified: compiler-rt/trunk/lib/hwasan/hwasan_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_linux.cc?rev=341005&r1=341004&r2=341005&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_linux.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_linux.cc Wed Aug 29 17:13:20 2018
@@ -214,13 +214,13 @@ void InstallAtExitHandler() {
 // ---------------------- TSD ---------------- {{{1
 
 extern "C" void __hwasan_thread_enter() {
-  HwasanThread *t = HwasanThread::Create(nullptr, nullptr);
+  Thread *t = Thread::Create(nullptr, nullptr);
   SetCurrentThread(t);
   t->Init();
 }
 
 extern "C" void __hwasan_thread_exit() {
-  HwasanThread *t = GetCurrentThread();
+  Thread *t = GetCurrentThread();
   // Make sure that signal handler can not see a stale current thread pointer.
   atomic_signal_fence(memory_order_seq_cst);
   if (t)
@@ -232,7 +232,7 @@ static pthread_key_t tsd_key;
 static bool tsd_key_inited = false;
 
 void HwasanTSDDtor(void *tsd) {
-  HwasanThread *t = (HwasanThread*)tsd;
+  Thread *t = (Thread*)tsd;
   if (t->destructor_iterations_ > 1) {
     t->destructor_iterations_--;
     CHECK_EQ(0, pthread_setspecific(tsd_key, tsd));
@@ -247,24 +247,24 @@ void HwasanTSDInit() {
   CHECK_EQ(0, pthread_key_create(&tsd_key, HwasanTSDDtor));
 }
 
-HwasanThread *GetCurrentThread() {
-  return (HwasanThread *)pthread_getspecific(tsd_key);
+Thread *GetCurrentThread() {
+  return (Thread *)pthread_getspecific(tsd_key);
 }
 
-void SetCurrentThread(HwasanThread *t) {
+void SetCurrentThread(Thread *t) {
   // Make sure that HwasanTSDDtor gets called at the end.
   CHECK(tsd_key_inited);
-  // Make sure we do not reset the current HwasanThread.
+  // Make sure we do not reset the current Thread.
   CHECK_EQ(0, pthread_getspecific(tsd_key));
   pthread_setspecific(tsd_key, (void *)t);
 }
 #elif SANITIZER_ANDROID
 void HwasanTSDInit() {}
-HwasanThread *GetCurrentThread() {
-  return (HwasanThread*)*get_android_tls_ptr();
+Thread *GetCurrentThread() {
+  return (Thread*)*get_android_tls_ptr();
 }
 
-void SetCurrentThread(HwasanThread *t) {
+void SetCurrentThread(Thread *t) {
   *get_android_tls_ptr() = (uptr)t;
 }
 #else

Modified: compiler-rt/trunk/lib/hwasan/hwasan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_report.cc?rev=341005&r1=341004&r2=341005&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_report.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_report.cc Wed Aug 29 17:13:20 2018
@@ -206,10 +206,12 @@ void ReportTagMismatch(StackTrace *stack
   // * remove reduntant fields from the allocator metadata
   // * use the allocations found in the ring buffer for the main report.
   HeapAllocationRecord har;
-  HwasanThread *t = GetCurrentThread();
-  if (t && FindHeapAllocation(t->heap_allocations(), tagged_addr, &har))
+  Thread *t = GetCurrentThread();
+  if (FindHeapAllocation(t->heap_allocations(), tagged_addr, &har))
     Printf("Address found in the ring buffer: %p %u %u\n", har.tagged_addr,
            har.free_context_id, har.requested_size);
+  Printf("Current thread: tid: %d\n", t->context()->tid);
+
 
   PrintTagsAroundAddr(tag_ptr);
 

Modified: compiler-rt/trunk/lib/hwasan/hwasan_thread.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_thread.cc?rev=341005&r1=341004&r2=341005&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_thread.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_thread.cc Wed Aug 29 17:13:20 2018
@@ -6,6 +6,7 @@
 #include "hwasan_interface_internal.h"
 
 #include "sanitizer_common/sanitizer_file.h"
+#include "sanitizer_common/sanitizer_placement_new.h"
 #include "sanitizer_common/sanitizer_tls_get_addr.h"
 
 namespace __hwasan {
@@ -23,21 +24,24 @@ static u32 RandomSeed() {
   return seed;
 }
 
-HwasanThread *HwasanThread::Create(thread_callback_t start_routine,
+Thread *Thread::Create(thread_callback_t start_routine,
                                void *arg) {
   uptr PageSize = GetPageSizeCached();
-  uptr size = RoundUpTo(sizeof(HwasanThread), PageSize);
-  HwasanThread *thread = (HwasanThread*)MmapOrDie(size, __func__);
+  uptr size = RoundUpTo(sizeof(Thread), PageSize);
+  Thread *thread = (Thread*)MmapOrDie(size, __func__);
   thread->start_routine_ = start_routine;
   thread->arg_ = arg;
   thread->destructor_iterations_ = GetPthreadDestructorIterations();
   thread->random_state_ = flags()->random_tags ? RandomSeed() : 0;
+  thread->context_ = nullptr;
+  ThreadContext::Args args = {thread};
+  thread->tid_ = GetThreadRegistry().CreateThread(0, false, 0, &args);
   if (auto sz = flags()->heap_history_size)
     thread->heap_allocations_ = RingBuffer<HeapAllocationRecord>::New(sz);
   return thread;
 }
 
-void HwasanThread::SetThreadStackAndTls() {
+void Thread::SetThreadStackAndTls() {
   // If this process is "init" (pid 1), /proc may not be mounted yet.
   if (IsMainThread() && !FileExists("/proc/self/maps")) {
     stack_top_ = stack_bottom_ = 0;
@@ -58,7 +62,7 @@ void HwasanThread::SetThreadStackAndTls(
   CHECK(MemIsApp(stack_top_ - 1));
 }
 
-void HwasanThread::Init() {
+void Thread::Init() {
   SetThreadStackAndTls();
   if (stack_bottom_) {
     CHECK(MemIsApp(stack_bottom_));
@@ -66,24 +70,24 @@ void HwasanThread::Init() {
   }
 }
 
-void HwasanThread::ClearShadowForThreadStackAndTLS() {
+void Thread::ClearShadowForThreadStackAndTLS() {
   if (stack_top_ != stack_bottom_)
     TagMemory(stack_bottom_, stack_top_ - stack_bottom_, 0);
   if (tls_begin_ != tls_end_)
     TagMemory(tls_begin_, tls_end_ - tls_begin_, 0);
 }
 
-void HwasanThread::Destroy() {
+void Thread::Destroy() {
   malloc_storage().CommitBack();
   ClearShadowForThreadStackAndTLS();
-  uptr size = RoundUpTo(sizeof(HwasanThread), GetPageSizeCached());
+  uptr size = RoundUpTo(sizeof(Thread), GetPageSizeCached());
   if (heap_allocations_)
     heap_allocations_->Delete();
   UnmapOrDie(this, size);
   DTLS_Destroy();
 }
 
-thread_return_t HwasanThread::ThreadStart() {
+thread_return_t Thread::ThreadStart() {
   return start_routine_(arg_);
 }
 
@@ -95,7 +99,7 @@ static u32 xorshift(u32 state) {
 }
 
 // Generate a (pseudo-)random non-zero tag.
-tag_t HwasanThread::GenerateRandomTag() {
+tag_t Thread::GenerateRandomTag() {
   tag_t tag;
   do {
     if (flags()->random_tags) {
@@ -111,4 +115,32 @@ tag_t HwasanThread::GenerateRandomTag()
   return tag;
 }
 
+void ThreadContext::OnCreated(void *arg) {
+  Args *args = static_cast<Args*>(arg);
+  thread = args->thread;
+  thread->set_context(this);
+}
+
+void ThreadContext::OnFinished() {
+  thread = nullptr;
+}
+
+static const u32 kMaxLiveThreads = 1024;
+
+static ThreadContextBase *ThreadContextFactory(u32 tid) {
+  static ALIGNED(16) char placeholder[sizeof(ThreadContext) * kMaxLiveThreads];
+  void *mem = &placeholder[0] + tid * sizeof(ThreadContext);
+  CHECK_LT(tid, kMaxLiveThreads);
+  return new (mem) ThreadContext(tid);
+}
+
+ThreadRegistry &GetThreadRegistry() {
+  static ALIGNED(16) char placeholder[sizeof(ThreadRegistry)];
+  static ThreadRegistry *registry;
+  if (!registry)
+    registry = new (placeholder)
+        ThreadRegistry(ThreadContextFactory, kMaxLiveThreads, kMaxLiveThreads);
+  return *registry;
+}
+
 } // namespace __hwasan

Modified: compiler-rt/trunk/lib/hwasan/hwasan_thread.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_thread.h?rev=341005&r1=341004&r2=341005&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_thread.h (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_thread.h Wed Aug 29 17:13:20 2018
@@ -16,12 +16,33 @@
 
 #include "hwasan_allocator.h"
 #include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_thread_registry.h"
 
 namespace __hwasan {
 
-class HwasanThread {
+class Thread;
+
+class ThreadContext : public ThreadContextBase {
+ public:
+  explicit ThreadContext(int tid)
+      : ThreadContextBase(tid), thread(nullptr){}
+
+  Thread *thread;
+
+  void OnCreated(void *arg) override;
+  void OnFinished() override;
+
+  struct Args {
+    Thread *thread;
+  };
+};
+
+// We want this to be small.
+COMPILER_CHECK(sizeof(ThreadContext) <= 256);
+
+class Thread {
  public:
-  static HwasanThread *Create(thread_callback_t start_routine, void *arg);
+  static Thread *Create(thread_callback_t start_routine, void *arg);
   void Destroy();
 
   void Init();
@@ -54,12 +75,15 @@ class HwasanThread {
     return heap_allocations_;
   }
 
+  void set_context(ThreadContext *context) { context_ = context; }
+  const ThreadContext *context() const { return context_; }
+
   tag_t GenerateRandomTag();
 
   int destructor_iterations_;
 
  private:
-  // NOTE: There is no HwasanThread constructor. It is allocated
+  // NOTE: There is no Thread constructor. It is allocated
   // via mmap() and *must* be valid in zero-initialized state.
   void SetThreadStackAndTls();
   void ClearShadowForThreadStackAndTLS();
@@ -79,10 +103,18 @@ class HwasanThread {
 
   HwasanThreadLocalMallocStorage malloc_storage_;
   HeapAllocationsRingBuffer *heap_allocations_;
+
+  u32 tid_;
+  ThreadContext *context_;
 };
 
-HwasanThread *GetCurrentThread();
-void SetCurrentThread(HwasanThread *t);
+Thread *GetCurrentThread();
+void SetCurrentThread(Thread *t);
+
+// Returns the ThreadRegistry singleton.
+ThreadRegistry &GetThreadRegistry();
+
+// Returns the ThreadRegistry singleton.
 
 } // namespace __hwasan
 




More information about the llvm-commits mailing list