xref: /freebsd/contrib/llvm-project/compiler-rt/lib/lsan/lsan.cpp (revision fe6060f10f634930ff71b7c50291ddc610da2475)
168d75effSDimitry Andric //=-- lsan.cpp ------------------------------------------------------------===//
268d75effSDimitry Andric //
368d75effSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
468d75effSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
568d75effSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
668d75effSDimitry Andric //
768d75effSDimitry Andric //===----------------------------------------------------------------------===//
868d75effSDimitry Andric //
968d75effSDimitry Andric // This file is a part of LeakSanitizer.
1068d75effSDimitry Andric // Standalone LSan RTL.
1168d75effSDimitry Andric //
1268d75effSDimitry Andric //===----------------------------------------------------------------------===//
1368d75effSDimitry Andric 
1468d75effSDimitry Andric #include "lsan.h"
1568d75effSDimitry Andric 
1668d75effSDimitry Andric #include "sanitizer_common/sanitizer_flags.h"
1768d75effSDimitry Andric #include "sanitizer_common/sanitizer_flag_parser.h"
1868d75effSDimitry Andric #include "lsan_allocator.h"
1968d75effSDimitry Andric #include "lsan_common.h"
2068d75effSDimitry Andric #include "lsan_thread.h"
2168d75effSDimitry Andric 
2268d75effSDimitry Andric bool lsan_inited;
2368d75effSDimitry Andric bool lsan_init_is_running;
2468d75effSDimitry Andric 
2568d75effSDimitry Andric namespace __lsan {
2668d75effSDimitry Andric 
2768d75effSDimitry Andric ///// Interface to the common LSan module. /////
2868d75effSDimitry Andric bool WordIsPoisoned(uptr addr) {
2968d75effSDimitry Andric   return false;
3068d75effSDimitry Andric }
3168d75effSDimitry Andric 
3268d75effSDimitry Andric }  // namespace __lsan
3368d75effSDimitry Andric 
3468d75effSDimitry Andric void __sanitizer::BufferedStackTrace::UnwindImpl(
3568d75effSDimitry Andric     uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
3668d75effSDimitry Andric   using namespace __lsan;
3768d75effSDimitry Andric   uptr stack_top = 0, stack_bottom = 0;
38*fe6060f1SDimitry Andric   if (ThreadContext *t = CurrentThreadContext()) {
3968d75effSDimitry Andric     stack_top = t->stack_end();
4068d75effSDimitry Andric     stack_bottom = t->stack_begin();
4168d75effSDimitry Andric   }
42*fe6060f1SDimitry Andric   if (SANITIZER_MIPS && !IsValidFrame(bp, stack_top, stack_bottom))
43*fe6060f1SDimitry Andric     return;
44*fe6060f1SDimitry Andric   bool fast = StackTrace::WillUseFastUnwind(request_fast);
45*fe6060f1SDimitry Andric   Unwind(max_depth, pc, bp, context, stack_top, stack_bottom, fast);
4668d75effSDimitry Andric }
4768d75effSDimitry Andric 
4868d75effSDimitry Andric using namespace __lsan;
4968d75effSDimitry Andric 
5068d75effSDimitry Andric static void InitializeFlags() {
5168d75effSDimitry Andric   // Set all the default values.
5268d75effSDimitry Andric   SetCommonFlagsDefaults();
5368d75effSDimitry Andric   {
5468d75effSDimitry Andric     CommonFlags cf;
5568d75effSDimitry Andric     cf.CopyFrom(*common_flags());
5668d75effSDimitry Andric     cf.external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH");
5768d75effSDimitry Andric     cf.malloc_context_size = 30;
5868d75effSDimitry Andric     cf.intercept_tls_get_addr = true;
5968d75effSDimitry Andric     cf.detect_leaks = true;
6068d75effSDimitry Andric     cf.exitcode = 23;
6168d75effSDimitry Andric     OverrideCommonFlags(cf);
6268d75effSDimitry Andric   }
6368d75effSDimitry Andric 
6468d75effSDimitry Andric   Flags *f = flags();
6568d75effSDimitry Andric   f->SetDefaults();
6668d75effSDimitry Andric 
6768d75effSDimitry Andric   FlagParser parser;
6868d75effSDimitry Andric   RegisterLsanFlags(&parser, f);
6968d75effSDimitry Andric   RegisterCommonFlags(&parser);
7068d75effSDimitry Andric 
7168d75effSDimitry Andric   // Override from user-specified string.
72e8d8bef9SDimitry Andric   const char *lsan_default_options = __lsan_default_options();
7368d75effSDimitry Andric   parser.ParseString(lsan_default_options);
7468d75effSDimitry Andric   parser.ParseStringFromEnv("LSAN_OPTIONS");
7568d75effSDimitry Andric 
76e8d8bef9SDimitry Andric   InitializeCommonFlags();
7768d75effSDimitry Andric 
7868d75effSDimitry Andric   if (Verbosity()) ReportUnrecognizedFlags();
7968d75effSDimitry Andric 
8068d75effSDimitry Andric   if (common_flags()->help) parser.PrintFlagDescriptions();
8168d75effSDimitry Andric 
8268d75effSDimitry Andric   __sanitizer_set_report_path(common_flags()->log_path);
8368d75effSDimitry Andric }
8468d75effSDimitry Andric 
8568d75effSDimitry Andric extern "C" void __lsan_init() {
8668d75effSDimitry Andric   CHECK(!lsan_init_is_running);
8768d75effSDimitry Andric   if (lsan_inited)
8868d75effSDimitry Andric     return;
8968d75effSDimitry Andric   lsan_init_is_running = true;
9068d75effSDimitry Andric   SanitizerToolName = "LeakSanitizer";
9168d75effSDimitry Andric   CacheBinaryName();
9268d75effSDimitry Andric   AvoidCVE_2016_2143();
9368d75effSDimitry Andric   InitializeFlags();
9468d75effSDimitry Andric   InitCommonLsan();
9568d75effSDimitry Andric   InitializeAllocator();
9668d75effSDimitry Andric   ReplaceSystemMalloc();
9768d75effSDimitry Andric   InitTlsSize();
9868d75effSDimitry Andric   InitializeInterceptors();
9968d75effSDimitry Andric   InitializeThreadRegistry();
10068d75effSDimitry Andric   InstallDeadlySignalHandlers(LsanOnDeadlySignal);
1015ffd83dbSDimitry Andric   InitializeMainThread();
10268d75effSDimitry Andric 
10368d75effSDimitry Andric   if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit)
10468d75effSDimitry Andric     Atexit(DoLeakCheck);
10568d75effSDimitry Andric 
10668d75effSDimitry Andric   InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
10768d75effSDimitry Andric 
10868d75effSDimitry Andric   lsan_inited = true;
10968d75effSDimitry Andric   lsan_init_is_running = false;
11068d75effSDimitry Andric }
11168d75effSDimitry Andric 
11268d75effSDimitry Andric extern "C" SANITIZER_INTERFACE_ATTRIBUTE
11368d75effSDimitry Andric void __sanitizer_print_stack_trace() {
11468d75effSDimitry Andric   GET_STACK_TRACE_FATAL;
11568d75effSDimitry Andric   stack.Print();
11668d75effSDimitry Andric }
117