1*68d75effSDimitry Andric //=-- lsan.cpp ------------------------------------------------------------===// 2*68d75effSDimitry Andric // 3*68d75effSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*68d75effSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*68d75effSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*68d75effSDimitry Andric // 7*68d75effSDimitry Andric //===----------------------------------------------------------------------===// 8*68d75effSDimitry Andric // 9*68d75effSDimitry Andric // This file is a part of LeakSanitizer. 10*68d75effSDimitry Andric // Standalone LSan RTL. 11*68d75effSDimitry Andric // 12*68d75effSDimitry Andric //===----------------------------------------------------------------------===// 13*68d75effSDimitry Andric 14*68d75effSDimitry Andric #include "lsan.h" 15*68d75effSDimitry Andric 16*68d75effSDimitry Andric #include "sanitizer_common/sanitizer_flags.h" 17*68d75effSDimitry Andric #include "sanitizer_common/sanitizer_flag_parser.h" 18*68d75effSDimitry Andric #include "sanitizer_common/sanitizer_stacktrace.h" 19*68d75effSDimitry Andric #include "lsan_allocator.h" 20*68d75effSDimitry Andric #include "lsan_common.h" 21*68d75effSDimitry Andric #include "lsan_thread.h" 22*68d75effSDimitry Andric 23*68d75effSDimitry Andric bool lsan_inited; 24*68d75effSDimitry Andric bool lsan_init_is_running; 25*68d75effSDimitry Andric 26*68d75effSDimitry Andric namespace __lsan { 27*68d75effSDimitry Andric 28*68d75effSDimitry Andric ///// Interface to the common LSan module. ///// 29*68d75effSDimitry Andric bool WordIsPoisoned(uptr addr) { 30*68d75effSDimitry Andric return false; 31*68d75effSDimitry Andric } 32*68d75effSDimitry Andric 33*68d75effSDimitry Andric } // namespace __lsan 34*68d75effSDimitry Andric 35*68d75effSDimitry Andric void __sanitizer::BufferedStackTrace::UnwindImpl( 36*68d75effSDimitry Andric uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) { 37*68d75effSDimitry Andric using namespace __lsan; 38*68d75effSDimitry Andric uptr stack_top = 0, stack_bottom = 0; 39*68d75effSDimitry Andric ThreadContext *t; 40*68d75effSDimitry Andric if (StackTrace::WillUseFastUnwind(request_fast) && 41*68d75effSDimitry Andric (t = CurrentThreadContext())) { 42*68d75effSDimitry Andric stack_top = t->stack_end(); 43*68d75effSDimitry Andric stack_bottom = t->stack_begin(); 44*68d75effSDimitry Andric } 45*68d75effSDimitry Andric if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) { 46*68d75effSDimitry Andric if (StackTrace::WillUseFastUnwind(request_fast)) 47*68d75effSDimitry Andric Unwind(max_depth, pc, bp, nullptr, stack_top, stack_bottom, true); 48*68d75effSDimitry Andric else 49*68d75effSDimitry Andric Unwind(max_depth, pc, 0, context, 0, 0, false); 50*68d75effSDimitry Andric } 51*68d75effSDimitry Andric } 52*68d75effSDimitry Andric 53*68d75effSDimitry Andric using namespace __lsan; 54*68d75effSDimitry Andric 55*68d75effSDimitry Andric static void InitializeFlags() { 56*68d75effSDimitry Andric // Set all the default values. 57*68d75effSDimitry Andric SetCommonFlagsDefaults(); 58*68d75effSDimitry Andric { 59*68d75effSDimitry Andric CommonFlags cf; 60*68d75effSDimitry Andric cf.CopyFrom(*common_flags()); 61*68d75effSDimitry Andric cf.external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH"); 62*68d75effSDimitry Andric cf.malloc_context_size = 30; 63*68d75effSDimitry Andric cf.intercept_tls_get_addr = true; 64*68d75effSDimitry Andric cf.detect_leaks = true; 65*68d75effSDimitry Andric cf.exitcode = 23; 66*68d75effSDimitry Andric OverrideCommonFlags(cf); 67*68d75effSDimitry Andric } 68*68d75effSDimitry Andric 69*68d75effSDimitry Andric Flags *f = flags(); 70*68d75effSDimitry Andric f->SetDefaults(); 71*68d75effSDimitry Andric 72*68d75effSDimitry Andric FlagParser parser; 73*68d75effSDimitry Andric RegisterLsanFlags(&parser, f); 74*68d75effSDimitry Andric RegisterCommonFlags(&parser); 75*68d75effSDimitry Andric 76*68d75effSDimitry Andric // Override from user-specified string. 77*68d75effSDimitry Andric const char *lsan_default_options = MaybeCallLsanDefaultOptions(); 78*68d75effSDimitry Andric parser.ParseString(lsan_default_options); 79*68d75effSDimitry Andric parser.ParseStringFromEnv("LSAN_OPTIONS"); 80*68d75effSDimitry Andric 81*68d75effSDimitry Andric SetVerbosity(common_flags()->verbosity); 82*68d75effSDimitry Andric 83*68d75effSDimitry Andric if (Verbosity()) ReportUnrecognizedFlags(); 84*68d75effSDimitry Andric 85*68d75effSDimitry Andric if (common_flags()->help) parser.PrintFlagDescriptions(); 86*68d75effSDimitry Andric 87*68d75effSDimitry Andric __sanitizer_set_report_path(common_flags()->log_path); 88*68d75effSDimitry Andric } 89*68d75effSDimitry Andric 90*68d75effSDimitry Andric static void OnStackUnwind(const SignalContext &sig, const void *, 91*68d75effSDimitry Andric BufferedStackTrace *stack) { 92*68d75effSDimitry Andric stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context, 93*68d75effSDimitry Andric common_flags()->fast_unwind_on_fatal); 94*68d75effSDimitry Andric } 95*68d75effSDimitry Andric 96*68d75effSDimitry Andric static void LsanOnDeadlySignal(int signo, void *siginfo, void *context) { 97*68d75effSDimitry Andric HandleDeadlySignal(siginfo, context, GetCurrentThread(), &OnStackUnwind, 98*68d75effSDimitry Andric nullptr); 99*68d75effSDimitry Andric } 100*68d75effSDimitry Andric 101*68d75effSDimitry Andric extern "C" void __lsan_init() { 102*68d75effSDimitry Andric CHECK(!lsan_init_is_running); 103*68d75effSDimitry Andric if (lsan_inited) 104*68d75effSDimitry Andric return; 105*68d75effSDimitry Andric lsan_init_is_running = true; 106*68d75effSDimitry Andric SanitizerToolName = "LeakSanitizer"; 107*68d75effSDimitry Andric CacheBinaryName(); 108*68d75effSDimitry Andric AvoidCVE_2016_2143(); 109*68d75effSDimitry Andric InitializeFlags(); 110*68d75effSDimitry Andric InitCommonLsan(); 111*68d75effSDimitry Andric InitializeAllocator(); 112*68d75effSDimitry Andric ReplaceSystemMalloc(); 113*68d75effSDimitry Andric InitTlsSize(); 114*68d75effSDimitry Andric InitializeInterceptors(); 115*68d75effSDimitry Andric InitializeThreadRegistry(); 116*68d75effSDimitry Andric InstallDeadlySignalHandlers(LsanOnDeadlySignal); 117*68d75effSDimitry Andric u32 tid = ThreadCreate(0, 0, true); 118*68d75effSDimitry Andric CHECK_EQ(tid, 0); 119*68d75effSDimitry Andric ThreadStart(tid, GetTid()); 120*68d75effSDimitry Andric SetCurrentThread(tid); 121*68d75effSDimitry Andric 122*68d75effSDimitry Andric if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) 123*68d75effSDimitry Andric Atexit(DoLeakCheck); 124*68d75effSDimitry Andric 125*68d75effSDimitry Andric InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir); 126*68d75effSDimitry Andric 127*68d75effSDimitry Andric lsan_inited = true; 128*68d75effSDimitry Andric lsan_init_is_running = false; 129*68d75effSDimitry Andric } 130*68d75effSDimitry Andric 131*68d75effSDimitry Andric extern "C" SANITIZER_INTERFACE_ATTRIBUTE 132*68d75effSDimitry Andric void __sanitizer_print_stack_trace() { 133*68d75effSDimitry Andric GET_STACK_TRACE_FATAL; 134*68d75effSDimitry Andric stack.Print(); 135*68d75effSDimitry Andric } 136