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