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