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