145
|
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 }
|