asan_thread.h revision 50f3daa00d3da0a80c8798a3e977705e96ec106f
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_stack.h"
20#include "asan_stats.h"
21#include "sanitizer_common/sanitizer_libc.h"
22#include "sanitizer_common/sanitizer_thread_registry.h"
23
24namespace __asan {
25
26const u32 kInvalidTid = 0xffffff;  // Must fit into 24 bits.
27const u32 kMaxNumberOfThreads = (1 << 22);  // 4M
28
29class AsanThread;
30
31// These objects are created for every thread and are never deleted,
32// so we can find them by tid even if the thread is long dead.
33class AsanThreadContext : public ThreadContextBase {
34 public:
35  explicit AsanThreadContext(int tid)
36      : ThreadContextBase(tid),
37        announced(false),
38        thread(0) {
39    internal_memset(&stack, 0, sizeof(stack));
40  }
41  bool announced;
42  StackTrace stack;
43  AsanThread *thread;
44
45  void OnCreated(void *arg);
46  void OnFinished();
47};
48
49// AsanThreadContext objects are never freed, so we need many of them.
50COMPILER_CHECK(sizeof(AsanThreadContext) <= 4096);
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  static void TSDDtor(void *tsd);
57  void Destroy();
58
59  void Init();  // Should be called from the thread itself.
60  thread_return_t ThreadStart(uptr os_id);
61
62  uptr stack_top() { return stack_top_; }
63  uptr stack_bottom() { return stack_bottom_; }
64  uptr stack_size() { return stack_top_ - stack_bottom_; }
65  u32 tid() { return context_->tid; }
66  AsanThreadContext *context() { return context_; }
67  void set_context(AsanThreadContext *context) { context_ = context; }
68
69  const char *GetFrameNameByAddr(uptr addr, uptr *offset, uptr *frame_pc);
70
71  bool AddrIsInStack(uptr addr) {
72    return addr >= stack_bottom_ && addr < stack_top_;
73  }
74
75  FakeStack &fake_stack() { return fake_stack_; }
76  AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
77  AsanStats &stats() { return stats_; }
78
79 private:
80  AsanThread() {}
81  void SetThreadStackTopAndBottom();
82  void ClearShadowForThreadStack();
83  AsanThreadContext *context_;
84  thread_callback_t start_routine_;
85  void *arg_;
86  uptr  stack_top_;
87  uptr  stack_bottom_;
88
89  FakeStack fake_stack_;
90  AsanThreadLocalMallocStorage malloc_storage_;
91  AsanStats stats_;
92};
93
94struct CreateThreadContextArgs {
95  AsanThread *thread;
96  StackTrace *stack;
97};
98
99// Returns a single instance of registry.
100ThreadRegistry &asanThreadRegistry();
101
102// Must be called under ThreadRegistryLock.
103AsanThreadContext *GetThreadContextByTidLocked(u32 tid);
104
105// Get the current thread. May return 0.
106AsanThread *GetCurrentThread();
107void SetCurrentThread(AsanThread *t);
108u32 GetCurrentTidOrInvalid();
109AsanThread *FindThreadByStackAddress(uptr addr);
110
111}  // namespace __asan
112
113#endif  // ASAN_THREAD_H
114