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 22namespace __asan { 23 24const size_t kMaxThreadStackSize = 16 * (1 << 20); // 16M 25 26class 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. 30class AsanThreadSummary { 31 public: 32 explicit AsanThreadSummary(LinkerInitialized) { } // for T0. 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 } 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 } 50 int tid() { return tid_; } 51 void set_tid(int tid) { tid_ = tid; } 52 AsanThread *thread() { return 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. 65class 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 75 uintptr_t stack_top() { return stack_top_; } 76 uintptr_t stack_bottom() { return stack_bottom_; } 77 size_t stack_size() { return stack_top_ - stack_bottom_; } 78 int tid() { return summary_->tid(); } 79 AsanThreadSummary *summary() { return summary_; } 80 void set_summary(AsanThreadSummary *summary) { summary_ = summary; } 81 82 const char *GetFrameNameByAddr(uintptr_t addr, uintptr_t *offset); 83 84 bool AddrIsInStack(uintptr_t addr) { 85 return addr >= stack_bottom_ && addr < stack_top_; 86 } 87 88 FakeStack &fake_stack() { return fake_stack_; } 89 AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; } 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