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