asan_thread.h revision 276851
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),
38        announced(false),
39        destructor_iterations(kPthreadDestructorIterations),
40        stack_id(0),
41        thread(0) {
42  }
43  bool announced;
44  u8 destructor_iterations;
45  u32 stack_id;
46  AsanThread *thread;
47
48  void OnCreated(void *arg);
49  void OnFinished();
50};
51
52// AsanThreadContext objects are never freed, so we need many of them.
53COMPILER_CHECK(sizeof(AsanThreadContext) <= 256);
54
55// AsanThread are stored in TSD and destroyed when the thread dies.
56class AsanThread {
57 public:
58  static AsanThread *Create(thread_callback_t start_routine, void *arg,
59                            u32 parent_tid, StackTrace *stack, bool detached);
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                              atomic_uintptr_t *signal_thread_is_registered);
66
67  uptr stack_top() { return stack_top_; }
68  uptr stack_bottom() { return stack_bottom_; }
69  uptr stack_size() { return stack_size_; }
70  uptr tls_begin() { return tls_begin_; }
71  uptr tls_end() { return tls_end_; }
72  u32 tid() { return context_->tid; }
73  AsanThreadContext *context() { return context_; }
74  void set_context(AsanThreadContext *context) { context_ = context; }
75
76  struct StackFrameAccess {
77    uptr offset;
78    uptr frame_pc;
79    const char *frame_descr;
80  };
81  bool GetStackFrameAccessByAddr(uptr addr, StackFrameAccess *access);
82
83  bool AddrIsInStack(uptr addr) {
84    return addr >= stack_bottom_ && addr < stack_top_;
85  }
86
87  void DeleteFakeStack(int tid) {
88    if (!fake_stack_) return;
89    FakeStack *t = fake_stack_;
90    fake_stack_ = 0;
91    SetTLSFakeStack(0);
92    t->Destroy(tid);
93  }
94
95  bool has_fake_stack() {
96    return (reinterpret_cast<uptr>(fake_stack_) > 1);
97  }
98
99  FakeStack *fake_stack() {
100    if (!__asan_option_detect_stack_use_after_return)
101      return 0;
102    if (!has_fake_stack())
103      return AsyncSignalSafeLazyInitFakeStack();
104    return fake_stack_;
105  }
106
107  // True is this thread is currently unwinding stack (i.e. collecting a stack
108  // trace). Used to prevent deadlocks on platforms where libc unwinder calls
109  // malloc internally. See PR17116 for more details.
110  bool isUnwinding() const { return unwinding_; }
111  void setUnwinding(bool b) { unwinding_ = b; }
112
113  // True if we are in a deadly signal handler.
114  bool isInDeadlySignal() const { return in_deadly_signal_; }
115  void setInDeadlySignal(bool b) { in_deadly_signal_ = b; }
116
117  AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
118  AsanStats &stats() { return stats_; }
119
120 private:
121  // NOTE: There is no AsanThread constructor. It is allocated
122  // via mmap() and *must* be valid in zero-initialized state.
123  void SetThreadStackAndTls();
124  void ClearShadowForThreadStackAndTLS();
125  FakeStack *AsyncSignalSafeLazyInitFakeStack();
126
127  AsanThreadContext *context_;
128  thread_callback_t start_routine_;
129  void *arg_;
130  uptr stack_top_;
131  uptr stack_bottom_;
132  // stack_size_ == stack_top_ - stack_bottom_;
133  // It needs to be set in a async-signal-safe manner.
134  uptr stack_size_;
135  uptr tls_begin_;
136  uptr tls_end_;
137
138  FakeStack *fake_stack_;
139  AsanThreadLocalMallocStorage malloc_storage_;
140  AsanStats stats_;
141  bool unwinding_;
142  bool in_deadly_signal_;
143};
144
145// ScopedUnwinding is a scope for stacktracing member of a context
146class ScopedUnwinding {
147 public:
148  explicit ScopedUnwinding(AsanThread *t) : thread(t) {
149    t->setUnwinding(true);
150  }
151  ~ScopedUnwinding() { thread->setUnwinding(false); }
152
153 private:
154  AsanThread *thread;
155};
156
157// ScopedDeadlySignal is a scope for handling deadly signals.
158class ScopedDeadlySignal {
159 public:
160  explicit ScopedDeadlySignal(AsanThread *t) : thread(t) {
161    if (thread) thread->setInDeadlySignal(true);
162  }
163  ~ScopedDeadlySignal() {
164    if (thread) thread->setInDeadlySignal(false);
165  }
166
167 private:
168  AsanThread *thread;
169};
170
171// Returns a single instance of registry.
172ThreadRegistry &asanThreadRegistry();
173
174// Must be called under ThreadRegistryLock.
175AsanThreadContext *GetThreadContextByTidLocked(u32 tid);
176
177// Get the current thread. May return 0.
178AsanThread *GetCurrentThread();
179void SetCurrentThread(AsanThread *t);
180u32 GetCurrentTidOrInvalid();
181AsanThread *FindThreadByStackAddress(uptr addr);
182
183// Used to handle fork().
184void EnsureMainThreadIDIsCorrect();
185}  // namespace __asan
186
187#endif  // ASAN_THREAD_H
188