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