asan_thread.h revision 244384d1a8a518c0b1ceaa5809333a91db1104b6
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  u32 tid() { return context_->tid; }
67  AsanThreadContext *context() { return context_; }
68  void set_context(AsanThreadContext *context) { context_ = context; }
69
70  const char *GetFrameNameByAddr(uptr addr, uptr *offset, uptr *frame_pc);
71
72  bool AddrIsInStack(uptr addr) {
73    return addr >= stack_bottom_ && addr < stack_top_;
74  }
75
76  FakeStack &fake_stack() { return fake_stack_; }
77  AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
78  AsanStats &stats() { return stats_; }
79
80 private:
81  AsanThread() {}
82  void SetThreadStackTopAndBottom();
83  void ClearShadowForThreadStack();
84  AsanThreadContext *context_;
85  thread_callback_t start_routine_;
86  void *arg_;
87  uptr  stack_top_;
88  uptr  stack_bottom_;
89
90  FakeStack fake_stack_;
91  AsanThreadLocalMallocStorage malloc_storage_;
92  AsanStats stats_;
93};
94
95struct CreateThreadContextArgs {
96  AsanThread *thread;
97  StackTrace *stack;
98};
99
100// Returns a single instance of registry.
101ThreadRegistry &asanThreadRegistry();
102
103// Must be called under ThreadRegistryLock.
104AsanThreadContext *GetThreadContextByTidLocked(u32 tid);
105
106// Get the current thread. May return 0.
107AsanThread *GetCurrentThread();
108void SetCurrentThread(AsanThread *t);
109u32 GetCurrentTidOrInvalid();
110AsanThread *FindThreadByStackAddress(uptr addr);
111
112}  // namespace __asan
113
114#endif  // ASAN_THREAD_H
115