xref: /freebsd-src/contrib/llvm-project/compiler-rt/lib/lsan/lsan.cpp (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
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;
3868d75effSDimitry Andric   ThreadContext *t;
3968d75effSDimitry Andric   if (StackTrace::WillUseFastUnwind(request_fast) &&
4068d75effSDimitry Andric       (t = CurrentThreadContext())) {
4168d75effSDimitry Andric     stack_top = t->stack_end();
4268d75effSDimitry Andric     stack_bottom = t->stack_begin();
4368d75effSDimitry Andric   }
4468d75effSDimitry Andric   if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) {
4568d75effSDimitry Andric     if (StackTrace::WillUseFastUnwind(request_fast))
4668d75effSDimitry Andric       Unwind(max_depth, pc, bp, nullptr, stack_top, stack_bottom, true);
4768d75effSDimitry Andric     else
4868d75effSDimitry Andric       Unwind(max_depth, pc, 0, context, 0, 0, false);
4968d75effSDimitry Andric   }
5068d75effSDimitry Andric }
5168d75effSDimitry Andric 
5268d75effSDimitry Andric using namespace __lsan;
5368d75effSDimitry Andric 
5468d75effSDimitry Andric static void InitializeFlags() {
5568d75effSDimitry Andric   // Set all the default values.
5668d75effSDimitry Andric   SetCommonFlagsDefaults();
5768d75effSDimitry Andric   {
5868d75effSDimitry Andric     CommonFlags cf;
5968d75effSDimitry Andric     cf.CopyFrom(*common_flags());
6068d75effSDimitry Andric     cf.external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH");
6168d75effSDimitry Andric     cf.malloc_context_size = 30;
6268d75effSDimitry Andric     cf.intercept_tls_get_addr = true;
6368d75effSDimitry Andric     cf.detect_leaks = true;
6468d75effSDimitry Andric     cf.exitcode = 23;
6568d75effSDimitry Andric     OverrideCommonFlags(cf);
6668d75effSDimitry Andric   }
6768d75effSDimitry Andric 
6868d75effSDimitry Andric   Flags *f = flags();
6968d75effSDimitry Andric   f->SetDefaults();
7068d75effSDimitry Andric 
7168d75effSDimitry Andric   FlagParser parser;
7268d75effSDimitry Andric   RegisterLsanFlags(&parser, f);
7368d75effSDimitry Andric   RegisterCommonFlags(&parser);
7468d75effSDimitry Andric 
7568d75effSDimitry Andric   // Override from user-specified string.
7668d75effSDimitry Andric   const char *lsan_default_options = MaybeCallLsanDefaultOptions();
7768d75effSDimitry Andric   parser.ParseString(lsan_default_options);
7868d75effSDimitry Andric   parser.ParseStringFromEnv("LSAN_OPTIONS");
7968d75effSDimitry Andric 
8068d75effSDimitry Andric   SetVerbosity(common_flags()->verbosity);
8168d75effSDimitry Andric 
8268d75effSDimitry Andric   if (Verbosity()) ReportUnrecognizedFlags();
8368d75effSDimitry Andric 
8468d75effSDimitry Andric   if (common_flags()->help) parser.PrintFlagDescriptions();
8568d75effSDimitry Andric 
8668d75effSDimitry Andric   __sanitizer_set_report_path(common_flags()->log_path);
8768d75effSDimitry Andric }
8868d75effSDimitry Andric 
8968d75effSDimitry Andric extern "C" void __lsan_init() {
9068d75effSDimitry Andric   CHECK(!lsan_init_is_running);
9168d75effSDimitry Andric   if (lsan_inited)
9268d75effSDimitry Andric     return;
9368d75effSDimitry Andric   lsan_init_is_running = true;
9468d75effSDimitry Andric   SanitizerToolName = "LeakSanitizer";
9568d75effSDimitry Andric   CacheBinaryName();
9668d75effSDimitry Andric   AvoidCVE_2016_2143();
9768d75effSDimitry Andric   InitializeFlags();
9868d75effSDimitry Andric   InitCommonLsan();
9968d75effSDimitry Andric   InitializeAllocator();
10068d75effSDimitry Andric   ReplaceSystemMalloc();
10168d75effSDimitry Andric   InitTlsSize();
10268d75effSDimitry Andric   InitializeInterceptors();
10368d75effSDimitry Andric   InitializeThreadRegistry();
10468d75effSDimitry Andric   InstallDeadlySignalHandlers(LsanOnDeadlySignal);
105*5ffd83dbSDimitry Andric   InitializeMainThread();
10668d75effSDimitry Andric 
10768d75effSDimitry Andric   if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit)
10868d75effSDimitry Andric     Atexit(DoLeakCheck);
10968d75effSDimitry Andric 
11068d75effSDimitry Andric   InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
11168d75effSDimitry Andric 
11268d75effSDimitry Andric   lsan_inited = true;
11368d75effSDimitry Andric   lsan_init_is_running = false;
11468d75effSDimitry Andric }
11568d75effSDimitry Andric 
11668d75effSDimitry Andric extern "C" SANITIZER_INTERFACE_ATTRIBUTE
11768d75effSDimitry Andric void __sanitizer_print_stack_trace() {
11868d75effSDimitry Andric   GET_STACK_TRACE_FATAL;
11968d75effSDimitry Andric   stack.Print();
12068d75effSDimitry Andric }
121