13cab2bb3Spatrick //=-- lsan.cpp ------------------------------------------------------------===// 23cab2bb3Spatrick // 33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information. 53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 63cab2bb3Spatrick // 73cab2bb3Spatrick //===----------------------------------------------------------------------===// 83cab2bb3Spatrick // 93cab2bb3Spatrick // This file is a part of LeakSanitizer. 103cab2bb3Spatrick // Standalone LSan RTL. 113cab2bb3Spatrick // 123cab2bb3Spatrick //===----------------------------------------------------------------------===// 133cab2bb3Spatrick 143cab2bb3Spatrick #include "lsan.h" 153cab2bb3Spatrick 163cab2bb3Spatrick #include "sanitizer_common/sanitizer_flags.h" 173cab2bb3Spatrick #include "sanitizer_common/sanitizer_flag_parser.h" 183cab2bb3Spatrick #include "lsan_allocator.h" 193cab2bb3Spatrick #include "lsan_common.h" 203cab2bb3Spatrick #include "lsan_thread.h" 213cab2bb3Spatrick 223cab2bb3Spatrick bool lsan_inited; 233cab2bb3Spatrick bool lsan_init_is_running; 243cab2bb3Spatrick 253cab2bb3Spatrick namespace __lsan { 263cab2bb3Spatrick 273cab2bb3Spatrick ///// Interface to the common LSan module. ///// 283cab2bb3Spatrick bool WordIsPoisoned(uptr addr) { 293cab2bb3Spatrick return false; 303cab2bb3Spatrick } 313cab2bb3Spatrick 323cab2bb3Spatrick } // namespace __lsan 333cab2bb3Spatrick 343cab2bb3Spatrick void __sanitizer::BufferedStackTrace::UnwindImpl( 353cab2bb3Spatrick uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) { 363cab2bb3Spatrick using namespace __lsan; 373cab2bb3Spatrick uptr stack_top = 0, stack_bottom = 0; 383cab2bb3Spatrick ThreadContext *t; 393cab2bb3Spatrick if (StackTrace::WillUseFastUnwind(request_fast) && 403cab2bb3Spatrick (t = CurrentThreadContext())) { 413cab2bb3Spatrick stack_top = t->stack_end(); 423cab2bb3Spatrick stack_bottom = t->stack_begin(); 433cab2bb3Spatrick } 443cab2bb3Spatrick if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) { 453cab2bb3Spatrick if (StackTrace::WillUseFastUnwind(request_fast)) 463cab2bb3Spatrick Unwind(max_depth, pc, bp, nullptr, stack_top, stack_bottom, true); 473cab2bb3Spatrick else 483cab2bb3Spatrick Unwind(max_depth, pc, 0, context, 0, 0, false); 493cab2bb3Spatrick } 503cab2bb3Spatrick } 513cab2bb3Spatrick 523cab2bb3Spatrick using namespace __lsan; 533cab2bb3Spatrick 543cab2bb3Spatrick static void InitializeFlags() { 553cab2bb3Spatrick // Set all the default values. 563cab2bb3Spatrick SetCommonFlagsDefaults(); 573cab2bb3Spatrick { 583cab2bb3Spatrick CommonFlags cf; 593cab2bb3Spatrick cf.CopyFrom(*common_flags()); 603cab2bb3Spatrick cf.external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH"); 613cab2bb3Spatrick cf.malloc_context_size = 30; 623cab2bb3Spatrick cf.intercept_tls_get_addr = true; 633cab2bb3Spatrick cf.detect_leaks = true; 643cab2bb3Spatrick cf.exitcode = 23; 653cab2bb3Spatrick OverrideCommonFlags(cf); 663cab2bb3Spatrick } 673cab2bb3Spatrick 683cab2bb3Spatrick Flags *f = flags(); 693cab2bb3Spatrick f->SetDefaults(); 703cab2bb3Spatrick 713cab2bb3Spatrick FlagParser parser; 723cab2bb3Spatrick RegisterLsanFlags(&parser, f); 733cab2bb3Spatrick RegisterCommonFlags(&parser); 743cab2bb3Spatrick 753cab2bb3Spatrick // Override from user-specified string. 763cab2bb3Spatrick const char *lsan_default_options = MaybeCallLsanDefaultOptions(); 773cab2bb3Spatrick parser.ParseString(lsan_default_options); 783cab2bb3Spatrick parser.ParseStringFromEnv("LSAN_OPTIONS"); 793cab2bb3Spatrick 803cab2bb3Spatrick SetVerbosity(common_flags()->verbosity); 813cab2bb3Spatrick 823cab2bb3Spatrick if (Verbosity()) ReportUnrecognizedFlags(); 833cab2bb3Spatrick 843cab2bb3Spatrick if (common_flags()->help) parser.PrintFlagDescriptions(); 853cab2bb3Spatrick 863cab2bb3Spatrick __sanitizer_set_report_path(common_flags()->log_path); 873cab2bb3Spatrick } 883cab2bb3Spatrick 893cab2bb3Spatrick extern "C" void __lsan_init() { 903cab2bb3Spatrick CHECK(!lsan_init_is_running); 913cab2bb3Spatrick if (lsan_inited) 923cab2bb3Spatrick return; 933cab2bb3Spatrick lsan_init_is_running = true; 943cab2bb3Spatrick SanitizerToolName = "LeakSanitizer"; 953cab2bb3Spatrick CacheBinaryName(); 963cab2bb3Spatrick AvoidCVE_2016_2143(); 973cab2bb3Spatrick InitializeFlags(); 983cab2bb3Spatrick InitCommonLsan(); 993cab2bb3Spatrick InitializeAllocator(); 1003cab2bb3Spatrick ReplaceSystemMalloc(); 1013cab2bb3Spatrick InitTlsSize(); 1023cab2bb3Spatrick InitializeInterceptors(); 1033cab2bb3Spatrick InitializeThreadRegistry(); 1043cab2bb3Spatrick InstallDeadlySignalHandlers(LsanOnDeadlySignal); 105*1f9cb04fSpatrick InitializeMainThread(); 1063cab2bb3Spatrick 1073cab2bb3Spatrick if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) 1083cab2bb3Spatrick Atexit(DoLeakCheck); 1093cab2bb3Spatrick 1103cab2bb3Spatrick InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir); 1113cab2bb3Spatrick 1123cab2bb3Spatrick lsan_inited = true; 1133cab2bb3Spatrick lsan_init_is_running = false; 1143cab2bb3Spatrick } 1153cab2bb3Spatrick 1163cab2bb3Spatrick extern "C" SANITIZER_INTERFACE_ATTRIBUTE 1173cab2bb3Spatrick void __sanitizer_print_stack_trace() { 1183cab2bb3Spatrick GET_STACK_TRACE_FATAL; 1193cab2bb3Spatrick stack.Print(); 1203cab2bb3Spatrick } 121