Home | History | Annotate | Line # | Download | only in lsan
      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. /////
     30 bool WordIsPoisoned(uptr addr) {
     31   return false;
     32 }
     33 
     34 }  // namespace __lsan
     35 
     36 using namespace __lsan;  // NOLINT
     37 
     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 
     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 
     79 static void LsanOnDeadlySignal(int signo, void *siginfo, void *context) {
     80   HandleDeadlySignal(siginfo, context, GetCurrentThread(), &OnStackUnwind,
     81                      nullptr);
     82 }
     83 
     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
    115 void __sanitizer_print_stack_trace() {
    116   GET_STACK_TRACE_FATAL;
    117   stack.Print();
    118 }
    119