1 //=-- lsan_posix.cpp -----------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===---------------------------------------------------------------------===// 8 // 9 // This file is a part of LeakSanitizer. 10 // Standalone LSan RTL code common to POSIX-like systems. 11 // 12 //===---------------------------------------------------------------------===// 13 14 #include "sanitizer_common/sanitizer_platform.h" 15 16 #if SANITIZER_POSIX 17 #include "lsan.h" 18 #include "lsan_allocator.h" 19 #include "sanitizer_common/sanitizer_stacktrace.h" 20 #include "sanitizer_common/sanitizer_tls_get_addr.h" 21 22 namespace __lsan { 23 24 ThreadContext::ThreadContext(int tid) : ThreadContextLsanBase(tid) {} 25 26 struct OnStartedArgs { 27 uptr stack_begin; 28 uptr stack_end; 29 uptr cache_begin; 30 uptr cache_end; 31 uptr tls_begin; 32 uptr tls_end; 33 DTLS *dtls; 34 }; 35 36 void ThreadContext::OnStarted(void *arg) { 37 auto args = reinterpret_cast<const OnStartedArgs *>(arg); 38 stack_begin_ = args->stack_begin; 39 stack_end_ = args->stack_end; 40 tls_begin_ = args->tls_begin; 41 tls_end_ = args->tls_end; 42 cache_begin_ = args->cache_begin; 43 cache_end_ = args->cache_end; 44 dtls_ = args->dtls; 45 } 46 47 void ThreadStart(u32 tid, tid_t os_id, ThreadType thread_type) { 48 OnStartedArgs args; 49 uptr stack_size = 0; 50 uptr tls_size = 0; 51 GetThreadStackAndTls(tid == 0, &args.stack_begin, &stack_size, 52 &args.tls_begin, &tls_size); 53 args.stack_end = args.stack_begin + stack_size; 54 args.tls_end = args.tls_begin + tls_size; 55 GetAllocatorCacheRange(&args.cache_begin, &args.cache_end); 56 args.dtls = DTLS_Get(); 57 ThreadContextLsanBase::ThreadStart(tid, os_id, thread_type, &args); 58 } 59 60 bool GetThreadRangesLocked(tid_t os_id, uptr *stack_begin, uptr *stack_end, 61 uptr *tls_begin, uptr *tls_end, uptr *cache_begin, 62 uptr *cache_end, DTLS **dtls) { 63 ThreadContext *context = static_cast<ThreadContext *>( 64 GetThreadRegistryLocked()->FindThreadContextByOsIDLocked(os_id)); 65 if (!context) 66 return false; 67 *stack_begin = context->stack_begin(); 68 *stack_end = context->stack_end(); 69 *tls_begin = context->tls_begin(); 70 *tls_end = context->tls_end(); 71 *cache_begin = context->cache_begin(); 72 *cache_end = context->cache_end(); 73 *dtls = context->dtls(); 74 return true; 75 } 76 77 void InitializeMainThread() { 78 u32 tid = ThreadCreate(0, 0, true); 79 CHECK_EQ(tid, 0); 80 ThreadStart(tid, GetTid()); 81 } 82 83 static void OnStackUnwind(const SignalContext &sig, const void *, 84 BufferedStackTrace *stack) { 85 stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context, 86 common_flags()->fast_unwind_on_fatal); 87 } 88 89 void LsanOnDeadlySignal(int signo, void *siginfo, void *context) { 90 HandleDeadlySignal(siginfo, context, GetCurrentThread(), &OnStackUnwind, 91 nullptr); 92 } 93 94 } // namespace __lsan 95 96 #endif // SANITIZER_POSIX 97