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 
22 bool lsan_inited;
23 bool lsan_init_is_running;
24 
25 namespace __lsan {
26 
27 ///// Interface to the common LSan module. /////
WordIsPoisoned(uptr addr)28 bool WordIsPoisoned(uptr addr) {
29   return false;
30 }
31 
32 }  // namespace __lsan
33 
34 using namespace __lsan;  // NOLINT
35 
InitializeFlags()36 static 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 
OnStackUnwind(const SignalContext & sig,const void *,BufferedStackTrace * stack)71 static 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 
LsanOnDeadlySignal(int signo,void * siginfo,void * context)77 static void LsanOnDeadlySignal(int signo, void *siginfo, void *context) {
78   HandleDeadlySignal(siginfo, context, GetCurrentThread(), &OnStackUnwind,
79                      nullptr);
80 }
81 
__lsan_init()82 extern "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 
112 extern "C" SANITIZER_INTERFACE_ATTRIBUTE
__sanitizer_print_stack_trace()113 void __sanitizer_print_stack_trace() {
114   GET_STACK_TRACE_FATAL;
115   stack.Print();
116 }
117