1*490215a3Smrg //=-- lsan.cc -------------------------------------------------------------===//
2*490215a3Smrg //
3*490215a3Smrg // This file is distributed under the University of Illinois Open Source
4*490215a3Smrg // License. See LICENSE.TXT for details.
5*490215a3Smrg //
6*490215a3Smrg //===----------------------------------------------------------------------===//
7*490215a3Smrg //
8*490215a3Smrg // This file is a part of LeakSanitizer.
9*490215a3Smrg // Standalone LSan RTL.
10*490215a3Smrg //
11*490215a3Smrg //===----------------------------------------------------------------------===//
12*490215a3Smrg
13*490215a3Smrg #include "lsan.h"
14*490215a3Smrg
15*490215a3Smrg #include "sanitizer_common/sanitizer_flags.h"
16*490215a3Smrg #include "sanitizer_common/sanitizer_flag_parser.h"
17*490215a3Smrg #include "sanitizer_common/sanitizer_stacktrace.h"
18*490215a3Smrg #include "lsan_allocator.h"
19*490215a3Smrg #include "lsan_common.h"
20*490215a3Smrg #include "lsan_thread.h"
21*490215a3Smrg
22*490215a3Smrg bool lsan_inited;
23*490215a3Smrg bool lsan_init_is_running;
24*490215a3Smrg
25*490215a3Smrg namespace __lsan {
26*490215a3Smrg
27*490215a3Smrg ///// Interface to the common LSan module. /////
WordIsPoisoned(uptr addr)28*490215a3Smrg bool WordIsPoisoned(uptr addr) {
29*490215a3Smrg return false;
30*490215a3Smrg }
31*490215a3Smrg
32*490215a3Smrg } // namespace __lsan
33*490215a3Smrg
34*490215a3Smrg using namespace __lsan; // NOLINT
35*490215a3Smrg
InitializeFlags()36*490215a3Smrg static void InitializeFlags() {
37*490215a3Smrg // Set all the default values.
38*490215a3Smrg SetCommonFlagsDefaults();
39*490215a3Smrg {
40*490215a3Smrg CommonFlags cf;
41*490215a3Smrg cf.CopyFrom(*common_flags());
42*490215a3Smrg cf.external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH");
43*490215a3Smrg cf.malloc_context_size = 30;
44*490215a3Smrg cf.intercept_tls_get_addr = true;
45*490215a3Smrg cf.detect_leaks = true;
46*490215a3Smrg cf.exitcode = 23;
47*490215a3Smrg OverrideCommonFlags(cf);
48*490215a3Smrg }
49*490215a3Smrg
50*490215a3Smrg Flags *f = flags();
51*490215a3Smrg f->SetDefaults();
52*490215a3Smrg
53*490215a3Smrg FlagParser parser;
54*490215a3Smrg RegisterLsanFlags(&parser, f);
55*490215a3Smrg RegisterCommonFlags(&parser);
56*490215a3Smrg
57*490215a3Smrg // Override from user-specified string.
58*490215a3Smrg const char *lsan_default_options = MaybeCallLsanDefaultOptions();
59*490215a3Smrg parser.ParseString(lsan_default_options);
60*490215a3Smrg parser.ParseString(GetEnv("LSAN_OPTIONS"));
61*490215a3Smrg
62*490215a3Smrg SetVerbosity(common_flags()->verbosity);
63*490215a3Smrg
64*490215a3Smrg if (Verbosity()) ReportUnrecognizedFlags();
65*490215a3Smrg
66*490215a3Smrg if (common_flags()->help) parser.PrintFlagDescriptions();
67*490215a3Smrg
68*490215a3Smrg __sanitizer_set_report_path(common_flags()->log_path);
69*490215a3Smrg }
70*490215a3Smrg
OnStackUnwind(const SignalContext & sig,const void *,BufferedStackTrace * stack)71*490215a3Smrg static void OnStackUnwind(const SignalContext &sig, const void *,
72*490215a3Smrg BufferedStackTrace *stack) {
73*490215a3Smrg GetStackTrace(stack, kStackTraceMax, sig.pc, sig.bp, sig.context,
74*490215a3Smrg common_flags()->fast_unwind_on_fatal);
75*490215a3Smrg }
76*490215a3Smrg
LsanOnDeadlySignal(int signo,void * siginfo,void * context)77*490215a3Smrg static void LsanOnDeadlySignal(int signo, void *siginfo, void *context) {
78*490215a3Smrg HandleDeadlySignal(siginfo, context, GetCurrentThread(), &OnStackUnwind,
79*490215a3Smrg nullptr);
80*490215a3Smrg }
81*490215a3Smrg
__lsan_init()82*490215a3Smrg extern "C" void __lsan_init() {
83*490215a3Smrg CHECK(!lsan_init_is_running);
84*490215a3Smrg if (lsan_inited)
85*490215a3Smrg return;
86*490215a3Smrg lsan_init_is_running = true;
87*490215a3Smrg SanitizerToolName = "LeakSanitizer";
88*490215a3Smrg CacheBinaryName();
89*490215a3Smrg AvoidCVE_2016_2143();
90*490215a3Smrg InitializeFlags();
91*490215a3Smrg InitCommonLsan();
92*490215a3Smrg InitializeAllocator();
93*490215a3Smrg ReplaceSystemMalloc();
94*490215a3Smrg InitTlsSize();
95*490215a3Smrg InitializeInterceptors();
96*490215a3Smrg InitializeThreadRegistry();
97*490215a3Smrg InstallDeadlySignalHandlers(LsanOnDeadlySignal);
98*490215a3Smrg u32 tid = ThreadCreate(0, 0, true);
99*490215a3Smrg CHECK_EQ(tid, 0);
100*490215a3Smrg ThreadStart(tid, GetTid());
101*490215a3Smrg SetCurrentThread(tid);
102*490215a3Smrg
103*490215a3Smrg if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit)
104*490215a3Smrg Atexit(DoLeakCheck);
105*490215a3Smrg
106*490215a3Smrg InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
107*490215a3Smrg
108*490215a3Smrg lsan_inited = true;
109*490215a3Smrg lsan_init_is_running = false;
110*490215a3Smrg }
111*490215a3Smrg
112*490215a3Smrg extern "C" SANITIZER_INTERFACE_ATTRIBUTE
__sanitizer_print_stack_trace()113*490215a3Smrg void __sanitizer_print_stack_trace() {
114*490215a3Smrg GET_STACK_TRACE_FATAL;
115*490215a3Smrg stack.Print();
116*490215a3Smrg }
117