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_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: 36 explicit AsanThreadContext(int tid) 37 : ThreadContextBase(tid), 38 announced(false), 39 thread(0) { 40 internal_memset(&stack, 0, sizeof(stack)); 41 } 42 bool announced; 43 StackTrace stack; 44 AsanThread *thread; 45 46 void OnCreated(void *arg); 47 void OnFinished(); 48 }; 49 50 // AsanThreadContext objects are never freed, so we need many of them. 51 COMPILER_CHECK(sizeof(AsanThreadContext) <= 4096); 52 53 // AsanThread are stored in TSD and destroyed when the thread dies. 54 class AsanThread { 55 public: 56 static AsanThread *Create(thread_callback_t start_routine, void *arg); 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 63 uptr stack_top() { return stack_top_; } 64 uptr stack_bottom() { return stack_bottom_; } 65 uptr stack_size() { return stack_top_ - stack_bottom_; } 66 uptr tls_begin() { return tls_begin_; } 67 uptr tls_end() { return tls_end_; } 68 u32 tid() { return context_->tid; } 69 AsanThreadContext *context() { return context_; } 70 void set_context(AsanThreadContext *context) { context_ = context; } 71 72 const char *GetFrameNameByAddr(uptr addr, uptr *offset, uptr *frame_pc); 73 74 bool AddrIsInStack(uptr addr) { 75 return addr >= stack_bottom_ && addr < stack_top_; 76 } 77 78 void LazyInitFakeStack() { 79 if (fake_stack_) return; 80 fake_stack_ = (FakeStack*)MmapOrDie(sizeof(FakeStack), "FakeStack"); 81 fake_stack_->Init(stack_size()); 82 } 83 void DeleteFakeStack() { 84 if (!fake_stack_) return; 85 fake_stack_->Cleanup(); 86 UnmapOrDie(fake_stack_, sizeof(FakeStack)); 87 } 88 FakeStack *fake_stack() { return fake_stack_; } 89 90 AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; } 91 AsanStats &stats() { return stats_; } 92 93 private: 94 AsanThread() {} 95 void SetThreadStackAndTls(); 96 void ClearShadowForThreadStackAndTLS(); 97 AsanThreadContext *context_; 98 thread_callback_t start_routine_; 99 void *arg_; 100 uptr stack_top_; 101 uptr stack_bottom_; 102 uptr tls_begin_; 103 uptr tls_end_; 104 105 FakeStack *fake_stack_; 106 AsanThreadLocalMallocStorage malloc_storage_; 107 AsanStats stats_; 108 }; 109 110 struct CreateThreadContextArgs { 111 AsanThread *thread; 112 StackTrace *stack; 113 }; 114 115 // Returns a single instance of registry. 116 ThreadRegistry &asanThreadRegistry(); 117 118 // Must be called under ThreadRegistryLock. 119 AsanThreadContext *GetThreadContextByTidLocked(u32 tid); 120 121 // Get the current thread. May return 0. 122 AsanThread *GetCurrentThread(); 123 void SetCurrentThread(AsanThread *t); 124 u32 GetCurrentTidOrInvalid(); 125 AsanThread *FindThreadByStackAddress(uptr addr); 126 127 // Used to handle fork(). 128 void EnsureMainThreadIDIsCorrect(); 129 } // namespace __asan 130 131 #endif // ASAN_THREAD_H 132