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