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. /////
WordIsPoisoned(uptr addr)2968d75effSDimitry Andric bool WordIsPoisoned(uptr addr) {
3068d75effSDimitry Andric return false;
3168d75effSDimitry Andric }
3268d75effSDimitry Andric
3368d75effSDimitry Andric } // namespace __lsan
3468d75effSDimitry Andric
UnwindImpl(uptr pc,uptr bp,void * context,bool request_fast,u32 max_depth)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
InitializeFlags()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
__lsan_init()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
__sanitizer_print_stack_trace()11368d75effSDimitry Andric void __sanitizer_print_stack_trace() {
11468d75effSDimitry Andric GET_STACK_TRACE_FATAL;
11568d75effSDimitry Andric stack.Print();
11668d75effSDimitry Andric }
117