xref: /freebsd/contrib/llvm-project/compiler-rt/lib/lsan/lsan.cpp (revision e32fecd0c2c3ee37c47ee100f169e7eb0282a873)
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 "lsan_allocator.h"
17 #include "lsan_common.h"
18 #include "lsan_thread.h"
19 #include "sanitizer_common/sanitizer_flag_parser.h"
20 #include "sanitizer_common/sanitizer_flags.h"
21 #include "sanitizer_common/sanitizer_interface_internal.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   if (ThreadContext *t = CurrentThreadContext()) {
40     stack_top = t->stack_end();
41     stack_bottom = t->stack_begin();
42   }
43   if (SANITIZER_MIPS && !IsValidFrame(bp, stack_top, stack_bottom))
44     return;
45   bool fast = StackTrace::WillUseFastUnwind(request_fast);
46   Unwind(max_depth, pc, bp, context, stack_top, stack_bottom, fast);
47 }
48 
49 using namespace __lsan;
50 
51 static void InitializeFlags() {
52   // Set all the default values.
53   SetCommonFlagsDefaults();
54   {
55     CommonFlags cf;
56     cf.CopyFrom(*common_flags());
57     cf.external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH");
58     cf.malloc_context_size = 30;
59     cf.intercept_tls_get_addr = true;
60     cf.detect_leaks = true;
61     cf.exitcode = 23;
62     OverrideCommonFlags(cf);
63   }
64 
65   Flags *f = flags();
66   f->SetDefaults();
67 
68   FlagParser parser;
69   RegisterLsanFlags(&parser, f);
70   RegisterCommonFlags(&parser);
71 
72   // Override from user-specified string.
73   const char *lsan_default_options = __lsan_default_options();
74   parser.ParseString(lsan_default_options);
75   parser.ParseStringFromEnv("LSAN_OPTIONS");
76 
77   InitializeCommonFlags();
78 
79   if (Verbosity()) ReportUnrecognizedFlags();
80 
81   if (common_flags()->help) parser.PrintFlagDescriptions();
82 
83   __sanitizer_set_report_path(common_flags()->log_path);
84 }
85 
86 extern "C" void __lsan_init() {
87   CHECK(!lsan_init_is_running);
88   if (lsan_inited)
89     return;
90   lsan_init_is_running = true;
91   SanitizerToolName = "LeakSanitizer";
92   CacheBinaryName();
93   AvoidCVE_2016_2143();
94   InitializeFlags();
95   InitCommonLsan();
96   InitializeAllocator();
97   ReplaceSystemMalloc();
98   InitTlsSize();
99   InitializeInterceptors();
100   InitializeThreadRegistry();
101   InstallDeadlySignalHandlers(LsanOnDeadlySignal);
102   InitializeMainThread();
103   InstallAtExitCheckLeaks();
104 
105   InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
106 
107   lsan_inited = true;
108   lsan_init_is_running = false;
109 }
110 
111 extern "C" SANITIZER_INTERFACE_ATTRIBUTE
112 void __sanitizer_print_stack_trace() {
113   GET_STACK_TRACE_FATAL;
114   stack.Print();
115 }
116