Home | History | Annotate | Download | only in asan
      1 //===-- asan_thread.h -------------------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file is a part of AddressSanitizer, an address sanity checker.
     11 //
     12 // ASan-private header for asan_thread.cc.
     13 //===----------------------------------------------------------------------===//
     14 #ifndef ASAN_THREAD_H
     15 #define ASAN_THREAD_H
     16 
     17 #include "asan_allocator.h"
     18 #include "asan_internal.h"
     19 #include "asan_fake_stack.h"
     20 #include "asan_stack.h"
     21 #include "asan_stats.h"
     22 #include "sanitizer_common/sanitizer_libc.h"
     23 #include "sanitizer_common/sanitizer_thread_registry.h"
     24 
     25 namespace __asan {
     26 
     27 const u32 kInvalidTid = 0xffffff;  // Must fit into 24 bits.
     28 const u32 kMaxNumberOfThreads = (1 << 22);  // 4M
     29 
     30 class AsanThread;
     31 
     32 // These objects are created for every thread and are never deleted,
     33 // so we can find them by tid even if the thread is long dead.
     34 class AsanThreadContext : public ThreadContextBase {
     35  public:
     36   explicit AsanThreadContext(int tid)
     37       : ThreadContextBase(tid),
     38         announced(false),
     39         thread(0) {
     40     internal_memset(&stack, 0, sizeof(stack));
     41   }
     42   bool announced;
     43   StackTrace stack;
     44   AsanThread *thread;
     45 
     46   void OnCreated(void *arg);
     47   void OnFinished();
     48 };
     49 
     50 // AsanThreadContext objects are never freed, so we need many of them.
     51 COMPILER_CHECK(sizeof(AsanThreadContext) <= 4096);
     52 
     53 // AsanThread are stored in TSD and destroyed when the thread dies.
     54 class AsanThread {
     55  public:
     56   static AsanThread *Create(thread_callback_t start_routine, void *arg);
     57   static void TSDDtor(void *tsd);
     58   void Destroy();
     59 
     60   void Init();  // Should be called from the thread itself.
     61   thread_return_t ThreadStart(uptr os_id);
     62 
     63   uptr stack_top() { return stack_top_; }
     64   uptr stack_bottom() { return stack_bottom_; }
     65   uptr stack_size() { return stack_top_ - stack_bottom_; }
     66   uptr tls_begin() { return tls_begin_; }
     67   uptr tls_end() { return tls_end_; }
     68   u32 tid() { return context_->tid; }
     69   AsanThreadContext *context() { return context_; }
     70   void set_context(AsanThreadContext *context) { context_ = context; }
     71 
     72   const char *GetFrameNameByAddr(uptr addr, uptr *offset, uptr *frame_pc);
     73 
     74   bool AddrIsInStack(uptr addr) {
     75     return addr >= stack_bottom_ && addr < stack_top_;
     76   }
     77 
     78   void LazyInitFakeStack() {
     79     if (fake_stack_) return;
     80     fake_stack_ = (FakeStack*)MmapOrDie(sizeof(FakeStack), "FakeStack");
     81     fake_stack_->Init(stack_size());
     82   }
     83   void DeleteFakeStack() {
     84     if (!fake_stack_) return;
     85     fake_stack_->Cleanup();
     86     UnmapOrDie(fake_stack_, sizeof(FakeStack));
     87   }
     88   FakeStack *fake_stack() { return fake_stack_; }
     89 
     90   AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
     91   AsanStats &stats() { return stats_; }
     92 
     93  private:
     94   AsanThread() {}
     95   void SetThreadStackAndTls();
     96   void ClearShadowForThreadStackAndTLS();
     97   AsanThreadContext *context_;
     98   thread_callback_t start_routine_;
     99   void *arg_;
    100   uptr  stack_top_;
    101   uptr  stack_bottom_;
    102   uptr tls_begin_;
    103   uptr tls_end_;
    104 
    105   FakeStack *fake_stack_;
    106   AsanThreadLocalMallocStorage malloc_storage_;
    107   AsanStats stats_;
    108 };
    109 
    110 struct CreateThreadContextArgs {
    111   AsanThread *thread;
    112   StackTrace *stack;
    113 };
    114 
    115 // Returns a single instance of registry.
    116 ThreadRegistry &asanThreadRegistry();
    117 
    118 // Must be called under ThreadRegistryLock.
    119 AsanThreadContext *GetThreadContextByTidLocked(u32 tid);
    120 
    121 // Get the current thread. May return 0.
    122 AsanThread *GetCurrentThread();
    123 void SetCurrentThread(AsanThread *t);
    124 u32 GetCurrentTidOrInvalid();
    125 AsanThread *FindThreadByStackAddress(uptr addr);
    126 
    127 // Used to handle fork().
    128 void EnsureMainThreadIDIsCorrect();
    129 }  // namespace __asan
    130 
    131 #endif  // ASAN_THREAD_H
    132