asan_thread.h revision 229109
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 tid, int parent_tid, AsanStackTrace *stack) 34 : tid_(tid), 35 parent_tid_(parent_tid), 36 announced_(false) { 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 AsanThread *thread() { return thread_; } 52 void set_thread(AsanThread *thread) { thread_ = thread; } 53 private: 54 int tid_; 55 int parent_tid_; 56 bool announced_; 57 AsanStackTrace stack_; 58 AsanThread *thread_; 59}; 60 61// AsanThread are stored in TSD and destroyed when the thread dies. 62class AsanThread { 63 public: 64 explicit AsanThread(LinkerInitialized); // for T0. 65 AsanThread(int parent_tid, void *(*start_routine) (void *), 66 void *arg, AsanStackTrace *stack); 67 ~AsanThread(); 68 69 void Init(); // Should be called from the thread itself. 70 void *ThreadStart(); 71 72 uintptr_t stack_top() { return stack_top_; } 73 uintptr_t stack_bottom() { return stack_bottom_; } 74 size_t stack_size() { return stack_top_ - stack_bottom_; } 75 int tid() { return summary_->tid(); } 76 AsanThreadSummary *summary() { return summary_; } 77 void set_summary(AsanThreadSummary *summary) { summary_ = summary; } 78 79 const char *GetFrameNameByAddr(uintptr_t addr, uintptr_t *offset); 80 81 bool AddrIsInStack(uintptr_t addr) { 82 return addr >= stack_bottom_ && addr < stack_top_; 83 } 84 85 FakeStack &fake_stack() { return fake_stack_; } 86 AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; } 87 AsanStats &stats() { return stats_; } 88 89 static const int kInvalidTid = -1; 90 91 private: 92 93 void SetThreadStackTopAndBottom(); 94 void ClearShadowForThreadStack(); 95 AsanThreadSummary *summary_; 96 void *(*start_routine_) (void *param); 97 void *arg_; 98 uintptr_t stack_top_; 99 uintptr_t stack_bottom_; 100 101 FakeStack fake_stack_; 102 AsanThreadLocalMallocStorage malloc_storage_; 103 AsanStats stats_; 104}; 105 106} // namespace __asan 107 108#endif // ASAN_THREAD_H 109