1 //=-- lsan.cc -------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file is a part of LeakSanitizer.
10 // Standalone LSan RTL.
12 //===----------------------------------------------------------------------===//
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"
24 bool lsan_init_is_running;
28 ///// Interface to the common LSan module. /////
29 bool WordIsPoisoned(uptr addr) {
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;
40 if (StackTrace::WillUseFastUnwind(request_fast) &&
41 (t = CurrentThreadContext())) {
42 stack_top = t->stack_end();
43 stack_bottom = t->stack_begin();
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);
49 Unwind(max_depth, pc, 0, context, 0, 0, false);
53 using namespace __lsan; // NOLINT
55 static void InitializeFlags() {
56 // Set all the default values.
57 SetCommonFlagsDefaults();
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;
66 OverrideCommonFlags(cf);
73 RegisterLsanFlags(&parser, f);
74 RegisterCommonFlags(&parser);
76 // Override from user-specified string.
77 const char *lsan_default_options = MaybeCallLsanDefaultOptions();
78 parser.ParseString(lsan_default_options);
79 parser.ParseStringFromEnv("LSAN_OPTIONS");
81 SetVerbosity(common_flags()->verbosity);
83 if (Verbosity()) ReportUnrecognizedFlags();
85 if (common_flags()->help) parser.PrintFlagDescriptions();
87 __sanitizer_set_report_path(common_flags()->log_path);
90 static void OnStackUnwind(const SignalContext &sig, const void *,
91 BufferedStackTrace *stack) {
92 stack->Unwind(sig.pc, sig.bp, sig.context,
93 common_flags()->fast_unwind_on_fatal);
96 static void LsanOnDeadlySignal(int signo, void *siginfo, void *context) {
97 HandleDeadlySignal(siginfo, context, GetCurrentThread(), &OnStackUnwind,
101 extern "C" void __lsan_init() {
102 CHECK(!lsan_init_is_running);
105 lsan_init_is_running = true;
106 SanitizerToolName = "LeakSanitizer";
108 AvoidCVE_2016_2143();
111 InitializeAllocator();
112 ReplaceSystemMalloc();
114 InitializeInterceptors();
115 InitializeThreadRegistry();
116 InstallDeadlySignalHandlers(LsanOnDeadlySignal);
117 u32 tid = ThreadCreate(0, 0, true);
119 ThreadStart(tid, GetTid());
120 SetCurrentThread(tid);
122 if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit)
125 InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
128 lsan_init_is_running = false;
131 extern "C" SANITIZER_INTERFACE_ATTRIBUTE
132 void __sanitizer_print_stack_trace() {
133 GET_STACK_TRACE_FATAL;