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