| 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 "lsan_allocator.h" |
| 17 | #include "lsan_common.h" |
| 18 | #include "lsan_thread.h" |
| 19 | #include "sanitizer_common/sanitizer_flag_parser.h" |
| 20 | #include "sanitizer_common/sanitizer_flags.h" |
| 21 | #include "sanitizer_common/sanitizer_interface_internal.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 | if (ThreadContextLsanBase *t = GetCurrentThread()) { |
| 40 | stack_top = t->stack_end(); |
| 41 | stack_bottom = t->stack_begin(); |
| 42 | } |
| 43 | if (SANITIZER_MIPS && !IsValidFrame(frame: bp, stack_top, stack_bottom)) |
| 44 | return; |
| 45 | bool fast = StackTrace::WillUseFastUnwind(request_fast_unwind: request_fast); |
| 46 | Unwind(max_depth, pc, bp, context, stack_top, stack_bottom, request_fast_unwind: fast); |
| 47 | } |
| 48 | |
| 49 | using namespace __lsan; |
| 50 | |
| 51 | static void InitializeFlags() { |
| 52 | // Set all the default values. |
| 53 | SetCommonFlagsDefaults(); |
| 54 | { |
| 55 | CommonFlags cf; |
| 56 | cf.CopyFrom(other: *common_flags()); |
| 57 | cf.external_symbolizer_path = GetEnv(name: "LSAN_SYMBOLIZER_PATH" ); |
| 58 | cf.malloc_context_size = 30; |
| 59 | cf.intercept_tls_get_addr = true; |
| 60 | cf.detect_leaks = true; |
| 61 | cf.exitcode = 23; |
| 62 | OverrideCommonFlags(cf); |
| 63 | } |
| 64 | |
| 65 | Flags *f = flags(); |
| 66 | f->SetDefaults(); |
| 67 | |
| 68 | FlagParser parser; |
| 69 | RegisterLsanFlags(parser: &parser, f); |
| 70 | RegisterCommonFlags(parser: &parser); |
| 71 | |
| 72 | // Override from user-specified string. |
| 73 | const char *lsan_default_options = __lsan_default_options(); |
| 74 | parser.ParseString(s: lsan_default_options); |
| 75 | parser.ParseStringFromEnv(env_name: "LSAN_OPTIONS" ); |
| 76 | |
| 77 | InitializeCommonFlags(); |
| 78 | |
| 79 | if (Verbosity()) ReportUnrecognizedFlags(); |
| 80 | |
| 81 | if (common_flags()->help) parser.PrintFlagDescriptions(); |
| 82 | |
| 83 | __sanitizer_set_report_path(path: common_flags()->log_path); |
| 84 | } |
| 85 | |
| 86 | extern "C" void __lsan_init() { |
| 87 | CHECK(!lsan_init_is_running); |
| 88 | if (lsan_inited) |
| 89 | return; |
| 90 | lsan_init_is_running = true; |
| 91 | SanitizerToolName = "LeakSanitizer" ; |
| 92 | CacheBinaryName(); |
| 93 | AvoidCVE_2016_2143(); |
| 94 | InitializeFlags(); |
| 95 | InitializePlatformEarly(); |
| 96 | InitCommonLsan(); |
| 97 | InitializeAllocator(); |
| 98 | ReplaceSystemMalloc(); |
| 99 | InitializeInterceptors(); |
| 100 | InitializeThreads(); |
| 101 | InstallDeadlySignalHandlers(handler: LsanOnDeadlySignal); |
| 102 | InitializeMainThread(); |
| 103 | InstallAtExitCheckLeaks(); |
| 104 | InstallAtForkHandler(); |
| 105 | |
| 106 | InitializeCoverage(enabled: common_flags()->coverage, coverage_dir: common_flags()->coverage_dir); |
| 107 | |
| 108 | lsan_inited = true; |
| 109 | lsan_init_is_running = false; |
| 110 | } |
| 111 | |
| 112 | extern "C" SANITIZER_INTERFACE_ATTRIBUTE |
| 113 | void __sanitizer_print_stack_trace() { |
| 114 | GET_STACK_TRACE_FATAL; |
| 115 | stack.Print(); |
| 116 | } |
| 117 | |