asan_thread.h revision 7a0bba457ee05ced3adf37a0c0790d0ed23a5446
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_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        thread(0) {
40    internal_memset(&stack, 0, sizeof(stack));
41  }
42  bool announced;
43  StackTrace stack;
44  AsanThread *thread;
45
46  void OnCreated(void *arg);
47  void OnFinished();
48};
49
50// AsanThreadContext objects are never freed, so we need many of them.
51COMPILER_CHECK(sizeof(AsanThreadContext) <= 4096);
52
53// AsanThread are stored in TSD and destroyed when the thread dies.
54class AsanThread {
55 public:
56  static AsanThread *Create(thread_callback_t start_routine, void *arg);
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
63  uptr stack_top() { return stack_top_; }
64  uptr stack_bottom() { return stack_bottom_; }
65  uptr stack_size() { return stack_top_ - stack_bottom_; }
66  uptr tls_begin() { return tls_begin_; }
67  uptr tls_end() { return tls_end_; }
68  u32 tid() { return context_->tid; }
69  AsanThreadContext *context() { return context_; }
70  void set_context(AsanThreadContext *context) { context_ = context; }
71
72  const char *GetFrameNameByAddr(uptr addr, uptr *offset, uptr *frame_pc);
73
74  bool AddrIsInStack(uptr addr) {
75    return addr >= stack_bottom_ && addr < stack_top_;
76  }
77
78  void LazyInitFakeStack() {
79    if (fake_stack_) return;
80    fake_stack_ = (FakeStack*)MmapOrDie(sizeof(FakeStack), "FakeStack");
81    fake_stack_->Init(stack_size());
82  }
83  void DeleteFakeStack() {
84    if (!fake_stack_) return;
85    fake_stack_->Cleanup();
86    UnmapOrDie(fake_stack_, sizeof(FakeStack));
87  }
88  FakeStack *fake_stack() { return fake_stack_; }
89
90  AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
91  AsanStats &stats() { return stats_; }
92
93 private:
94  AsanThread() {}
95  void SetThreadStackAndTls();
96  void ClearShadowForThreadStackAndTLS();
97  AsanThreadContext *context_;
98  thread_callback_t start_routine_;
99  void *arg_;
100  uptr  stack_top_;
101  uptr  stack_bottom_;
102  uptr tls_begin_;
103  uptr tls_end_;
104
105  FakeStack *fake_stack_;
106  AsanThreadLocalMallocStorage malloc_storage_;
107  AsanStats stats_;
108};
109
110struct CreateThreadContextArgs {
111  AsanThread *thread;
112  StackTrace *stack;
113};
114
115// Returns a single instance of registry.
116ThreadRegistry &asanThreadRegistry();
117
118// Must be called under ThreadRegistryLock.
119AsanThreadContext *GetThreadContextByTidLocked(u32 tid);
120
121// Get the current thread. May return 0.
122AsanThread *GetCurrentThread();
123void SetCurrentThread(AsanThread *t);
124u32 GetCurrentTidOrInvalid();
125AsanThread *FindThreadByStackAddress(uptr addr);
126
127}  // namespace __asan
128
129#endif  // ASAN_THREAD_H
130