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