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