asan_thread.h revision 314564
152419Sjulian//===-- asan_thread.h -------------------------------------------*- C++ -*-===// 252419Sjulian// 352419Sjulian// The LLVM Compiler Infrastructure 452419Sjulian// 552419Sjulian// This file is distributed under the University of Illinois Open Source 652419Sjulian// License. See LICENSE.TXT for details. 752419Sjulian// 852419Sjulian//===----------------------------------------------------------------------===// 952419Sjulian// 1052419Sjulian// This file is a part of AddressSanitizer, an address sanity checker. 1152419Sjulian// 1252419Sjulian// ASan-private header for asan_thread.cc. 1352419Sjulian//===----------------------------------------------------------------------===// 1452419Sjulian 1552419Sjulian#ifndef ASAN_THREAD_H 1652419Sjulian#define ASAN_THREAD_H 1752419Sjulian 1852419Sjulian#include "asan_allocator.h" 1952419Sjulian#include "asan_internal.h" 2052419Sjulian#include "asan_fake_stack.h" 2152419Sjulian#include "asan_stats.h" 2252419Sjulian#include "sanitizer_common/sanitizer_common.h" 2352419Sjulian#include "sanitizer_common/sanitizer_libc.h" 2452419Sjulian#include "sanitizer_common/sanitizer_thread_registry.h" 2552419Sjulian 2652419Sjuliannamespace __sanitizer { 2752419Sjulianstruct DTLS; 2852419Sjulian} // namespace __sanitizer 2952419Sjulian 3052419Sjuliannamespace __asan { 3152419Sjulian 3252419Sjulianconst u32 kInvalidTid = 0xffffff; // Must fit into 24 bits. 3352419Sjulianconst u32 kMaxNumberOfThreads = (1 << 22); // 4M 3452419Sjulian 3552419Sjulianclass AsanThread; 3652419Sjulian 3752419Sjulian// These objects are created for every thread and are never deleted, 3852419Sjulian// so we can find them by tid even if the thread is long dead. 3952419Sjulianclass AsanThreadContext : public ThreadContextBase { 4052419Sjulian public: 4152419Sjulian explicit AsanThreadContext(int tid) 4252419Sjulian : ThreadContextBase(tid), announced(false), 4352419Sjulian destructor_iterations(GetPthreadDestructorIterations()), stack_id(0), 4456708Sarchie thread(nullptr) {} 4552419Sjulian bool announced; 4652419Sjulian u8 destructor_iterations; 47169551Smav u32 stack_id; 4856708Sarchie AsanThread *thread; 49122649Sharti 5052419Sjulian void OnCreated(void *arg) override; 5152419Sjulian void OnFinished() override; 5252419Sjulian}; 5352419Sjulian 5452419Sjulian// AsanThreadContext objects are never freed, so we need many of them. 5552419SjulianCOMPILER_CHECK(sizeof(AsanThreadContext) <= 256); 5652419Sjulian 5752419Sjulian// AsanThread are stored in TSD and destroyed when the thread dies. 5852419Sjulianclass AsanThread { 59122649Sharti public: 60122649Sharti static AsanThread *Create(thread_callback_t start_routine, void *arg, 61122649Sharti u32 parent_tid, StackTrace *stack, bool detached); 62122649Sharti static void TSDDtor(void *tsd); 6352419Sjulian void Destroy(); 6452419Sjulian 6552419Sjulian void Init(); // Should be called from the thread itself. 6652419Sjulian thread_return_t ThreadStart(uptr os_id, 6752419Sjulian atomic_uintptr_t *signal_thread_is_registered); 6852419Sjulian 6952419Sjulian uptr stack_top(); 7052419Sjulian uptr stack_bottom(); 7153913Sarchie uptr stack_size(); 7253913Sarchie uptr tls_begin() { return tls_begin_; } 7352419Sjulian uptr tls_end() { return tls_end_; } 7452419Sjulian DTLS *dtls() { return dtls_; } 75 u32 tid() { return context_->tid; } 76 AsanThreadContext *context() { return 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 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, uptr *bottom_old, 98 uptr *size_old); 99 100 bool has_fake_stack() { 101 return !atomic_load(&stack_switching_, memory_order_relaxed) && 102 (reinterpret_cast<uptr>(fake_stack_) > 1); 103 } 104 105 FakeStack *fake_stack() { 106 if (!__asan_option_detect_stack_use_after_return) 107 return nullptr; 108 if (atomic_load(&stack_switching_, memory_order_relaxed)) 109 return nullptr; 110 if (!has_fake_stack()) 111 return AsyncSignalSafeLazyInitFakeStack(); 112 return fake_stack_; 113 } 114 115 // True is this thread is currently unwinding stack (i.e. collecting a stack 116 // trace). Used to prevent deadlocks on platforms where libc unwinder calls 117 // malloc internally. See PR17116 for more details. 118 bool isUnwinding() const { return unwinding_; } 119 void setUnwinding(bool b) { unwinding_ = b; } 120 121 // True if we are in a deadly signal handler. 122 bool isInDeadlySignal() const { return in_deadly_signal_; } 123 void setInDeadlySignal(bool b) { in_deadly_signal_ = b; } 124 125 AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; } 126 AsanStats &stats() { return stats_; } 127 128 private: 129 // NOTE: There is no AsanThread constructor. It is allocated 130 // via mmap() and *must* be valid in zero-initialized state. 131 void SetThreadStackAndTls(); 132 void ClearShadowForThreadStackAndTLS(); 133 FakeStack *AsyncSignalSafeLazyInitFakeStack(); 134 135 struct StackBounds { 136 uptr bottom; 137 uptr top; 138 }; 139 StackBounds GetStackBounds() const; 140 141 AsanThreadContext *context_; 142 thread_callback_t start_routine_; 143 void *arg_; 144 145 uptr stack_top_; 146 uptr stack_bottom_; 147 // these variables are used when the thread is about to switch stack 148 uptr next_stack_top_; 149 uptr next_stack_bottom_; 150 // true if switching is in progress 151 atomic_uint8_t stack_switching_; 152 153 uptr tls_begin_; 154 uptr tls_end_; 155 DTLS *dtls_; 156 157 FakeStack *fake_stack_; 158 AsanThreadLocalMallocStorage malloc_storage_; 159 AsanStats stats_; 160 bool unwinding_; 161 bool in_deadly_signal_; 162}; 163 164// ScopedUnwinding is a scope for stacktracing member of a context 165class ScopedUnwinding { 166 public: 167 explicit ScopedUnwinding(AsanThread *t) : thread(t) { 168 t->setUnwinding(true); 169 } 170 ~ScopedUnwinding() { thread->setUnwinding(false); } 171 172 private: 173 AsanThread *thread; 174}; 175 176// ScopedDeadlySignal is a scope for handling deadly signals. 177class ScopedDeadlySignal { 178 public: 179 explicit ScopedDeadlySignal(AsanThread *t) : thread(t) { 180 if (thread) thread->setInDeadlySignal(true); 181 } 182 ~ScopedDeadlySignal() { 183 if (thread) thread->setInDeadlySignal(false); 184 } 185 186 private: 187 AsanThread *thread; 188}; 189 190// Returns a single instance of registry. 191ThreadRegistry &asanThreadRegistry(); 192 193// Must be called under ThreadRegistryLock. 194AsanThreadContext *GetThreadContextByTidLocked(u32 tid); 195 196// Get the current thread. May return 0. 197AsanThread *GetCurrentThread(); 198void SetCurrentThread(AsanThread *t); 199u32 GetCurrentTidOrInvalid(); 200AsanThread *FindThreadByStackAddress(uptr addr); 201 202// Used to handle fork(). 203void EnsureMainThreadIDIsCorrect(); 204} // namespace __asan 205 206#endif // ASAN_THREAD_H 207