//=-- lsan.cc -------------------------------------------------------------===// // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file is a part of LeakSanitizer. // Standalone LSan RTL. // //===----------------------------------------------------------------------===// #include "lsan.h" #include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_flag_parser.h" #include "sanitizer_common/sanitizer_stacktrace.h" #include "sanitizer_common/sanitizer_libc.h" #include "lsan_allocator.h" #include "lsan_common.h" #include "lsan_thread.h" bool lsan_inited; bool lsan_init_is_running; namespace __lsan { ///// Interface to the common LSan module. ///// bool WordIsPoisoned(uptr addr) { return false; } #if LSAN_DYNAMIC // Initialize runtime in case it's LD_PRELOAD-ed into unsanitized executable // (and thus normal initializers from .preinit_array or modules haven't run). class LsanInitializer { public: // NOLINT LsanInitializer() { __lsan_init(); } }; static LsanInitializer lsan_initializer; #endif // LSAN_DYNAMIC } // namespace __lsan using namespace __lsan; // NOLINT static void InitializeFlags() { // Set all the default values. SetCommonFlagsDefaults(); { CommonFlags cf; cf.CopyFrom(*common_flags()); cf.external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH"); cf.malloc_context_size = 30; cf.detect_leaks = false; cf.exitcode = 0; OverrideCommonFlags(cf); } Flags *f = flags(); f->SetDefaults(); FlagParser parser; RegisterLsanFlags(&parser, f); RegisterCommonFlags(&parser); int mmaped = 0; const char *options = GetRuntimeOptions("LSAN_OPTIONS", "/LSAN_OPTIONS", &mmaped); parser.ParseString(options); SetVerbosity(common_flags()->verbosity); if (Verbosity()) ReportUnrecognizedFlags(); if (common_flags()->help) parser.PrintFlagDescriptions(); __sanitizer_set_report_path(common_flags()->log_path); if (mmaped) UnmapOrDie((void *)options, GetPageSizeCached()); } extern "C" void __lsan_init() { CHECK(!lsan_init_is_running); if (LIKELY(lsan_inited)) return; SanitizerToolName = "LeakSanitizer"; MaybeMountProcFS(); lsan_init_is_running = true; CacheBinaryName(); InitializeFlags(); InitCommonLsan(); InitializeAllocator(); InitTlsSize(); InitializeInterceptors(); InitializeThreadRegistry(); u32 tid = ThreadCreate(0, 0, true); CHECK_EQ(tid, 0); ThreadStart(tid, GetTid()); SetCurrentThread(tid); if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) Atexit(DoLeakCheck); InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir); lsan_inited = true; lsan_init_is_running = false; } extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_print_stack_trace() { GET_STACK_TRACE_FATAL; stack.Print(); }