asan_thread.h revision 6d95869fa900da9ddd68e15e2aa065854cfa176b
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_common.h"
23#include "sanitizer_common/sanitizer_libc.h"
24#include "sanitizer_common/sanitizer_thread_registry.h"
25
26namespace __asan {
27
28const u32 kInvalidTid = 0xffffff;  // Must fit into 24 bits.
29const u32 kMaxNumberOfThreads = (1 << 22);  // 4M
30
31class AsanThread;
32
33// These objects are created for every thread and are never deleted,
34// so we can find them by tid even if the thread is long dead.
35class AsanThreadContext : public ThreadContextBase {
36 public:
37  explicit AsanThreadContext(int tid)
38      : ThreadContextBase(tid),
39        announced(false),
40        destructor_iterations(kPthreadDestructorIterations),
41        stack_id(0),
42        thread(0) {
43  }
44  bool announced;
45  u8 destructor_iterations;
46  u32 stack_id;
47  AsanThread *thread;
48
49  void OnCreated(void *arg);
50  void OnFinished();
51};
52
53// AsanThreadContext objects are never freed, so we need many of them.
54COMPILER_CHECK(sizeof(AsanThreadContext) <= 256);
55
56// AsanThread are stored in TSD and destroyed when the thread dies.
57class AsanThread {
58 public:
59  static AsanThread *Create(thread_callback_t start_routine, void *arg);
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
66  uptr stack_top() { return stack_top_; }
67  uptr stack_bottom() { return stack_bottom_; }
68  uptr stack_size() { return stack_size_; }
69  uptr tls_begin() { return tls_begin_; }
70  uptr tls_end() { return tls_end_; }
71  u32 tid() { return context_->tid; }
72  AsanThreadContext *context() { return context_; }
73  void set_context(AsanThreadContext *context) { context_ = context; }
74
75  const char *GetFrameNameByAddr(uptr addr, uptr *offset, uptr *frame_pc);
76
77  bool AddrIsInStack(uptr addr) {
78    return addr >= stack_bottom_ && addr < stack_top_;
79  }
80
81  void DeleteFakeStack() {
82    if (!fake_stack_) return;
83    FakeStack *t = fake_stack_;
84    fake_stack_ = 0;
85    SetTLSFakeStack(0);
86    t->Destroy();
87  }
88
89  bool has_fake_stack() {
90    return (reinterpret_cast<uptr>(fake_stack_) > 1);
91  }
92
93  FakeStack *fake_stack() {
94    if (!__asan_option_detect_stack_use_after_return)
95      return 0;
96    if (!has_fake_stack())
97      return AsyncSignalSafeLazyInitFakeStack();
98    return fake_stack_;
99  }
100
101  // True is this thread is currently unwinding stack (i.e. collecting a stack
102  // trace). Used to prevent deadlocks on platforms where libc unwinder calls
103  // malloc internally. See PR17116 for more details.
104  bool isUnwinding() const { return unwinding; }
105  void setUnwinding(bool b) { unwinding = b; }
106
107  AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
108  AsanStats &stats() { return stats_; }
109
110 private:
111  AsanThread() : unwinding(false) {}
112  void SetThreadStackAndTls();
113  void ClearShadowForThreadStackAndTLS();
114  FakeStack *AsyncSignalSafeLazyInitFakeStack();
115
116  AsanThreadContext *context_;
117  thread_callback_t start_routine_;
118  void *arg_;
119  uptr  stack_top_;
120  uptr  stack_bottom_;
121  // stack_size_ == stack_top_ - stack_bottom_;
122  // It needs to be set in a async-signal-safe manner.
123  uptr  stack_size_;
124  uptr tls_begin_;
125  uptr tls_end_;
126
127  FakeStack *fake_stack_;
128  AsanThreadLocalMallocStorage malloc_storage_;
129  AsanStats stats_;
130  bool unwinding;
131};
132
133// ScopedUnwinding is a scope for stacktracing member of a context
134class ScopedUnwinding {
135 public:
136  explicit ScopedUnwinding(AsanThread *t) : thread(t) {
137    t->setUnwinding(true);
138  }
139  ~ScopedUnwinding() { thread->setUnwinding(false); }
140
141 private:
142  AsanThread *thread;
143};
144
145struct CreateThreadContextArgs {
146  AsanThread *thread;
147  StackTrace *stack;
148};
149
150// Returns a single instance of registry.
151ThreadRegistry &asanThreadRegistry();
152
153// Must be called under ThreadRegistryLock.
154AsanThreadContext *GetThreadContextByTidLocked(u32 tid);
155
156// Get the current thread. May return 0.
157AsanThread *GetCurrentThread();
158void SetCurrentThread(AsanThread *t);
159u32 GetCurrentTidOrInvalid();
160AsanThread *FindThreadByStackAddress(uptr addr);
161
162// Used to handle fork().
163void EnsureMainThreadIDIsCorrect();
164}  // namespace __asan
165
166#endif  // ASAN_THREAD_H
167