1238901Sandrew//===-- asan_thread.cc ----------------------------------------------------===// 2229109Sed// 3229109Sed// The LLVM Compiler Infrastructure 4229109Sed// 5229109Sed// This file is distributed under the University of Illinois Open Source 6229109Sed// License. See LICENSE.TXT for details. 7229109Sed// 8229109Sed//===----------------------------------------------------------------------===// 9229109Sed// 10229109Sed// This file is a part of AddressSanitizer, an address sanity checker. 11229109Sed// 12229109Sed// Thread-related code. 13229109Sed//===----------------------------------------------------------------------===// 14229109Sed#include "asan_allocator.h" 15229109Sed#include "asan_interceptors.h" 16251034Sed#include "asan_poisoning.h" 17238901Sandrew#include "asan_stack.h" 18229109Sed#include "asan_thread.h" 19229109Sed#include "asan_mapping.h" 20238901Sandrew#include "sanitizer_common/sanitizer_common.h" 21251034Sed#include "sanitizer_common/sanitizer_placement_new.h" 22274201Sdim#include "sanitizer_common/sanitizer_stackdepot.h" 23276789Sdim#include "sanitizer_common/sanitizer_tls_get_addr.h" 24251034Sed#include "lsan/lsan_common.h" 25229109Sed 26229109Sednamespace __asan { 27229109Sed 28251034Sed// AsanThreadContext implementation. 29229109Sed 30276789Sdimstruct CreateThreadContextArgs { 31276789Sdim AsanThread *thread; 32276789Sdim StackTrace *stack; 33276789Sdim}; 34276789Sdim 35251034Sedvoid AsanThreadContext::OnCreated(void *arg) { 36251034Sed CreateThreadContextArgs *args = static_cast<CreateThreadContextArgs*>(arg); 37274201Sdim if (args->stack) 38276789Sdim stack_id = StackDepotPut(*args->stack); 39251034Sed thread = args->thread; 40251034Sed thread->set_context(this); 41251034Sed} 42251034Sed 43251034Sedvoid AsanThreadContext::OnFinished() { 44251034Sed // Drop the link to the AsanThread object. 45296417Sdim thread = nullptr; 46251034Sed} 47251034Sed 48274201Sdim// MIPS requires aligned address 49274201Sdimstatic ALIGNED(16) char thread_registry_placeholder[sizeof(ThreadRegistry)]; 50251034Sedstatic ThreadRegistry *asan_thread_registry; 51251034Sed 52274201Sdimstatic BlockingMutex mu_for_thread_context(LINKER_INITIALIZED); 53274201Sdimstatic LowLevelAllocator allocator_for_thread_context; 54274201Sdim 55251034Sedstatic ThreadContextBase *GetAsanThreadContext(u32 tid) { 56274201Sdim BlockingMutexLock lock(&mu_for_thread_context); 57274201Sdim return new(allocator_for_thread_context) AsanThreadContext(tid); 58251034Sed} 59251034Sed 60251034SedThreadRegistry &asanThreadRegistry() { 61251034Sed static bool initialized; 62251034Sed // Don't worry about thread_safety - this should be called when there is 63251034Sed // a single thread. 64251034Sed if (!initialized) { 65251034Sed // Never reuse ASan threads: we store pointer to AsanThreadContext 66251034Sed // in TSD and can't reliably tell when no more TSD destructors will 67251034Sed // be called. It would be wrong to reuse AsanThreadContext for another 68251034Sed // thread before all TSD destructors will be called for it. 69251034Sed asan_thread_registry = new(thread_registry_placeholder) ThreadRegistry( 70251034Sed GetAsanThreadContext, kMaxNumberOfThreads, kMaxNumberOfThreads); 71251034Sed initialized = true; 72251034Sed } 73251034Sed return *asan_thread_registry; 74251034Sed} 75251034Sed 76251034SedAsanThreadContext *GetThreadContextByTidLocked(u32 tid) { 77251034Sed return static_cast<AsanThreadContext *>( 78251034Sed asanThreadRegistry().GetThreadLocked(tid)); 79251034Sed} 80251034Sed 81251034Sed// AsanThread implementation. 82251034Sed 83276789SdimAsanThread *AsanThread::Create(thread_callback_t start_routine, void *arg, 84276789Sdim u32 parent_tid, StackTrace *stack, 85276789Sdim bool detached) { 86245614Sandrew uptr PageSize = GetPageSizeCached(); 87245614Sandrew uptr size = RoundUpTo(sizeof(AsanThread), PageSize); 88276789Sdim AsanThread *thread = (AsanThread*)MmapOrDie(size, __func__); 89238901Sandrew thread->start_routine_ = start_routine; 90238901Sandrew thread->arg_ = arg; 91276789Sdim CreateThreadContextArgs args = { thread, stack }; 92276789Sdim asanThreadRegistry().CreateThread(*reinterpret_cast<uptr *>(thread), detached, 93276789Sdim parent_tid, &args); 94238901Sandrew 95238901Sandrew return thread; 96229109Sed} 97229109Sed 98251034Sedvoid AsanThread::TSDDtor(void *tsd) { 99251034Sed AsanThreadContext *context = (AsanThreadContext*)tsd; 100276789Sdim VReport(1, "T%d TSDDtor\n", context->tid); 101251034Sed if (context->thread) 102251034Sed context->thread->Destroy(); 103238901Sandrew} 104238901Sandrew 105238901Sandrewvoid AsanThread::Destroy() { 106276789Sdim int tid = this->tid(); 107276789Sdim VReport(1, "T%d exited\n", tid); 108238901Sandrew 109274201Sdim malloc_storage().CommitBack(); 110276789Sdim if (common_flags()->use_sigaltstack) UnsetAlternateSignalStack(); 111276789Sdim asanThreadRegistry().FinishThread(tid); 112274201Sdim FlushToDeadThreadStats(&stats_); 113229109Sed // We also clear the shadow on thread destruction because 114229109Sed // some code may still be executing in later TSD destructors 115229109Sed // and we don't want it to have any poisoned stack. 116274201Sdim ClearShadowForThreadStackAndTLS(); 117276789Sdim DeleteFakeStack(tid); 118245614Sandrew uptr size = RoundUpTo(sizeof(AsanThread), GetPageSizeCached()); 119238901Sandrew UnmapOrDie(this, size); 120276789Sdim DTLS_Destroy(); 121229109Sed} 122229109Sed 123274201Sdim// We want to create the FakeStack lazyly on the first use, but not eralier 124274201Sdim// than the stack size is known and the procedure has to be async-signal safe. 125274201SdimFakeStack *AsanThread::AsyncSignalSafeLazyInitFakeStack() { 126274201Sdim uptr stack_size = this->stack_size(); 127274201Sdim if (stack_size == 0) // stack_size is not yet available, don't use FakeStack. 128296417Sdim return nullptr; 129274201Sdim uptr old_val = 0; 130274201Sdim // fake_stack_ has 3 states: 131274201Sdim // 0 -- not initialized 132274201Sdim // 1 -- being initialized 133274201Sdim // ptr -- initialized 134274201Sdim // This CAS checks if the state was 0 and if so changes it to state 1, 135276789Sdim // if that was successful, it initializes the pointer. 136274201Sdim if (atomic_compare_exchange_strong( 137274201Sdim reinterpret_cast<atomic_uintptr_t *>(&fake_stack_), &old_val, 1UL, 138274201Sdim memory_order_relaxed)) { 139274201Sdim uptr stack_size_log = Log2(RoundUpToPowerOfTwo(stack_size)); 140276789Sdim CHECK_LE(flags()->min_uar_stack_size_log, flags()->max_uar_stack_size_log); 141276789Sdim stack_size_log = 142276789Sdim Min(stack_size_log, static_cast<uptr>(flags()->max_uar_stack_size_log)); 143276789Sdim stack_size_log = 144276789Sdim Max(stack_size_log, static_cast<uptr>(flags()->min_uar_stack_size_log)); 145274201Sdim fake_stack_ = FakeStack::Create(stack_size_log); 146274201Sdim SetTLSFakeStack(fake_stack_); 147274201Sdim return fake_stack_; 148274201Sdim } 149296417Sdim return nullptr; 150274201Sdim} 151274201Sdim 152229109Sedvoid AsanThread::Init() { 153296417Sdim fake_stack_ = nullptr; // Will be initialized lazily if needed. 154276789Sdim CHECK_EQ(this->stack_size(), 0U); 155274201Sdim SetThreadStackAndTls(); 156276789Sdim CHECK_GT(this->stack_size(), 0U); 157229109Sed CHECK(AddrIsInMem(stack_bottom_)); 158245614Sandrew CHECK(AddrIsInMem(stack_top_ - 1)); 159274201Sdim ClearShadowForThreadStackAndTLS(); 160276789Sdim int local = 0; 161276789Sdim VReport(1, "T%d: stack [%p,%p) size 0x%zx; local=%p\n", tid(), 162276789Sdim (void *)stack_bottom_, (void *)stack_top_, stack_top_ - stack_bottom_, 163276789Sdim &local); 164229109Sed} 165229109Sed 166276789Sdimthread_return_t AsanThread::ThreadStart( 167276789Sdim uptr os_id, atomic_uintptr_t *signal_thread_is_registered) { 168229109Sed Init(); 169296417Sdim asanThreadRegistry().StartThread(tid(), os_id, nullptr); 170276789Sdim if (signal_thread_is_registered) 171276789Sdim atomic_store(signal_thread_is_registered, 1, memory_order_release); 172229109Sed 173276789Sdim if (common_flags()->use_sigaltstack) SetAlternateSignalStack(); 174276789Sdim 175229109Sed if (!start_routine_) { 176238901Sandrew // start_routine_ == 0 if we're on the main thread or on one of the 177229109Sed // OS X libdispatch worker threads. But nobody is supposed to call 178229109Sed // ThreadStart() for the worker threads. 179251034Sed CHECK_EQ(tid(), 0); 180229109Sed return 0; 181229109Sed } 182229109Sed 183238901Sandrew thread_return_t res = start_routine_(arg_); 184229109Sed 185274201Sdim // On POSIX systems we defer this to the TSD destructor. LSan will consider 186274201Sdim // the thread's memory as non-live from the moment we call Destroy(), even 187274201Sdim // though that memory might contain pointers to heap objects which will be 188274201Sdim // cleaned up by a user-defined TSD destructor. Thus, calling Destroy() before 189274201Sdim // the TSD destructors have run might cause false positives in LSan. 190274201Sdim if (!SANITIZER_POSIX) 191274201Sdim this->Destroy(); 192229109Sed 193229109Sed return res; 194229109Sed} 195229109Sed 196274201Sdimvoid AsanThread::SetThreadStackAndTls() { 197274201Sdim uptr tls_size = 0; 198274201Sdim GetThreadStackAndTls(tid() == 0, &stack_bottom_, &stack_size_, &tls_begin_, 199274201Sdim &tls_size); 200274201Sdim stack_top_ = stack_bottom_ + stack_size_; 201274201Sdim tls_end_ = tls_begin_ + tls_size; 202274201Sdim 203238901Sandrew int local; 204238901Sandrew CHECK(AddrIsInStack((uptr)&local)); 205238901Sandrew} 206238901Sandrew 207274201Sdimvoid AsanThread::ClearShadowForThreadStackAndTLS() { 208238901Sandrew PoisonShadow(stack_bottom_, stack_top_ - stack_bottom_, 0); 209274201Sdim if (tls_begin_ != tls_end_) 210274201Sdim PoisonShadow(tls_begin_, tls_end_ - tls_begin_, 0); 211238901Sandrew} 212238901Sandrew 213276789Sdimbool AsanThread::GetStackFrameAccessByAddr(uptr addr, 214276789Sdim StackFrameAccess *access) { 215238901Sandrew uptr bottom = 0; 216229109Sed if (AddrIsInStack(addr)) { 217229109Sed bottom = stack_bottom(); 218274201Sdim } else if (has_fake_stack()) { 219274201Sdim bottom = fake_stack()->AddrIsInFakeStack(addr); 220229109Sed CHECK(bottom); 221276789Sdim access->offset = addr - bottom; 222276789Sdim access->frame_pc = ((uptr*)bottom)[2]; 223276789Sdim access->frame_descr = (const char *)((uptr*)bottom)[1]; 224276789Sdim return true; 225229109Sed } 226245614Sandrew uptr aligned_addr = addr & ~(SANITIZER_WORDSIZE/8 - 1); // align addr. 227238901Sandrew u8 *shadow_ptr = (u8*)MemToShadow(aligned_addr); 228238901Sandrew u8 *shadow_bottom = (u8*)MemToShadow(bottom); 229238901Sandrew 230238901Sandrew while (shadow_ptr >= shadow_bottom && 231245614Sandrew *shadow_ptr != kAsanStackLeftRedzoneMagic) { 232238901Sandrew shadow_ptr--; 233229109Sed } 234229109Sed 235238901Sandrew while (shadow_ptr >= shadow_bottom && 236245614Sandrew *shadow_ptr == kAsanStackLeftRedzoneMagic) { 237238901Sandrew shadow_ptr--; 238238901Sandrew } 239229109Sed 240238901Sandrew if (shadow_ptr < shadow_bottom) { 241276789Sdim return false; 242229109Sed } 243229109Sed 244238901Sandrew uptr* ptr = (uptr*)SHADOW_TO_MEM((uptr)(shadow_ptr + 1)); 245245614Sandrew CHECK(ptr[0] == kCurrentStackFrameMagic); 246276789Sdim access->offset = addr - (uptr)ptr; 247276789Sdim access->frame_pc = ptr[2]; 248276789Sdim access->frame_descr = (const char*)ptr[1]; 249276789Sdim return true; 250229109Sed} 251229109Sed 252251034Sedstatic bool ThreadStackContainsAddress(ThreadContextBase *tctx_base, 253251034Sed void *addr) { 254251034Sed AsanThreadContext *tctx = static_cast<AsanThreadContext*>(tctx_base); 255251034Sed AsanThread *t = tctx->thread; 256274201Sdim if (!t) return false; 257274201Sdim if (t->AddrIsInStack((uptr)addr)) return true; 258274201Sdim if (t->has_fake_stack() && t->fake_stack()->AddrIsInFakeStack((uptr)addr)) 259274201Sdim return true; 260274201Sdim return false; 261251034Sed} 262251034Sed 263251034SedAsanThread *GetCurrentThread() { 264274201Sdim AsanThreadContext *context = 265274201Sdim reinterpret_cast<AsanThreadContext *>(AsanTSDGet()); 266251034Sed if (!context) { 267251034Sed if (SANITIZER_ANDROID) { 268251034Sed // On Android, libc constructor is called _after_ asan_init, and cleans up 269251034Sed // TSD. Try to figure out if this is still the main thread by the stack 270251034Sed // address. We are not entirely sure that we have correct main thread 271251034Sed // limits, so only do this magic on Android, and only if the found thread 272251034Sed // is the main thread. 273251034Sed AsanThreadContext *tctx = GetThreadContextByTidLocked(0); 274251034Sed if (ThreadStackContainsAddress(tctx, &context)) { 275251034Sed SetCurrentThread(tctx->thread); 276251034Sed return tctx->thread; 277251034Sed } 278251034Sed } 279296417Sdim return nullptr; 280251034Sed } 281251034Sed return context->thread; 282251034Sed} 283251034Sed 284251034Sedvoid SetCurrentThread(AsanThread *t) { 285251034Sed CHECK(t->context()); 286276789Sdim VReport(2, "SetCurrentThread: %p for thread %p\n", t->context(), 287276789Sdim (void *)GetThreadSelf()); 288251034Sed // Make sure we do not reset the current AsanThread. 289251034Sed CHECK_EQ(0, AsanTSDGet()); 290251034Sed AsanTSDSet(t->context()); 291251034Sed CHECK_EQ(t->context(), AsanTSDGet()); 292251034Sed} 293251034Sed 294251034Sedu32 GetCurrentTidOrInvalid() { 295251034Sed AsanThread *t = GetCurrentThread(); 296251034Sed return t ? t->tid() : kInvalidTid; 297251034Sed} 298251034Sed 299251034SedAsanThread *FindThreadByStackAddress(uptr addr) { 300251034Sed asanThreadRegistry().CheckLocked(); 301251034Sed AsanThreadContext *tctx = static_cast<AsanThreadContext *>( 302251034Sed asanThreadRegistry().FindThreadContextLocked(ThreadStackContainsAddress, 303251034Sed (void *)addr)); 304296417Sdim return tctx ? tctx->thread : nullptr; 305251034Sed} 306274201Sdim 307274201Sdimvoid EnsureMainThreadIDIsCorrect() { 308274201Sdim AsanThreadContext *context = 309274201Sdim reinterpret_cast<AsanThreadContext *>(AsanTSDGet()); 310274201Sdim if (context && (context->tid == 0)) 311274201Sdim context->os_id = GetTid(); 312274201Sdim} 313274201Sdim 314274201Sdim__asan::AsanThread *GetAsanThreadByOsIDLocked(uptr os_id) { 315274201Sdim __asan::AsanThreadContext *context = static_cast<__asan::AsanThreadContext *>( 316274201Sdim __asan::asanThreadRegistry().FindThreadContextByOsIDLocked(os_id)); 317296417Sdim if (!context) return nullptr; 318274201Sdim return context->thread; 319274201Sdim} 320296417Sdim} // namespace __asan 321251034Sed 322251034Sed// --- Implementation of LSan-specific functions --- {{{1 323251034Sednamespace __lsan { 324251034Sedbool GetThreadRangesLocked(uptr os_id, uptr *stack_begin, uptr *stack_end, 325251034Sed uptr *tls_begin, uptr *tls_end, 326251034Sed uptr *cache_begin, uptr *cache_end) { 327274201Sdim __asan::AsanThread *t = __asan::GetAsanThreadByOsIDLocked(os_id); 328274201Sdim if (!t) return false; 329274201Sdim *stack_begin = t->stack_bottom(); 330274201Sdim *stack_end = t->stack_top(); 331274201Sdim *tls_begin = t->tls_begin(); 332274201Sdim *tls_end = t->tls_end(); 333274201Sdim // ASan doesn't keep allocator caches in TLS, so these are unused. 334274201Sdim *cache_begin = 0; 335274201Sdim *cache_end = 0; 336274201Sdim return true; 337251034Sed} 338251034Sed 339274201Sdimvoid ForEachExtraStackRange(uptr os_id, RangeIteratorCallback callback, 340274201Sdim void *arg) { 341274201Sdim __asan::AsanThread *t = __asan::GetAsanThreadByOsIDLocked(os_id); 342274201Sdim if (t && t->has_fake_stack()) 343274201Sdim t->fake_stack()->ForEachFakeFrame(callback, arg); 344274201Sdim} 345274201Sdim 346251034Sedvoid LockThreadRegistry() { 347251034Sed __asan::asanThreadRegistry().Lock(); 348251034Sed} 349251034Sed 350251034Sedvoid UnlockThreadRegistry() { 351251034Sed __asan::asanThreadRegistry().Unlock(); 352251034Sed} 353274201Sdim 354274201Sdimvoid EnsureMainThreadIDIsCorrect() { 355274201Sdim __asan::EnsureMainThreadIDIsCorrect(); 356274201Sdim} 357296417Sdim} // namespace __lsan 358