• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
25 namespace __asan {
26 
27 const u32 kInvalidTid = 0xffffff;  // Must fit into 24 bits.
28 const u32 kMaxNumberOfThreads = (1 << 22);  // 4M
29 
30 class 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.
34 class AsanThreadContext : public ThreadContextBase {
35  public:
AsanThreadContext(int tid)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.
51 COMPILER_CHECK(sizeof(AsanThreadContext) <= 4096);
52 
53 // AsanThread are stored in TSD and destroyed when the thread dies.
54 class 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 
stack_top()63   uptr stack_top() { return stack_top_; }
stack_bottom()64   uptr stack_bottom() { return stack_bottom_; }
stack_size()65   uptr stack_size() { return stack_top_ - stack_bottom_; }
tls_begin()66   uptr tls_begin() { return tls_begin_; }
tls_end()67   uptr tls_end() { return tls_end_; }
tid()68   u32 tid() { return context_->tid; }
context()69   AsanThreadContext *context() { return context_; }
set_context(AsanThreadContext * context)70   void set_context(AsanThreadContext *context) { context_ = context; }
71 
72   const char *GetFrameNameByAddr(uptr addr, uptr *offset, uptr *frame_pc);
73 
AddrIsInStack(uptr addr)74   bool AddrIsInStack(uptr addr) {
75     return addr >= stack_bottom_ && addr < stack_top_;
76   }
77 
LazyInitFakeStack()78   void LazyInitFakeStack() {
79     if (fake_stack_) return;
80     fake_stack_ = (FakeStack*)MmapOrDie(sizeof(FakeStack), "FakeStack");
81     fake_stack_->Init(stack_size());
82   }
DeleteFakeStack()83   void DeleteFakeStack() {
84     if (!fake_stack_) return;
85     fake_stack_->Cleanup();
86     UnmapOrDie(fake_stack_, sizeof(FakeStack));
87   }
fake_stack()88   FakeStack *fake_stack() { return fake_stack_; }
89 
malloc_storage()90   AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
stats()91   AsanStats &stats() { return stats_; }
92 
93  private:
AsanThread()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 
110 struct CreateThreadContextArgs {
111   AsanThread *thread;
112   StackTrace *stack;
113 };
114 
115 // Returns a single instance of registry.
116 ThreadRegistry &asanThreadRegistry();
117 
118 // Must be called under ThreadRegistryLock.
119 AsanThreadContext *GetThreadContextByTidLocked(u32 tid);
120 
121 // Get the current thread. May return 0.
122 AsanThread *GetCurrentThread();
123 void SetCurrentThread(AsanThread *t);
124 u32 GetCurrentTidOrInvalid();
125 AsanThread *FindThreadByStackAddress(uptr addr);
126 
127 // Used to handle fork().
128 void EnsureMainThreadIDIsCorrect();
129 }  // namespace __asan
130 
131 #endif  // ASAN_THREAD_H
132