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_stack.h" 20 #include "asan_stats.h" 21 22 namespace __asan { 23 24 const size_t kMaxThreadStackSize = 16 * (1 << 20); // 16M 25 26 class AsanThread; 27 28 // These objects are created for every thread and are never deleted, 29 // so we can find them by tid even if the thread is long dead. 30 class AsanThreadSummary { 31 public: AsanThreadSummary(LinkerInitialized)32 explicit AsanThreadSummary(LinkerInitialized) { } // for T0. AsanThreadSummary(int parent_tid,AsanStackTrace * stack)33 AsanThreadSummary(int parent_tid, AsanStackTrace *stack) 34 : parent_tid_(parent_tid), 35 announced_(false) { 36 tid_ = -1; 37 if (stack) { 38 stack_ = *stack; 39 } 40 thread_ = 0; 41 } Announce()42 void Announce() { 43 if (tid_ == 0) return; // no need to announce the main thread. 44 if (!announced_) { 45 announced_ = true; 46 Printf("Thread T%d created by T%d here:\n", tid_, parent_tid_); 47 stack_.PrintStack(); 48 } 49 } tid()50 int tid() { return tid_; } set_tid(int tid)51 void set_tid(int tid) { tid_ = tid; } thread()52 AsanThread *thread() { return thread_; } set_thread(AsanThread * thread)53 void set_thread(AsanThread *thread) { thread_ = thread; } 54 static void TSDDtor(void *tsd); 55 56 private: 57 int tid_; 58 int parent_tid_; 59 bool announced_; 60 AsanStackTrace stack_; 61 AsanThread *thread_; 62 }; 63 64 // AsanThread are stored in TSD and destroyed when the thread dies. 65 class AsanThread { 66 public: 67 explicit AsanThread(LinkerInitialized); // for T0. 68 static AsanThread *Create(int parent_tid, thread_callback_t start_routine, 69 void *arg, AsanStackTrace *stack); 70 void Destroy(); 71 72 void Init(); // Should be called from the thread itself. 73 thread_return_t ThreadStart(); 74 stack_top()75 uintptr_t stack_top() { return stack_top_; } stack_bottom()76 uintptr_t stack_bottom() { return stack_bottom_; } stack_size()77 size_t stack_size() { return stack_top_ - stack_bottom_; } tid()78 int tid() { return summary_->tid(); } summary()79 AsanThreadSummary *summary() { return summary_; } set_summary(AsanThreadSummary * summary)80 void set_summary(AsanThreadSummary *summary) { summary_ = summary; } 81 82 const char *GetFrameNameByAddr(uintptr_t addr, uintptr_t *offset); 83 AddrIsInStack(uintptr_t addr)84 bool AddrIsInStack(uintptr_t addr) { 85 return addr >= stack_bottom_ && addr < stack_top_; 86 } 87 fake_stack()88 FakeStack &fake_stack() { return fake_stack_; } malloc_storage()89 AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; } stats()90 AsanStats &stats() { return stats_; } 91 92 static const int kInvalidTid = -1; 93 94 private: 95 96 void SetThreadStackTopAndBottom(); 97 void ClearShadowForThreadStack(); 98 AsanThreadSummary *summary_; 99 thread_callback_t start_routine_; 100 void *arg_; 101 uintptr_t stack_top_; 102 uintptr_t stack_bottom_; 103 104 FakeStack fake_stack_; 105 AsanThreadLocalMallocStorage malloc_storage_; 106 AsanStats stats_; 107 }; 108 109 } // namespace __asan 110 111 #endif // ASAN_THREAD_H 112