xref: /freebsd/contrib/llvm-project/compiler-rt/lib/lsan/lsan.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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 "lsan_allocator.h"
1768d75effSDimitry Andric #include "lsan_common.h"
1868d75effSDimitry Andric #include "lsan_thread.h"
1981ad6265SDimitry Andric #include "sanitizer_common/sanitizer_flag_parser.h"
2081ad6265SDimitry Andric #include "sanitizer_common/sanitizer_flags.h"
2181ad6265SDimitry Andric #include "sanitizer_common/sanitizer_interface_internal.h"
2268d75effSDimitry Andric 
2368d75effSDimitry Andric bool lsan_inited;
2468d75effSDimitry Andric bool lsan_init_is_running;
2568d75effSDimitry Andric 
2668d75effSDimitry Andric namespace __lsan {
2768d75effSDimitry Andric 
2868d75effSDimitry Andric ///// Interface to the common LSan module. /////
2968d75effSDimitry Andric bool WordIsPoisoned(uptr addr) {
3068d75effSDimitry Andric   return false;
3168d75effSDimitry Andric }
3268d75effSDimitry Andric 
3368d75effSDimitry Andric }  // namespace __lsan
3468d75effSDimitry Andric 
3568d75effSDimitry Andric void __sanitizer::BufferedStackTrace::UnwindImpl(
3668d75effSDimitry Andric     uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
3768d75effSDimitry Andric   using namespace __lsan;
3868d75effSDimitry Andric   uptr stack_top = 0, stack_bottom = 0;
3906c3fb27SDimitry Andric   if (ThreadContextLsanBase *t = GetCurrentThread()) {
4068d75effSDimitry Andric     stack_top = t->stack_end();
4168d75effSDimitry Andric     stack_bottom = t->stack_begin();
4268d75effSDimitry Andric   }
43fe6060f1SDimitry Andric   if (SANITIZER_MIPS && !IsValidFrame(bp, stack_top, stack_bottom))
44fe6060f1SDimitry Andric     return;
45fe6060f1SDimitry Andric   bool fast = StackTrace::WillUseFastUnwind(request_fast);
46fe6060f1SDimitry Andric   Unwind(max_depth, pc, bp, context, stack_top, stack_bottom, fast);
4768d75effSDimitry Andric }
4868d75effSDimitry Andric 
4968d75effSDimitry Andric using namespace __lsan;
5068d75effSDimitry Andric 
5168d75effSDimitry Andric static void InitializeFlags() {
5268d75effSDimitry Andric   // Set all the default values.
5368d75effSDimitry Andric   SetCommonFlagsDefaults();
5468d75effSDimitry Andric   {
5568d75effSDimitry Andric     CommonFlags cf;
5668d75effSDimitry Andric     cf.CopyFrom(*common_flags());
5768d75effSDimitry Andric     cf.external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH");
5868d75effSDimitry Andric     cf.malloc_context_size = 30;
5968d75effSDimitry Andric     cf.intercept_tls_get_addr = true;
6068d75effSDimitry Andric     cf.detect_leaks = true;
6168d75effSDimitry Andric     cf.exitcode = 23;
6268d75effSDimitry Andric     OverrideCommonFlags(cf);
6368d75effSDimitry Andric   }
6468d75effSDimitry Andric 
6568d75effSDimitry Andric   Flags *f = flags();
6668d75effSDimitry Andric   f->SetDefaults();
6768d75effSDimitry Andric 
6868d75effSDimitry Andric   FlagParser parser;
6968d75effSDimitry Andric   RegisterLsanFlags(&parser, f);
7068d75effSDimitry Andric   RegisterCommonFlags(&parser);
7168d75effSDimitry Andric 
7268d75effSDimitry Andric   // Override from user-specified string.
73e8d8bef9SDimitry Andric   const char *lsan_default_options = __lsan_default_options();
7468d75effSDimitry Andric   parser.ParseString(lsan_default_options);
7568d75effSDimitry Andric   parser.ParseStringFromEnv("LSAN_OPTIONS");
7668d75effSDimitry Andric 
77e8d8bef9SDimitry Andric   InitializeCommonFlags();
7868d75effSDimitry Andric 
7968d75effSDimitry Andric   if (Verbosity()) ReportUnrecognizedFlags();
8068d75effSDimitry Andric 
8168d75effSDimitry Andric   if (common_flags()->help) parser.PrintFlagDescriptions();
8268d75effSDimitry Andric 
8368d75effSDimitry Andric   __sanitizer_set_report_path(common_flags()->log_path);
8468d75effSDimitry Andric }
8568d75effSDimitry Andric 
8668d75effSDimitry Andric extern "C" void __lsan_init() {
8768d75effSDimitry Andric   CHECK(!lsan_init_is_running);
8868d75effSDimitry Andric   if (lsan_inited)
8968d75effSDimitry Andric     return;
9068d75effSDimitry Andric   lsan_init_is_running = true;
9168d75effSDimitry Andric   SanitizerToolName = "LeakSanitizer";
9268d75effSDimitry Andric   CacheBinaryName();
9368d75effSDimitry Andric   AvoidCVE_2016_2143();
9468d75effSDimitry Andric   InitializeFlags();
9568d75effSDimitry Andric   InitCommonLsan();
9668d75effSDimitry Andric   InitializeAllocator();
9768d75effSDimitry Andric   ReplaceSystemMalloc();
9868d75effSDimitry Andric   InitTlsSize();
9968d75effSDimitry Andric   InitializeInterceptors();
10006c3fb27SDimitry Andric   InitializeThreads();
10168d75effSDimitry Andric   InstallDeadlySignalHandlers(LsanOnDeadlySignal);
1025ffd83dbSDimitry Andric   InitializeMainThread();
10381ad6265SDimitry Andric   InstallAtExitCheckLeaks();
104*5f757f3fSDimitry Andric   InstallAtForkHandler();
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