1//=-- lsan.cc -------------------------------------------------------------===// 2// 3// This file is distributed under the University of Illinois Open Source 4// License. See LICENSE.TXT for details. 5// 6//===----------------------------------------------------------------------===// 7// 8// This file is a part of LeakSanitizer. 9// Standalone LSan RTL. 10// 11//===----------------------------------------------------------------------===// 12 13#include "lsan.h" 14 15#include "sanitizer_common/sanitizer_flags.h" 16#include "sanitizer_common/sanitizer_flag_parser.h" 17#include "sanitizer_common/sanitizer_stacktrace.h" 18#include "lsan_allocator.h" 19#include "lsan_common.h" 20#include "lsan_thread.h" 21 22bool lsan_inited; 23bool lsan_init_is_running; 24 25namespace __lsan { 26 27///// Interface to the common LSan module. ///// 28bool WordIsPoisoned(uptr addr) { 29 return false; 30} 31 32} // namespace __lsan 33 34using namespace __lsan; // NOLINT 35 36static void InitializeFlags() { 37 // Set all the default values. 38 SetCommonFlagsDefaults(); 39 { 40 CommonFlags cf; 41 cf.CopyFrom(*common_flags()); 42 cf.external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH"); 43 cf.malloc_context_size = 30; 44 cf.intercept_tls_get_addr = true; 45 cf.detect_leaks = true; 46 cf.exitcode = 23; 47 OverrideCommonFlags(cf); 48 } 49 50 Flags *f = flags(); 51 f->SetDefaults(); 52 53 FlagParser parser; 54 RegisterLsanFlags(&parser, f); 55 RegisterCommonFlags(&parser); 56 57 // Override from user-specified string. 58 const char *lsan_default_options = MaybeCallLsanDefaultOptions(); 59 parser.ParseString(lsan_default_options); 60 parser.ParseString(GetEnv("LSAN_OPTIONS")); 61 62 SetVerbosity(common_flags()->verbosity); 63 64 if (Verbosity()) ReportUnrecognizedFlags(); 65 66 if (common_flags()->help) parser.PrintFlagDescriptions(); 67 68 __sanitizer_set_report_path(common_flags()->log_path); 69} 70 71static void OnStackUnwind(const SignalContext &sig, const void *, 72 BufferedStackTrace *stack) { 73 GetStackTrace(stack, kStackTraceMax, sig.pc, sig.bp, sig.context, 74 common_flags()->fast_unwind_on_fatal); 75} 76 77static void LsanOnDeadlySignal(int signo, void *siginfo, void *context) { 78 HandleDeadlySignal(siginfo, context, GetCurrentThread(), &OnStackUnwind, 79 nullptr); 80} 81 82extern "C" void __lsan_init() { 83 CHECK(!lsan_init_is_running); 84 if (lsan_inited) 85 return; 86 lsan_init_is_running = true; 87 SanitizerToolName = "LeakSanitizer"; 88 CacheBinaryName(); 89 AvoidCVE_2016_2143(); 90 InitializeFlags(); 91 InitCommonLsan(); 92 InitializeAllocator(); 93 ReplaceSystemMalloc(); 94 InitTlsSize(); 95 InitializeInterceptors(); 96 InitializeThreadRegistry(); 97 InstallDeadlySignalHandlers(LsanOnDeadlySignal); 98 u32 tid = ThreadCreate(0, 0, true); 99 CHECK_EQ(tid, 0); 100 ThreadStart(tid, GetTid()); 101 SetCurrentThread(tid); 102 103 if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) 104 Atexit(DoLeakCheck); 105 106 InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir); 107 108 lsan_inited = true; 109 lsan_init_is_running = false; 110} 111 112extern "C" SANITIZER_INTERFACE_ATTRIBUTE 113void __sanitizer_print_stack_trace() { 114 GET_STACK_TRACE_FATAL; 115 stack.Print(); 116} 117