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