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