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