]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/lsan/lsan.cc
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / lsan / lsan.cc
1 //=-- lsan.cc -------------------------------------------------------------===//
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 "sanitizer_common/sanitizer_stacktrace.h"
19 #include "lsan_allocator.h"
20 #include "lsan_common.h"
21 #include "lsan_thread.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   ThreadContext *t;
40   if (StackTrace::WillUseFastUnwind(request_fast) &&
41       (t = CurrentThreadContext())) {
42     stack_top = t->stack_end();
43     stack_bottom = t->stack_begin();
44   }
45   if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) {
46     if (StackTrace::WillUseFastUnwind(request_fast))
47       Unwind(max_depth, pc, bp, nullptr, stack_top, stack_bottom, true);
48     else
49       Unwind(max_depth, pc, 0, context, 0, 0, false);
50   }
51 }
52
53 using namespace __lsan;  // NOLINT
54
55 static void InitializeFlags() {
56   // Set all the default values.
57   SetCommonFlagsDefaults();
58   {
59     CommonFlags cf;
60     cf.CopyFrom(*common_flags());
61     cf.external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH");
62     cf.malloc_context_size = 30;
63     cf.intercept_tls_get_addr = true;
64     cf.detect_leaks = true;
65     cf.exitcode = 23;
66     OverrideCommonFlags(cf);
67   }
68
69   Flags *f = flags();
70   f->SetDefaults();
71
72   FlagParser parser;
73   RegisterLsanFlags(&parser, f);
74   RegisterCommonFlags(&parser);
75
76   // Override from user-specified string.
77   const char *lsan_default_options = MaybeCallLsanDefaultOptions();
78   parser.ParseString(lsan_default_options);
79   parser.ParseStringFromEnv("LSAN_OPTIONS");
80
81   SetVerbosity(common_flags()->verbosity);
82
83   if (Verbosity()) ReportUnrecognizedFlags();
84
85   if (common_flags()->help) parser.PrintFlagDescriptions();
86
87   __sanitizer_set_report_path(common_flags()->log_path);
88 }
89
90 static void OnStackUnwind(const SignalContext &sig, const void *,
91                           BufferedStackTrace *stack) {
92   stack->Unwind(sig.pc, sig.bp, sig.context,
93                 common_flags()->fast_unwind_on_fatal);
94 }
95
96 static void LsanOnDeadlySignal(int signo, void *siginfo, void *context) {
97   HandleDeadlySignal(siginfo, context, GetCurrentThread(), &OnStackUnwind,
98                      nullptr);
99 }
100
101 extern "C" void __lsan_init() {
102   CHECK(!lsan_init_is_running);
103   if (lsan_inited)
104     return;
105   lsan_init_is_running = true;
106   SanitizerToolName = "LeakSanitizer";
107   CacheBinaryName();
108   AvoidCVE_2016_2143();
109   InitializeFlags();
110   InitCommonLsan();
111   InitializeAllocator();
112   ReplaceSystemMalloc();
113   InitTlsSize();
114   InitializeInterceptors();
115   InitializeThreadRegistry();
116   InstallDeadlySignalHandlers(LsanOnDeadlySignal);
117   u32 tid = ThreadCreate(0, 0, true);
118   CHECK_EQ(tid, 0);
119   ThreadStart(tid, GetTid());
120   SetCurrentThread(tid);
121
122   if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit)
123     Atexit(DoLeakCheck);
124
125   InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
126
127   lsan_inited = true;
128   lsan_init_is_running = false;
129 }
130
131 extern "C" SANITIZER_INTERFACE_ATTRIBUTE
132 void __sanitizer_print_stack_trace() {
133   GET_STACK_TRACE_FATAL;
134   stack.Print();
135 }