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_fake_stack.h" 18 #include "asan_stats.h" 19 #include "sanitizer_common/sanitizer_common.h" 20 #include "sanitizer_common/sanitizer_libc.h" 21 #include "sanitizer_common/sanitizer_thread_registry.h" 22 23 namespace __asan { 24 25 const u32 kInvalidTid = 0xffffff; // Must fit into 24 bits. 26 const u32 kMaxNumberOfThreads = (1 << 22); // 4M 27 28 class AsanThread; 29 30 // These objects are created for every thread and are never deleted, 31 // so we can find them by tid even if the thread is long dead. 32 class AsanThreadContext : public ThreadContextBase { 33 public: 34 explicit AsanThreadContext(int tid) 35 : ThreadContextBase(tid), 36 announced(false), 37 destructor_iterations(kPthreadDestructorIterations), 38 stack_id(0), 39 thread(0) { 40 } 41 bool announced; 42 u8 destructor_iterations; 43 u32 stack_id; 44 AsanThread *thread; 45 46 void OnCreated(void *arg); 47 void OnFinished(); 48 }; 49 50 // AsanThreadContext objects are never freed, so we need many of them. 51 COMPILER_CHECK(sizeof(AsanThreadContext) <= 256); 52 53 // AsanThread are stored in TSD and destroyed when the thread dies. 54 class AsanThread { 55 public: 56 static AsanThread *Create(thread_callback_t start_routine, void *arg); 57 static void TSDDtor(void *tsd); 58 void Destroy(); 59 60 void Init(); // Should be called from the thread itself. 61 thread_return_t ThreadStart(uptr os_id); 62 63 uptr stack_top() { return stack_top_; } 64 uptr stack_bottom() { return stack_bottom_; } 65 uptr stack_size() { return stack_size_; } 66 uptr tls_begin() { return tls_begin_; } 67 uptr tls_end() { return tls_end_; } 68 u32 tid() { return context_->tid; } 69 AsanThreadContext *context() { return context_; } 70 void set_context(AsanThreadContext *context) { context_ = context; } 71 72 struct StackFrameAccess { 73 uptr offset; 74 uptr frame_pc; 75 const char *frame_descr; 76 }; 77 bool GetStackFrameAccessByAddr(uptr addr, StackFrameAccess *access); 78 79 bool AddrIsInStack(uptr addr) { 80 return addr >= stack_bottom_ && addr < stack_top_; 81 } 82 83 void DeleteFakeStack(int tid) { 84 if (!fake_stack_) return; 85 FakeStack *t = fake_stack_; 86 fake_stack_ = 0; 87 SetTLSFakeStack(0); 88 t->Destroy(tid); 89 } 90 91 bool has_fake_stack() { 92 return (reinterpret_cast<uptr>(fake_stack_) > 1); 93 } 94 95 FakeStack *fake_stack() { 96 if (!__asan_option_detect_stack_use_after_return) 97 return 0; 98 if (!has_fake_stack()) 99 return AsyncSignalSafeLazyInitFakeStack(); 100 return fake_stack_; 101 } 102 103 // True is this thread is currently unwinding stack (i.e. collecting a stack 104 // trace). Used to prevent deadlocks on platforms where libc unwinder calls 105 // malloc internally. See PR17116 for more details. 106 bool isUnwinding() const { return unwinding_; } 107 void setUnwinding(bool b) { unwinding_ = b; } 108 109 // True if we are in a deadly signal handler. 110 bool isInDeadlySignal() const { return in_deadly_signal_; } 111 void setInDeadlySignal(bool b) { in_deadly_signal_ = b; } 112 113 AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; } 114 AsanStats &stats() { return stats_; } 115 116 private: 117 // NOTE: There is no AsanThread constructor. It is allocated 118 // via mmap() and *must* be valid in zero-initialized state. 119 void SetThreadStackAndTls(); 120 void ClearShadowForThreadStackAndTLS(); 121 FakeStack *AsyncSignalSafeLazyInitFakeStack(); 122 123 AsanThreadContext *context_; 124 thread_callback_t start_routine_; 125 void *arg_; 126 uptr stack_top_; 127 uptr stack_bottom_; 128 // stack_size_ == stack_top_ - stack_bottom_; 129 // It needs to be set in a async-signal-safe manner. 130 uptr stack_size_; 131 uptr tls_begin_; 132 uptr tls_end_; 133 134 FakeStack *fake_stack_; 135 AsanThreadLocalMallocStorage malloc_storage_; 136 AsanStats stats_; 137 bool unwinding_; 138 bool in_deadly_signal_; 139 }; 140 141 // ScopedUnwinding is a scope for stacktracing member of a context 142 class ScopedUnwinding { 143 public: 144 explicit ScopedUnwinding(AsanThread *t) : thread(t) { 145 t->setUnwinding(true); 146 } 147 ~ScopedUnwinding() { thread->setUnwinding(false); } 148 149 private: 150 AsanThread *thread; 151 }; 152 153 // ScopedDeadlySignal is a scope for handling deadly signals. 154 class ScopedDeadlySignal { 155 public: 156 explicit ScopedDeadlySignal(AsanThread *t) : thread(t) { 157 if (thread) thread->setInDeadlySignal(true); 158 } 159 ~ScopedDeadlySignal() { 160 if (thread) thread->setInDeadlySignal(false); 161 } 162 163 private: 164 AsanThread *thread; 165 }; 166 167 struct CreateThreadContextArgs { 168 AsanThread *thread; 169 StackTrace *stack; 170 }; 171 172 // Returns a single instance of registry. 173 ThreadRegistry &asanThreadRegistry(); 174 175 // Must be called under ThreadRegistryLock. 176 AsanThreadContext *GetThreadContextByTidLocked(u32 tid); 177 178 // Get the current thread. May return 0. 179 AsanThread *GetCurrentThread(); 180 void SetCurrentThread(AsanThread *t); 181 u32 GetCurrentTidOrInvalid(); 182 AsanThread *FindThreadByStackAddress(uptr addr); 183 184 // Used to handle fork(). 185 void EnsureMainThreadIDIsCorrect(); 186 } // namespace __asan 187 188 #endif // ASAN_THREAD_H 189