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