Home | History | Annotate | Line # | Download | only in asan
asan_thread.h revision 1.1
      1  1.1  mrg //===-- asan_thread.h -------------------------------------------*- C++ -*-===//
      2  1.1  mrg //
      3  1.1  mrg // This file is distributed under the University of Illinois Open Source
      4  1.1  mrg // License. See LICENSE.TXT for details.
      5  1.1  mrg //
      6  1.1  mrg //===----------------------------------------------------------------------===//
      7  1.1  mrg //
      8  1.1  mrg // This file is a part of AddressSanitizer, an address sanity checker.
      9  1.1  mrg //
     10  1.1  mrg // ASan-private header for asan_thread.cc.
     11  1.1  mrg //===----------------------------------------------------------------------===//
     12  1.1  mrg #ifndef ASAN_THREAD_H
     13  1.1  mrg #define ASAN_THREAD_H
     14  1.1  mrg 
     15  1.1  mrg #include "asan_allocator.h"
     16  1.1  mrg #include "asan_internal.h"
     17  1.1  mrg #include "asan_stack.h"
     18  1.1  mrg #include "asan_stats.h"
     19  1.1  mrg #include "sanitizer_common/sanitizer_libc.h"
     20  1.1  mrg 
     21  1.1  mrg namespace __asan {
     22  1.1  mrg 
     23  1.1  mrg const u32 kInvalidTid = 0xffffff;  // Must fit into 24 bits.
     24  1.1  mrg 
     25  1.1  mrg class AsanThread;
     26  1.1  mrg 
     27  1.1  mrg // These objects are created for every thread and are never deleted,
     28  1.1  mrg // so we can find them by tid even if the thread is long dead.
     29  1.1  mrg class AsanThreadSummary {
     30  1.1  mrg  public:
     31  1.1  mrg   explicit AsanThreadSummary(LinkerInitialized) { }  // for T0.
     32  1.1  mrg   void Init(u32 parent_tid, StackTrace *stack) {
     33  1.1  mrg     parent_tid_ = parent_tid;
     34  1.1  mrg     announced_ = false;
     35  1.1  mrg     tid_ = kInvalidTid;
     36  1.1  mrg     if (stack) {
     37  1.1  mrg       internal_memcpy(&stack_, stack, sizeof(*stack));
     38  1.1  mrg     }
     39  1.1  mrg     thread_ = 0;
     40  1.1  mrg     name_[0] = 0;
     41  1.1  mrg   }
     42  1.1  mrg   u32 tid() { return tid_; }
     43  1.1  mrg   void set_tid(u32 tid) { tid_ = tid; }
     44  1.1  mrg   u32 parent_tid() { return parent_tid_; }
     45  1.1  mrg   bool announced() { return announced_; }
     46  1.1  mrg   void set_announced(bool announced) { announced_ = announced; }
     47  1.1  mrg   StackTrace *stack() { return &stack_; }
     48  1.1  mrg   AsanThread *thread() { return thread_; }
     49  1.1  mrg   void set_thread(AsanThread *thread) { thread_ = thread; }
     50  1.1  mrg   static void TSDDtor(void *tsd);
     51  1.1  mrg   void set_name(const char *name) {
     52  1.1  mrg     internal_strncpy(name_, name, sizeof(name_) - 1);
     53  1.1  mrg   }
     54  1.1  mrg   const char *name() { return name_; }
     55  1.1  mrg 
     56  1.1  mrg  private:
     57  1.1  mrg   u32 tid_;
     58  1.1  mrg   u32 parent_tid_;
     59  1.1  mrg   bool announced_;
     60  1.1  mrg   StackTrace stack_;
     61  1.1  mrg   AsanThread *thread_;
     62  1.1  mrg   char name_[128];
     63  1.1  mrg };
     64  1.1  mrg 
     65  1.1  mrg // AsanThreadSummary objects are never freed, so we need many of them.
     66  1.1  mrg COMPILER_CHECK(sizeof(AsanThreadSummary) <= 4094);
     67  1.1  mrg 
     68  1.1  mrg // AsanThread are stored in TSD and destroyed when the thread dies.
     69  1.1  mrg class AsanThread {
     70  1.1  mrg  public:
     71  1.1  mrg   explicit AsanThread(LinkerInitialized);  // for T0.
     72  1.1  mrg   static AsanThread *Create(u32 parent_tid, thread_callback_t start_routine,
     73  1.1  mrg                             void *arg, StackTrace *stack);
     74  1.1  mrg   void Destroy();
     75  1.1  mrg 
     76  1.1  mrg   void Init();  // Should be called from the thread itself.
     77  1.1  mrg   thread_return_t ThreadStart();
     78  1.1  mrg 
     79  1.1  mrg   uptr stack_top() { return stack_top_; }
     80  1.1  mrg   uptr stack_bottom() { return stack_bottom_; }
     81  1.1  mrg   uptr stack_size() { return stack_top_ - stack_bottom_; }
     82  1.1  mrg   u32 tid() { return summary_->tid(); }
     83  1.1  mrg   AsanThreadSummary *summary() { return summary_; }
     84  1.1  mrg   void set_summary(AsanThreadSummary *summary) { summary_ = summary; }
     85  1.1  mrg 
     86  1.1  mrg   const char *GetFrameNameByAddr(uptr addr, uptr *offset);
     87  1.1  mrg 
     88  1.1  mrg   bool AddrIsInStack(uptr addr) {
     89  1.1  mrg     return addr >= stack_bottom_ && addr < stack_top_;
     90  1.1  mrg   }
     91  1.1  mrg 
     92  1.1  mrg   FakeStack &fake_stack() { return fake_stack_; }
     93  1.1  mrg   AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
     94  1.1  mrg   AsanStats &stats() { return stats_; }
     95  1.1  mrg 
     96  1.1  mrg  private:
     97  1.1  mrg   void SetThreadStackTopAndBottom();
     98  1.1  mrg   void ClearShadowForThreadStack();
     99  1.1  mrg   AsanThreadSummary *summary_;
    100  1.1  mrg   thread_callback_t start_routine_;
    101  1.1  mrg   void *arg_;
    102  1.1  mrg   uptr  stack_top_;
    103  1.1  mrg   uptr  stack_bottom_;
    104  1.1  mrg 
    105  1.1  mrg   FakeStack fake_stack_;
    106  1.1  mrg   AsanThreadLocalMallocStorage malloc_storage_;
    107  1.1  mrg   AsanStats stats_;
    108  1.1  mrg };
    109  1.1  mrg 
    110  1.1  mrg }  // namespace __asan
    111  1.1  mrg 
    112  1.1  mrg #endif  // ASAN_THREAD_H
    113