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