• 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_stack.h"
20 #include "asan_stats.h"
21 
22 namespace __asan {
23 
24 const size_t kMaxThreadStackSize = 16 * (1 << 20);  // 16M
25 
26 class AsanThread;
27 
28 // These objects are created for every thread and are never deleted,
29 // so we can find them by tid even if the thread is long dead.
30 class AsanThreadSummary {
31  public:
AsanThreadSummary(LinkerInitialized)32   explicit AsanThreadSummary(LinkerInitialized) { }  // for T0.
AsanThreadSummary(int parent_tid,AsanStackTrace * stack)33   AsanThreadSummary(int parent_tid, AsanStackTrace *stack)
34       : parent_tid_(parent_tid),
35         announced_(false) {
36     tid_ = -1;
37     if (stack) {
38       stack_ = *stack;
39     }
40     thread_ = 0;
41   }
Announce()42   void Announce() {
43     if (tid_ == 0) return;  // no need to announce the main thread.
44     if (!announced_) {
45       announced_ = true;
46       Printf("Thread T%d created by T%d here:\n", tid_, parent_tid_);
47       stack_.PrintStack();
48     }
49   }
tid()50   int tid() { return tid_; }
set_tid(int tid)51   void set_tid(int tid) { tid_ = tid; }
thread()52   AsanThread *thread() { return thread_; }
set_thread(AsanThread * thread)53   void set_thread(AsanThread *thread) { thread_ = thread; }
54   static void TSDDtor(void *tsd);
55 
56  private:
57   int tid_;
58   int parent_tid_;
59   bool announced_;
60   AsanStackTrace stack_;
61   AsanThread *thread_;
62 };
63 
64 // AsanThread are stored in TSD and destroyed when the thread dies.
65 class AsanThread {
66  public:
67   explicit AsanThread(LinkerInitialized);  // for T0.
68   static AsanThread *Create(int parent_tid, thread_callback_t start_routine,
69                             void *arg, AsanStackTrace *stack);
70   void Destroy();
71 
72   void Init();  // Should be called from the thread itself.
73   thread_return_t ThreadStart();
74 
stack_top()75   uintptr_t stack_top() { return stack_top_; }
stack_bottom()76   uintptr_t stack_bottom() { return stack_bottom_; }
stack_size()77   size_t stack_size() { return stack_top_ - stack_bottom_; }
tid()78   int tid() { return summary_->tid(); }
summary()79   AsanThreadSummary *summary() { return summary_; }
set_summary(AsanThreadSummary * summary)80   void set_summary(AsanThreadSummary *summary) { summary_ = summary; }
81 
82   const char *GetFrameNameByAddr(uintptr_t addr, uintptr_t *offset);
83 
AddrIsInStack(uintptr_t addr)84   bool AddrIsInStack(uintptr_t addr) {
85     return addr >= stack_bottom_ && addr < stack_top_;
86   }
87 
fake_stack()88   FakeStack &fake_stack() { return fake_stack_; }
malloc_storage()89   AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
stats()90   AsanStats &stats() { return stats_; }
91 
92   static const int kInvalidTid = -1;
93 
94  private:
95 
96   void SetThreadStackTopAndBottom();
97   void ClearShadowForThreadStack();
98   AsanThreadSummary *summary_;
99   thread_callback_t start_routine_;
100   void *arg_;
101   uintptr_t  stack_top_;
102   uintptr_t  stack_bottom_;
103 
104   FakeStack fake_stack_;
105   AsanThreadLocalMallocStorage malloc_storage_;
106   AsanStats stats_;
107 };
108 
109 }  // namespace __asan
110 
111 #endif  // ASAN_THREAD_H
112