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: AsanThreadSummary(LinkerInitialized)31 explicit AsanThreadSummary(LinkerInitialized) { } // for T0. Init(u32 parent_tid,StackTrace * stack)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 } tid()42 u32 tid() { return tid_; } set_tid(u32 tid)43 void set_tid(u32 tid) { tid_ = tid; } parent_tid()44 u32 parent_tid() { return parent_tid_; } announced()45 bool announced() { return announced_; } set_announced(bool announced)46 void set_announced(bool announced) { announced_ = announced; } stack()47 StackTrace *stack() { return &stack_; } thread()48 AsanThread *thread() { return thread_; } set_thread(AsanThread * thread)49 void set_thread(AsanThread *thread) { thread_ = thread; } 50 static void TSDDtor(void *tsd); set_name(const char * name)51 void set_name(const char *name) { 52 internal_strncpy(name_, name, sizeof(name_) - 1); 53 } name()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 stack_top()79 uptr stack_top() { return stack_top_; } stack_bottom()80 uptr stack_bottom() { return stack_bottom_; } stack_size()81 uptr stack_size() { return stack_top_ - stack_bottom_; } tid()82 u32 tid() { return summary_->tid(); } summary()83 AsanThreadSummary *summary() { return summary_; } set_summary(AsanThreadSummary * summary)84 void set_summary(AsanThreadSummary *summary) { summary_ = summary; } 85 86 const char *GetFrameNameByAddr(uptr addr, uptr *offset); 87 AddrIsInStack(uptr addr)88 bool AddrIsInStack(uptr addr) { 89 return addr >= stack_bottom_ && addr < stack_top_; 90 } 91 fake_stack()92 FakeStack &fake_stack() { return fake_stack_; } malloc_storage()93 AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; } stats()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