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