asan_thread.h revision 245614
1204917Sdes//===-- asan_thread.h -------------------------------------------*- C++ -*-===// 276259Sgreen// 376259Sgreen// The LLVM Compiler Infrastructure 476259Sgreen// 576259Sgreen// This file is distributed under the University of Illinois Open Source 676259Sgreen// License. See LICENSE.TXT for details. 776259Sgreen// 876259Sgreen//===----------------------------------------------------------------------===// 976259Sgreen// 1076259Sgreen// This file is a part of AddressSanitizer, an address sanity checker. 1176259Sgreen// 1276259Sgreen// ASan-private header for asan_thread.cc. 1376259Sgreen//===----------------------------------------------------------------------===// 1476259Sgreen#ifndef ASAN_THREAD_H 1576259Sgreen#define ASAN_THREAD_H 1676259Sgreen 1776259Sgreen#include "asan_allocator.h" 1876259Sgreen#include "asan_internal.h" 1976259Sgreen#include "asan_stack.h" 2076259Sgreen#include "asan_stats.h" 2176259Sgreen#include "sanitizer_common/sanitizer_libc.h" 2276259Sgreen 2376259Sgreennamespace __asan { 2476259Sgreen 2576259Sgreenconst u32 kInvalidTid = 0xffffff; // Must fit into 24 bits. 2676259Sgreen 2776259Sgreenclass AsanThread; 2876259Sgreen 2976259Sgreen// These objects are created for every thread and are never deleted, 3076259Sgreen// so we can find them by tid even if the thread is long dead. 3176259Sgreenclass AsanThreadSummary { 3276259Sgreen public: 3376259Sgreen explicit AsanThreadSummary(LinkerInitialized) { } // for T0. 3476259Sgreen void Init(u32 parent_tid, StackTrace *stack) { 3576259Sgreen parent_tid_ = parent_tid; 3676259Sgreen announced_ = false; 3776259Sgreen tid_ = kInvalidTid; 3876259Sgreen if (stack) { 3976259Sgreen internal_memcpy(&stack_, stack, sizeof(*stack)); 40162852Sdes } 41162852Sdes thread_ = 0; 42162852Sdes name_[0] = 0; 43162852Sdes } 44162852Sdes u32 tid() { return tid_; } 45137015Sdes void set_tid(u32 tid) { tid_ = tid; } 4676259Sgreen u32 parent_tid() { return parent_tid_; } 4776259Sgreen bool announced() { return announced_; } 4876259Sgreen void set_announced(bool announced) { announced_ = announced; } 4976259Sgreen StackTrace *stack() { return &stack_; } 50181111Sdes AsanThread *thread() { return thread_; } 5176259Sgreen void set_thread(AsanThread *thread) { thread_ = thread; } 5276259Sgreen static void TSDDtor(void *tsd); 53181111Sdes void set_name(const char *name) { 5476259Sgreen internal_strncpy(name_, name, sizeof(name_) - 1); 5576259Sgreen } 5676259Sgreen const char *name() { return name_; } 57204917Sdes 5876259Sgreen private: 5976259Sgreen u32 tid_; 6076259Sgreen u32 parent_tid_; 61204917Sdes bool announced_; 62204917Sdes StackTrace stack_; 63204917Sdes AsanThread *thread_; 64204917Sdes char name_[128]; 6576259Sgreen}; 6676259Sgreen 6776259Sgreen// AsanThreadSummary objects are never freed, so we need many of them. 6876259SgreenCOMPILER_CHECK(sizeof(AsanThreadSummary) <= 4094); 69204917Sdes 7076259Sgreen// AsanThread are stored in TSD and destroyed when the thread dies. 7176259Sgreenclass AsanThread { 7276259Sgreen public: 7376259Sgreen explicit AsanThread(LinkerInitialized); // for T0. 74204917Sdes static AsanThread *Create(u32 parent_tid, thread_callback_t start_routine, 75204917Sdes void *arg, StackTrace *stack); 7676259Sgreen void Destroy(); 7776259Sgreen 7876259Sgreen void Init(); // Should be called from the thread itself. 7976259Sgreen thread_return_t ThreadStart(); 8076259Sgreen 81124208Sdes uptr stack_top() { return stack_top_; } 82124208Sdes uptr stack_bottom() { return stack_bottom_; } 83124208Sdes uptr stack_size() { return stack_top_ - stack_bottom_; } 8476259Sgreen u32 tid() { return summary_->tid(); } 8576259Sgreen AsanThreadSummary *summary() { return summary_; } 8676259Sgreen void set_summary(AsanThreadSummary *summary) { summary_ = summary; } 8776259Sgreen 8876259Sgreen const char *GetFrameNameByAddr(uptr addr, uptr *offset); 8976259Sgreen 9076259Sgreen bool AddrIsInStack(uptr addr) { 91204917Sdes return addr >= stack_bottom_ && addr < stack_top_; 92204917Sdes } 93204917Sdes 94204917Sdes FakeStack &fake_stack() { return fake_stack_; } 9576259Sgreen AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; } 9676259Sgreen AsanStats &stats() { return stats_; } 97 98 private: 99 void SetThreadStackTopAndBottom(); 100 void ClearShadowForThreadStack(); 101 AsanThreadSummary *summary_; 102 thread_callback_t start_routine_; 103 void *arg_; 104 uptr stack_top_; 105 uptr stack_bottom_; 106 107 FakeStack fake_stack_; 108 AsanThreadLocalMallocStorage malloc_storage_; 109 AsanStats stats_; 110}; 111 112} // namespace __asan 113 114#endif // ASAN_THREAD_H 115