asan_thread.h revision 50f3daa00d3da0a80c8798a3e977705e96ec106f
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#include "sanitizer_common/sanitizer_thread_registry.h" 23 24namespace __asan { 25 26const u32 kInvalidTid = 0xffffff; // Must fit into 24 bits. 27const u32 kMaxNumberOfThreads = (1 << 22); // 4M 28 29class AsanThread; 30 31// These objects are created for every thread and are never deleted, 32// so we can find them by tid even if the thread is long dead. 33class AsanThreadContext : public ThreadContextBase { 34 public: 35 explicit AsanThreadContext(int tid) 36 : ThreadContextBase(tid), 37 announced(false), 38 thread(0) { 39 internal_memset(&stack, 0, sizeof(stack)); 40 } 41 bool announced; 42 StackTrace stack; 43 AsanThread *thread; 44 45 void OnCreated(void *arg); 46 void OnFinished(); 47}; 48 49// AsanThreadContext objects are never freed, so we need many of them. 50COMPILER_CHECK(sizeof(AsanThreadContext) <= 4096); 51 52// AsanThread are stored in TSD and destroyed when the thread dies. 53class AsanThread { 54 public: 55 static AsanThread *Create(thread_callback_t start_routine, void *arg); 56 static void TSDDtor(void *tsd); 57 void Destroy(); 58 59 void Init(); // Should be called from the thread itself. 60 thread_return_t ThreadStart(uptr os_id); 61 62 uptr stack_top() { return stack_top_; } 63 uptr stack_bottom() { return stack_bottom_; } 64 uptr stack_size() { return stack_top_ - stack_bottom_; } 65 u32 tid() { return context_->tid; } 66 AsanThreadContext *context() { return context_; } 67 void set_context(AsanThreadContext *context) { context_ = context; } 68 69 const char *GetFrameNameByAddr(uptr addr, uptr *offset, uptr *frame_pc); 70 71 bool AddrIsInStack(uptr addr) { 72 return addr >= stack_bottom_ && addr < stack_top_; 73 } 74 75 FakeStack &fake_stack() { return fake_stack_; } 76 AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; } 77 AsanStats &stats() { return stats_; } 78 79 private: 80 AsanThread() {} 81 void SetThreadStackTopAndBottom(); 82 void ClearShadowForThreadStack(); 83 AsanThreadContext *context_; 84 thread_callback_t start_routine_; 85 void *arg_; 86 uptr stack_top_; 87 uptr stack_bottom_; 88 89 FakeStack fake_stack_; 90 AsanThreadLocalMallocStorage malloc_storage_; 91 AsanStats stats_; 92}; 93 94struct CreateThreadContextArgs { 95 AsanThread *thread; 96 StackTrace *stack; 97}; 98 99// Returns a single instance of registry. 100ThreadRegistry &asanThreadRegistry(); 101 102// Must be called under ThreadRegistryLock. 103AsanThreadContext *GetThreadContextByTidLocked(u32 tid); 104 105// Get the current thread. May return 0. 106AsanThread *GetCurrentThread(); 107void SetCurrentThread(AsanThread *t); 108u32 GetCurrentTidOrInvalid(); 109AsanThread *FindThreadByStackAddress(uptr addr); 110 111} // namespace __asan 112 113#endif // ASAN_THREAD_H 114