xref: /freebsd/contrib/llvm-project/compiler-rt/lib/lsan/lsan.cpp (revision e9e8876a4d6afc1ad5315faaa191b25121a813d7)
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 "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. /////
28 bool WordIsPoisoned(uptr addr) {
29   return false;
30 }
31 
32 }  // namespace __lsan
33 
34 void __sanitizer::BufferedStackTrace::UnwindImpl(
35     uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
36   using namespace __lsan;
37   uptr stack_top = 0, stack_bottom = 0;
38   if (ThreadContext *t = CurrentThreadContext()) {
39     stack_top = t->stack_end();
40     stack_bottom = t->stack_begin();
41   }
42   if (SANITIZER_MIPS && !IsValidFrame(bp, stack_top, stack_bottom))
43     return;
44   bool fast = StackTrace::WillUseFastUnwind(request_fast);
45   Unwind(max_depth, pc, bp, context, stack_top, stack_bottom, fast);
46 }
47 
48 using namespace __lsan;
49 
50 static void InitializeFlags() {
51   // Set all the default values.
52   SetCommonFlagsDefaults();
53   {
54     CommonFlags cf;
55     cf.CopyFrom(*common_flags());
56     cf.external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH");
57     cf.malloc_context_size = 30;
58     cf.intercept_tls_get_addr = true;
59     cf.detect_leaks = true;
60     cf.exitcode = 23;
61     OverrideCommonFlags(cf);
62   }
63 
64   Flags *f = flags();
65   f->SetDefaults();
66 
67   FlagParser parser;
68   RegisterLsanFlags(&parser, f);
69   RegisterCommonFlags(&parser);
70 
71   // Override from user-specified string.
72   const char *lsan_default_options = __lsan_default_options();
73   parser.ParseString(lsan_default_options);
74   parser.ParseStringFromEnv("LSAN_OPTIONS");
75 
76   InitializeCommonFlags();
77 
78   if (Verbosity()) ReportUnrecognizedFlags();
79 
80   if (common_flags()->help) parser.PrintFlagDescriptions();
81 
82   __sanitizer_set_report_path(common_flags()->log_path);
83 }
84 
85 extern "C" void __lsan_init() {
86   CHECK(!lsan_init_is_running);
87   if (lsan_inited)
88     return;
89   lsan_init_is_running = true;
90   SanitizerToolName = "LeakSanitizer";
91   CacheBinaryName();
92   AvoidCVE_2016_2143();
93   InitializeFlags();
94   InitCommonLsan();
95   InitializeAllocator();
96   ReplaceSystemMalloc();
97   InitTlsSize();
98   InitializeInterceptors();
99   InitializeThreadRegistry();
100   InstallDeadlySignalHandlers(LsanOnDeadlySignal);
101   InitializeMainThread();
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
113 void __sanitizer_print_stack_trace() {
114   GET_STACK_TRACE_FATAL;
115   stack.Print();
116 }
117