xref: /netbsd-src/sys/external/bsd/compiler_rt/dist/lib/lsan/lsan.cc (revision 38dfd33d612771e3205b5a18a9eaeef7e865abd3)
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