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