1 1.1 mrg //===-- asan_thread.h -------------------------------------------*- C++ -*-===// 2 1.1 mrg // 3 1.3 mrg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 1.3 mrg // See https://llvm.org/LICENSE.txt for license information. 5 1.3 mrg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 1.1 mrg // 7 1.1 mrg //===----------------------------------------------------------------------===// 8 1.1 mrg // 9 1.1 mrg // This file is a part of AddressSanitizer, an address sanity checker. 10 1.1 mrg // 11 1.3 mrg // ASan-private header for asan_thread.cpp. 12 1.1 mrg //===----------------------------------------------------------------------===// 13 1.2 mrg 14 1.1 mrg #ifndef ASAN_THREAD_H 15 1.1 mrg #define ASAN_THREAD_H 16 1.1 mrg 17 1.1 mrg #include "asan_allocator.h" 18 1.4 mrg #include "asan_fake_stack.h" 19 1.1 mrg #include "asan_internal.h" 20 1.1 mrg #include "asan_stats.h" 21 1.2 mrg #include "sanitizer_common/sanitizer_common.h" 22 1.1 mrg #include "sanitizer_common/sanitizer_libc.h" 23 1.4 mrg #include "sanitizer_common/sanitizer_thread_arg_retval.h" 24 1.2 mrg #include "sanitizer_common/sanitizer_thread_registry.h" 25 1.2 mrg 26 1.2 mrg namespace __sanitizer { 27 1.2 mrg struct DTLS; 28 1.2 mrg } // namespace __sanitizer 29 1.1 mrg 30 1.1 mrg namespace __asan { 31 1.1 mrg 32 1.1 mrg class AsanThread; 33 1.1 mrg 34 1.1 mrg // These objects are created for every thread and are never deleted, 35 1.1 mrg // so we can find them by tid even if the thread is long dead. 36 1.3 mrg class AsanThreadContext final : public ThreadContextBase { 37 1.1 mrg public: 38 1.2 mrg explicit AsanThreadContext(int tid) 39 1.2 mrg : ThreadContextBase(tid), announced(false), 40 1.2 mrg destructor_iterations(GetPthreadDestructorIterations()), stack_id(0), 41 1.2 mrg thread(nullptr) {} 42 1.2 mrg bool announced; 43 1.2 mrg u8 destructor_iterations; 44 1.2 mrg u32 stack_id; 45 1.2 mrg AsanThread *thread; 46 1.2 mrg 47 1.2 mrg void OnCreated(void *arg) override; 48 1.2 mrg void OnFinished() override; 49 1.2 mrg 50 1.2 mrg struct CreateThreadContextArgs { 51 1.2 mrg AsanThread *thread; 52 1.2 mrg StackTrace *stack; 53 1.2 mrg }; 54 1.1 mrg }; 55 1.1 mrg 56 1.2 mrg // AsanThreadContext objects are never freed, so we need many of them. 57 1.2 mrg COMPILER_CHECK(sizeof(AsanThreadContext) <= 256); 58 1.1 mrg 59 1.4 mrg #if defined(_MSC_VER) && !defined(__clang__) 60 1.4 mrg // MSVC raises a warning about a nonstandard extension being used for the 0 61 1.4 mrg // sized element in this array. Disable this for warn-as-error builds. 62 1.4 mrg # pragma warning(push) 63 1.4 mrg # pragma warning(disable : 4200) 64 1.4 mrg #endif 65 1.4 mrg 66 1.1 mrg // AsanThread are stored in TSD and destroyed when the thread dies. 67 1.1 mrg class AsanThread { 68 1.1 mrg public: 69 1.4 mrg template <typename T> 70 1.4 mrg static AsanThread *Create(const T &data, u32 parent_tid, StackTrace *stack, 71 1.4 mrg bool detached) { 72 1.4 mrg return Create(&data, sizeof(data), parent_tid, stack, detached); 73 1.4 mrg } 74 1.4 mrg static AsanThread *Create(u32 parent_tid, StackTrace *stack, bool detached) { 75 1.4 mrg return Create(nullptr, 0, parent_tid, stack, detached); 76 1.4 mrg } 77 1.2 mrg static void TSDDtor(void *tsd); 78 1.1 mrg void Destroy(); 79 1.1 mrg 80 1.2 mrg struct InitOptions; 81 1.2 mrg void Init(const InitOptions *options = nullptr); 82 1.2 mrg 83 1.4 mrg void ThreadStart(tid_t os_id); 84 1.4 mrg thread_return_t RunThread(); 85 1.1 mrg 86 1.2 mrg uptr stack_top(); 87 1.2 mrg uptr stack_bottom(); 88 1.2 mrg uptr stack_size(); 89 1.2 mrg uptr tls_begin() { return tls_begin_; } 90 1.2 mrg uptr tls_end() { return tls_end_; } 91 1.2 mrg DTLS *dtls() { return dtls_; } 92 1.2 mrg u32 tid() { return context_->tid; } 93 1.2 mrg AsanThreadContext *context() { return context_; } 94 1.2 mrg void set_context(AsanThreadContext *context) { context_ = context; } 95 1.2 mrg 96 1.2 mrg struct StackFrameAccess { 97 1.2 mrg uptr offset; 98 1.2 mrg uptr frame_pc; 99 1.2 mrg const char *frame_descr; 100 1.2 mrg }; 101 1.2 mrg bool GetStackFrameAccessByAddr(uptr addr, StackFrameAccess *access); 102 1.2 mrg 103 1.2 mrg // Returns a pointer to the start of the stack variable's shadow memory. 104 1.2 mrg uptr GetStackVariableShadowStart(uptr addr); 105 1.2 mrg 106 1.2 mrg bool AddrIsInStack(uptr addr); 107 1.2 mrg 108 1.2 mrg void DeleteFakeStack(int tid) { 109 1.2 mrg if (!fake_stack_) return; 110 1.2 mrg FakeStack *t = fake_stack_; 111 1.2 mrg fake_stack_ = nullptr; 112 1.2 mrg SetTLSFakeStack(nullptr); 113 1.2 mrg t->Destroy(tid); 114 1.2 mrg } 115 1.1 mrg 116 1.2 mrg void StartSwitchFiber(FakeStack **fake_stack_save, uptr bottom, uptr size); 117 1.2 mrg void FinishSwitchFiber(FakeStack *fake_stack_save, uptr *bottom_old, 118 1.2 mrg uptr *size_old); 119 1.2 mrg 120 1.3 mrg FakeStack *get_fake_stack() { 121 1.3 mrg if (atomic_load(&stack_switching_, memory_order_relaxed)) 122 1.3 mrg return nullptr; 123 1.3 mrg if (reinterpret_cast<uptr>(fake_stack_) <= 1) 124 1.3 mrg return nullptr; 125 1.3 mrg return fake_stack_; 126 1.2 mrg } 127 1.1 mrg 128 1.3 mrg FakeStack *get_or_create_fake_stack() { 129 1.2 mrg if (atomic_load(&stack_switching_, memory_order_relaxed)) 130 1.2 mrg return nullptr; 131 1.3 mrg if (reinterpret_cast<uptr>(fake_stack_) <= 1) 132 1.2 mrg return AsyncSignalSafeLazyInitFakeStack(); 133 1.2 mrg return fake_stack_; 134 1.1 mrg } 135 1.1 mrg 136 1.2 mrg // True is this thread is currently unwinding stack (i.e. collecting a stack 137 1.2 mrg // trace). Used to prevent deadlocks on platforms where libc unwinder calls 138 1.2 mrg // malloc internally. See PR17116 for more details. 139 1.2 mrg bool isUnwinding() const { return unwinding_; } 140 1.2 mrg void setUnwinding(bool b) { unwinding_ = b; } 141 1.2 mrg 142 1.1 mrg AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; } 143 1.1 mrg AsanStats &stats() { return stats_; } 144 1.1 mrg 145 1.3 mrg void *extra_spill_area() { return &extra_spill_area_; } 146 1.3 mrg 147 1.4 mrg template <typename T> 148 1.4 mrg void GetStartData(T &data) const { 149 1.4 mrg GetStartData(&data, sizeof(data)); 150 1.4 mrg } 151 1.3 mrg 152 1.1 mrg private: 153 1.2 mrg // NOTE: There is no AsanThread constructor. It is allocated 154 1.2 mrg // via mmap() and *must* be valid in zero-initialized state. 155 1.2 mrg 156 1.4 mrg static AsanThread *Create(const void *start_data, uptr data_size, 157 1.4 mrg u32 parent_tid, StackTrace *stack, bool detached); 158 1.4 mrg 159 1.2 mrg void SetThreadStackAndTls(const InitOptions *options); 160 1.2 mrg 161 1.2 mrg void ClearShadowForThreadStackAndTLS(); 162 1.2 mrg FakeStack *AsyncSignalSafeLazyInitFakeStack(); 163 1.2 mrg 164 1.2 mrg struct StackBounds { 165 1.2 mrg uptr bottom; 166 1.2 mrg uptr top; 167 1.2 mrg }; 168 1.2 mrg StackBounds GetStackBounds() const; 169 1.2 mrg 170 1.4 mrg void GetStartData(void *out, uptr out_size) const; 171 1.4 mrg 172 1.2 mrg AsanThreadContext *context_; 173 1.1 mrg 174 1.2 mrg uptr stack_top_; 175 1.2 mrg uptr stack_bottom_; 176 1.2 mrg // these variables are used when the thread is about to switch stack 177 1.2 mrg uptr next_stack_top_; 178 1.2 mrg uptr next_stack_bottom_; 179 1.2 mrg // true if switching is in progress 180 1.2 mrg atomic_uint8_t stack_switching_; 181 1.2 mrg 182 1.2 mrg uptr tls_begin_; 183 1.2 mrg uptr tls_end_; 184 1.2 mrg DTLS *dtls_; 185 1.2 mrg 186 1.2 mrg FakeStack *fake_stack_; 187 1.1 mrg AsanThreadLocalMallocStorage malloc_storage_; 188 1.1 mrg AsanStats stats_; 189 1.2 mrg bool unwinding_; 190 1.3 mrg uptr extra_spill_area_; 191 1.4 mrg 192 1.4 mrg char start_data_[]; 193 1.1 mrg }; 194 1.1 mrg 195 1.4 mrg #if defined(_MSC_VER) && !defined(__clang__) 196 1.4 mrg # pragma warning(pop) 197 1.4 mrg #endif 198 1.4 mrg 199 1.2 mrg // Returns a single instance of registry. 200 1.2 mrg ThreadRegistry &asanThreadRegistry(); 201 1.4 mrg ThreadArgRetval &asanThreadArgRetval(); 202 1.2 mrg 203 1.2 mrg // Must be called under ThreadRegistryLock. 204 1.2 mrg AsanThreadContext *GetThreadContextByTidLocked(u32 tid); 205 1.2 mrg 206 1.2 mrg // Get the current thread. May return 0. 207 1.2 mrg AsanThread *GetCurrentThread(); 208 1.2 mrg void SetCurrentThread(AsanThread *t); 209 1.2 mrg u32 GetCurrentTidOrInvalid(); 210 1.2 mrg AsanThread *FindThreadByStackAddress(uptr addr); 211 1.2 mrg 212 1.2 mrg // Used to handle fork(). 213 1.2 mrg void EnsureMainThreadIDIsCorrect(); 214 1.2 mrg } // namespace __asan 215 1.1 mrg 216 1.2 mrg #endif // ASAN_THREAD_H 217