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 (ThreadContextLsanBase *t = GetCurrentThread()) { |
40 | stack_top = t->stack_end(); |
41 | stack_bottom = t->stack_begin(); |
42 | } |
43 | if (SANITIZER_MIPS && !IsValidFrame(frame: bp, stack_top, stack_bottom)) |
44 | return; |
45 | bool fast = StackTrace::WillUseFastUnwind(request_fast_unwind: request_fast); |
46 | Unwind(max_depth, pc, bp, context, stack_top, stack_bottom, request_fast_unwind: 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(other: *common_flags()); |
57 | cf.external_symbolizer_path = GetEnv(name: "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: &parser, f); |
70 | RegisterCommonFlags(parser: &parser); |
71 | |
72 | // Override from user-specified string. |
73 | const char *lsan_default_options = __lsan_default_options(); |
74 | parser.ParseString(s: lsan_default_options); |
75 | parser.ParseStringFromEnv(env_name: "LSAN_OPTIONS" ); |
76 | |
77 | InitializeCommonFlags(); |
78 | |
79 | if (Verbosity()) ReportUnrecognizedFlags(); |
80 | |
81 | if (common_flags()->help) parser.PrintFlagDescriptions(); |
82 | |
83 | __sanitizer_set_report_path(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 | InitializeThreads(); |
101 | InstallDeadlySignalHandlers(handler: LsanOnDeadlySignal); |
102 | InitializeMainThread(); |
103 | InstallAtExitCheckLeaks(); |
104 | InstallAtForkHandler(); |
105 | |
106 | InitializeCoverage(enabled: common_flags()->coverage, coverage_dir: 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 | |