1e5f5895bda30f374b0b51412fd4d837fa59aed66Alexey Samsonov//===-- asan_thread.cc ----------------------------------------------------===// 21e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 31e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The LLVM Compiler Infrastructure 41e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 51e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is distributed under the University of Illinois Open Source 61e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// License. See LICENSE.TXT for details. 71e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 81e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===// 91e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker. 111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Thread-related code. 131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===// 141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_allocator.h" 151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_interceptors.h" 167e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov#include "asan_poisoning.h" 1755cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov#include "asan_stack.h" 181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_thread.h" 191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_mapping.h" 20e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov#include "sanitizer_common/sanitizer_common.h" 21def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov#include "sanitizer_common/sanitizer_placement_new.h" 226d95869fa900da9ddd68e15e2aa065854cfa176bKostya Serebryany#include "sanitizer_common/sanitizer_stackdepot.h" 232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "sanitizer_common/sanitizer_tls_get_addr.h" 24f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev#include "lsan/lsan_common.h" 251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan { 271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 28def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov// AsanThreadContext implementation. 291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 30def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonovvoid AsanThreadContext::OnCreated(void *arg) { 31def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov CreateThreadContextArgs *args = static_cast<CreateThreadContextArgs*>(arg); 326d95869fa900da9ddd68e15e2aa065854cfa176bKostya Serebryany if (args->stack) 336d95869fa900da9ddd68e15e2aa065854cfa176bKostya Serebryany stack_id = StackDepotPut(args->stack->trace, args->stack->size); 34def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov thread = args->thread; 35def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov thread->set_context(this); 36def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov} 37def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov 38def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonovvoid AsanThreadContext::OnFinished() { 39def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov // Drop the link to the AsanThread object. 40def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov thread = 0; 41def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov} 42def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov 4340527a579131210fcfa2373620a0c2200800e7c4Kostya Serebryany// MIPS requires aligned address 447c9ffde46a475d6dd739e977b547c27ac5968976Timur Iskhodzhanovstatic ALIGNED(16) char thread_registry_placeholder[sizeof(ThreadRegistry)]; 45def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonovstatic ThreadRegistry *asan_thread_registry; 46def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov 471fe68b87dcd9be36b5b4d35e74cc5b0666500ec4Kostya Serebryanystatic BlockingMutex mu_for_thread_context(LINKER_INITIALIZED); 481fe68b87dcd9be36b5b4d35e74cc5b0666500ec4Kostya Serebryanystatic LowLevelAllocator allocator_for_thread_context; 491fe68b87dcd9be36b5b4d35e74cc5b0666500ec4Kostya Serebryany 50def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonovstatic ThreadContextBase *GetAsanThreadContext(u32 tid) { 511fe68b87dcd9be36b5b4d35e74cc5b0666500ec4Kostya Serebryany BlockingMutexLock lock(&mu_for_thread_context); 5253177247698bfba075f2d5b255a447fc3ced6976Peter Collingbourne return new(allocator_for_thread_context) AsanThreadContext(tid); 53def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov} 54def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov 55def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey SamsonovThreadRegistry &asanThreadRegistry() { 56def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov static bool initialized; 57def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov // Don't worry about thread_safety - this should be called when there is 58def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov // a single thread. 59def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov if (!initialized) { 60def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov // Never reuse ASan threads: we store pointer to AsanThreadContext 61def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov // in TSD and can't reliably tell when no more TSD destructors will 62def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov // be called. It would be wrong to reuse AsanThreadContext for another 63def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov // thread before all TSD destructors will be called for it. 64def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov asan_thread_registry = new(thread_registry_placeholder) ThreadRegistry( 65def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov GetAsanThreadContext, kMaxNumberOfThreads, kMaxNumberOfThreads); 66def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov initialized = true; 67def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov } 68def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov return *asan_thread_registry; 69def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov} 70def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov 71def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey SamsonovAsanThreadContext *GetThreadContextByTidLocked(u32 tid) { 72def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov return static_cast<AsanThreadContext *>( 73def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov asanThreadRegistry().GetThreadLocked(tid)); 74def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov} 75def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov 76def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov// AsanThread implementation. 77def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov 78def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey SamsonovAsanThread *AsanThread::Create(thread_callback_t start_routine, 79def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov void *arg) { 80f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany uptr PageSize = GetPageSizeCached(); 81f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany uptr size = RoundUpTo(sizeof(AsanThread), PageSize); 822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines AsanThread *thread = (AsanThread*)MmapOrDie(size, __func__); 8355cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov thread->start_routine_ = start_routine; 8455cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov thread->arg_ = arg; 8555cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov 8655cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov return thread; 871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 89def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonovvoid AsanThread::TSDDtor(void *tsd) { 90def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov AsanThreadContext *context = (AsanThreadContext*)tsd; 912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "T%d TSDDtor\n", context->tid); 92def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov if (context->thread) 93def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov context->thread->Destroy(); 94f58f998066db0231e521169d2f50af439ceecb49Kostya Serebryany} 95f58f998066db0231e521169d2f50af439ceecb49Kostya Serebryany 96a6b52264e1231bfc4ee9a2d9a4f32678c97295f0Kostya Serebryanyvoid AsanThread::Destroy() { 972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines int tid = this->tid(); 982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "T%d exited\n", tid); 99f58f998066db0231e521169d2f50af439ceecb49Kostya Serebryany 100ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany malloc_storage().CommitBack(); 1012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (common_flags()->use_sigaltstack) UnsetAlternateSignalStack(); 1022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines asanThreadRegistry().FinishThread(tid); 103717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov FlushToDeadThreadStats(&stats_); 1041e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // We also clear the shadow on thread destruction because 1051e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // some code may still be executing in later TSD destructors 1061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // and we don't want it to have any poisoned stack. 10712d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev ClearShadowForThreadStackAndTLS(); 1082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines DeleteFakeStack(tid); 109f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany uptr size = RoundUpTo(sizeof(AsanThread), GetPageSizeCached()); 110a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov UnmapOrDie(this, size); 1112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines DTLS_Destroy(); 1121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 1131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 114c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany// We want to create the FakeStack lazyly on the first use, but not eralier 115c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany// than the stack size is known and the procedure has to be async-signal safe. 116c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya SerebryanyFakeStack *AsanThread::AsyncSignalSafeLazyInitFakeStack() { 117c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany uptr stack_size = this->stack_size(); 118c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany if (stack_size == 0) // stack_size is not yet available, don't use FakeStack. 119c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany return 0; 120c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany uptr old_val = 0; 121c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany // fake_stack_ has 3 states: 122c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany // 0 -- not initialized 123c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany // 1 -- being initialized 124c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany // ptr -- initialized 125c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany // This CAS checks if the state was 0 and if so changes it to state 1, 1262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // if that was successful, it initializes the pointer. 127c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany if (atomic_compare_exchange_strong( 128c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany reinterpret_cast<atomic_uintptr_t *>(&fake_stack_), &old_val, 1UL, 1299433af375c7813486be91d2ac76f5072ee41818dKostya Serebryany memory_order_relaxed)) { 130230e52f4e91b53f05ce19dbbf11047f4a0113483Kostya Serebryany uptr stack_size_log = Log2(RoundUpToPowerOfTwo(stack_size)); 1312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines CHECK_LE(flags()->min_uar_stack_size_log, flags()->max_uar_stack_size_log); 1322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stack_size_log = 1332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Min(stack_size_log, static_cast<uptr>(flags()->max_uar_stack_size_log)); 1342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines stack_size_log = 1352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Max(stack_size_log, static_cast<uptr>(flags()->min_uar_stack_size_log)); 136230e52f4e91b53f05ce19dbbf11047f4a0113483Kostya Serebryany fake_stack_ = FakeStack::Create(stack_size_log); 1379433af375c7813486be91d2ac76f5072ee41818dKostya Serebryany SetTLSFakeStack(fake_stack_); 1389433af375c7813486be91d2ac76f5072ee41818dKostya Serebryany return fake_stack_; 1399433af375c7813486be91d2ac76f5072ee41818dKostya Serebryany } 140c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany return 0; 141c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany} 142c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany 14369eca73ac96688c8bfe1f23ee006af29c7858c40Kostya Serebryanyvoid AsanThread::Init() { 1445d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines fake_stack_ = 0; // Will be initialized lazily if needed. 1455d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines CHECK_EQ(this->stack_size(), 0U); 14612d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev SetThreadStackAndTls(); 1475d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines CHECK_GT(this->stack_size(), 0U); 14855cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov CHECK(AddrIsInMem(stack_bottom_)); 149541cfb10f5daa17e48eb42365a74233cd551c545Kostya Serebryany CHECK(AddrIsInMem(stack_top_ - 1)); 15012d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev ClearShadowForThreadStackAndTLS(); 1512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines int local = 0; 1522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "T%d: stack [%p,%p) size 0x%zx; local=%p\n", tid(), 1532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines (void *)stack_bottom_, (void *)stack_top_, stack_top_ - stack_bottom_, 1542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines &local); 15575b19ebf25af204cf209d108997272822241d6daAlexander Potapenko AsanPlatformThreadInit(); 15669eca73ac96688c8bfe1f23ee006af29c7858c40Kostya Serebryany} 15769eca73ac96688c8bfe1f23ee006af29c7858c40Kostya Serebryany 158def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonovthread_return_t AsanThread::ThreadStart(uptr os_id) { 15969eca73ac96688c8bfe1f23ee006af29c7858c40Kostya Serebryany Init(); 160def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov asanThreadRegistry().StartThread(tid(), os_id, 0); 1612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (common_flags()->use_sigaltstack) SetAlternateSignalStack(); 1621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (!start_routine_) { 1643f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany // start_routine_ == 0 if we're on the main thread or on one of the 1651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // OS X libdispatch worker threads. But nobody is supposed to call 1661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // ThreadStart() for the worker threads. 167a27bdf70ca24202dce21cf7c1a387aeaa400d889Kostya Serebryany CHECK_EQ(tid(), 0); 1681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return 0; 1691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 1701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 171600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov thread_return_t res = start_routine_(arg_); 1721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 173e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev // On POSIX systems we defer this to the TSD destructor. LSan will consider 174e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev // the thread's memory as non-live from the moment we call Destroy(), even 175e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev // though that memory might contain pointers to heap objects which will be 176e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev // cleaned up by a user-defined TSD destructor. Thus, calling Destroy() before 177e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev // the TSD destructors have run might cause false positives in LSan. 178e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev if (!SANITIZER_POSIX) 179e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev this->Destroy(); 180af3441580555ceed092170232cd5f2cc180f19f4Kostya Serebryany 1811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return res; 1821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 1831e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 18412d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveevvoid AsanThread::SetThreadStackAndTls() { 185621770a196153ee61b338d34bafd1170c1899444Kostya Serebryany uptr tls_size = 0; 186621770a196153ee61b338d34bafd1170c1899444Kostya Serebryany GetThreadStackAndTls(tid() == 0, &stack_bottom_, &stack_size_, &tls_begin_, 18712d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev &tls_size); 188621770a196153ee61b338d34bafd1170c1899444Kostya Serebryany stack_top_ = stack_bottom_ + stack_size_; 18912d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev tls_end_ = tls_begin_ + tls_size; 19012d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev 191e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov int local; 192e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov CHECK(AddrIsInStack((uptr)&local)); 193e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov} 194e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov 19512d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveevvoid AsanThread::ClearShadowForThreadStackAndTLS() { 19655cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov PoisonShadow(stack_bottom_, stack_top_ - stack_bottom_, 0); 19712d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev if (tls_begin_ != tls_end_) 19812d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev PoisonShadow(tls_begin_, tls_end_ - tls_begin_, 0); 19955cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov} 20055cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov 20150f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryanyconst char *AsanThread::GetFrameNameByAddr(uptr addr, uptr *offset, 20250f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany uptr *frame_pc) { 2033f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr bottom = 0; 2041e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (AddrIsInStack(addr)) { 2051e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany bottom = stack_bottom(); 206dcf98bf49d68533c7aebadbf6c4467afdd486c99Kostya Serebryany } else if (has_fake_stack()) { 2077a0bba457ee05ced3adf37a0c0790d0ed23a5446Kostya Serebryany bottom = fake_stack()->AddrIsInFakeStack(addr); 2081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany CHECK(bottom); 209e406c8c47570659287e619e23479f9fb6640299eAlexander Potapenko *offset = addr - bottom; 21050f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany *frame_pc = ((uptr*)bottom)[2]; 211e406c8c47570659287e619e23479f9fb6640299eAlexander Potapenko return (const char *)((uptr*)bottom)[1]; 2121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 2135af39e50366f1aacbebc284f572f08ad1ad07357Kostya Serebryany uptr aligned_addr = addr & ~(SANITIZER_WORDSIZE/8 - 1); // align addr. 214ee3925515e4c7966f3ef489f687aa7e5692806a9Kostya Serebryany u8 *shadow_ptr = (u8*)MemToShadow(aligned_addr); 215ee3925515e4c7966f3ef489f687aa7e5692806a9Kostya Serebryany u8 *shadow_bottom = (u8*)MemToShadow(bottom); 2163972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov 2173972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov while (shadow_ptr >= shadow_bottom && 218e406c8c47570659287e619e23479f9fb6640299eAlexander Potapenko *shadow_ptr != kAsanStackLeftRedzoneMagic) { 2193972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov shadow_ptr--; 2203972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov } 2213972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov 2223972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov while (shadow_ptr >= shadow_bottom && 223e406c8c47570659287e619e23479f9fb6640299eAlexander Potapenko *shadow_ptr == kAsanStackLeftRedzoneMagic) { 2243972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov shadow_ptr--; 2251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 2263972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov 2273972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov if (shadow_ptr < shadow_bottom) { 228e406c8c47570659287e619e23479f9fb6640299eAlexander Potapenko *offset = 0; 229e406c8c47570659287e619e23479f9fb6640299eAlexander Potapenko return "UNKNOWN"; 2303972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov } 2313972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov 2323f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr* ptr = (uptr*)SHADOW_TO_MEM((uptr)(shadow_ptr + 1)); 233e406c8c47570659287e619e23479f9fb6640299eAlexander Potapenko CHECK(ptr[0] == kCurrentStackFrameMagic); 2343f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany *offset = addr - (uptr)ptr; 23550f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany *frame_pc = ptr[2]; 2363972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov return (const char*)ptr[1]; 2371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 239def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonovstatic bool ThreadStackContainsAddress(ThreadContextBase *tctx_base, 240def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov void *addr) { 241def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov AsanThreadContext *tctx = static_cast<AsanThreadContext*>(tctx_base); 242def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov AsanThread *t = tctx->thread; 2437a0bba457ee05ced3adf37a0c0790d0ed23a5446Kostya Serebryany if (!t) return false; 2447a0bba457ee05ced3adf37a0c0790d0ed23a5446Kostya Serebryany if (t->AddrIsInStack((uptr)addr)) return true; 245b39a604ff9d68ba7400197fca341771878443a69Kostya Serebryany if (t->has_fake_stack() && t->fake_stack()->AddrIsInFakeStack((uptr)addr)) 2467a0bba457ee05ced3adf37a0c0790d0ed23a5446Kostya Serebryany return true; 2477a0bba457ee05ced3adf37a0c0790d0ed23a5446Kostya Serebryany return false; 248def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov} 249def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov 25089c1384464848c1ad041becf8b97936fa10de21bAlexey SamsonovAsanThread *GetCurrentThread() { 251c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev AsanThreadContext *context = 252c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev reinterpret_cast<AsanThreadContext *>(AsanTSDGet()); 253def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov if (!context) { 254def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov if (SANITIZER_ANDROID) { 255def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov // On Android, libc constructor is called _after_ asan_init, and cleans up 256def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov // TSD. Try to figure out if this is still the main thread by the stack 257def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov // address. We are not entirely sure that we have correct main thread 258195369bb7f59896487c4542716ca9c5d53975e78Dmitry Vyukov // limits, so only do this magic on Android, and only if the found thread 259195369bb7f59896487c4542716ca9c5d53975e78Dmitry Vyukov // is the main thread. 260def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov AsanThreadContext *tctx = GetThreadContextByTidLocked(0); 261def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov if (ThreadStackContainsAddress(tctx, &context)) { 262def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov SetCurrentThread(tctx->thread); 263def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov return tctx->thread; 264def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov } 26589c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov } 26689c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov return 0; 26789c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov } 268def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov return context->thread; 26989c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov} 27089c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov 27189c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonovvoid SetCurrentThread(AsanThread *t) { 272def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov CHECK(t->context()); 2732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(2, "SetCurrentThread: %p for thread %p\n", t->context(), 2742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines (void *)GetThreadSelf()); 27589c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov // Make sure we do not reset the current AsanThread. 276def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov CHECK_EQ(0, AsanTSDGet()); 277def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov AsanTSDSet(t->context()); 278def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov CHECK_EQ(t->context(), AsanTSDGet()); 27989c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov} 28089c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov 28189c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonovu32 GetCurrentTidOrInvalid() { 28289c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov AsanThread *t = GetCurrentThread(); 28389c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov return t ? t->tid() : kInvalidTid; 28489c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov} 28589c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov 286def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey SamsonovAsanThread *FindThreadByStackAddress(uptr addr) { 287def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov asanThreadRegistry().CheckLocked(); 288def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov AsanThreadContext *tctx = static_cast<AsanThreadContext *>( 289def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov asanThreadRegistry().FindThreadContextLocked(ThreadStackContainsAddress, 290def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov (void *)addr)); 291def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov return tctx ? tctx->thread : 0; 292def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov} 293c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev 294c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveevvoid EnsureMainThreadIDIsCorrect() { 295c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev AsanThreadContext *context = 296c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev reinterpret_cast<AsanThreadContext *>(AsanTSDGet()); 297c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev if (context && (context->tid == 0)) 298c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev context->os_id = GetTid(); 299c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev} 300c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev 301c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev__asan::AsanThread *GetAsanThreadByOsIDLocked(uptr os_id) { 302c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev __asan::AsanThreadContext *context = static_cast<__asan::AsanThreadContext *>( 303c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev __asan::asanThreadRegistry().FindThreadContextByOsIDLocked(os_id)); 304c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev if (!context) return 0; 305c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev return context->thread; 306c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev} 3071e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} // namespace __asan 308f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev 309f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev// --- Implementation of LSan-specific functions --- {{{1 310f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveevnamespace __lsan { 311f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveevbool GetThreadRangesLocked(uptr os_id, uptr *stack_begin, uptr *stack_end, 312f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev uptr *tls_begin, uptr *tls_end, 313f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev uptr *cache_begin, uptr *cache_end) { 314c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev __asan::AsanThread *t = __asan::GetAsanThreadByOsIDLocked(os_id); 31512d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev if (!t) return false; 31612d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev *stack_begin = t->stack_bottom(); 31712d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev *stack_end = t->stack_top(); 31812d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev *tls_begin = t->tls_begin(); 31912d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev *tls_end = t->tls_end(); 32012d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev // ASan doesn't keep allocator caches in TLS, so these are unused. 32112d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev *cache_begin = 0; 32212d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev *cache_end = 0; 32312d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev return true; 324f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev} 325f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev 326c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveevvoid ForEachExtraStackRange(uptr os_id, RangeIteratorCallback callback, 327c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev void *arg) { 328c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev __asan::AsanThread *t = __asan::GetAsanThreadByOsIDLocked(os_id); 329c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev if (t && t->has_fake_stack()) 330c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev t->fake_stack()->ForEachFakeFrame(callback, arg); 331c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev} 332c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev 333f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveevvoid LockThreadRegistry() { 334f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev __asan::asanThreadRegistry().Lock(); 335f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev} 336f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev 337f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveevvoid UnlockThreadRegistry() { 338f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev __asan::asanThreadRegistry().Unlock(); 339f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev} 340c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev 341c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveevvoid EnsureMainThreadIDIsCorrect() { 342c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev __asan::EnsureMainThreadIDIsCorrect(); 343c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev} 344f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev} // namespace __lsan 345