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