diff options
Diffstat (limited to 'lib/lsan')
-rw-r--r-- | lib/lsan/lsan.cc | 3 | ||||
-rw-r--r-- | lib/lsan/lsan_allocator.cc | 2 | ||||
-rw-r--r-- | lib/lsan/lsan_common.cc | 77 | ||||
-rw-r--r-- | lib/lsan/lsan_common.h | 36 | ||||
-rw-r--r-- | lib/lsan/lsan_flags.inc | 44 |
5 files changed, 91 insertions, 71 deletions
diff --git a/lib/lsan/lsan.cc b/lib/lsan/lsan.cc index 1598fcac4a764..1509b2a7d342a 100644 --- a/lib/lsan/lsan.cc +++ b/lib/lsan/lsan.cc @@ -52,6 +52,9 @@ extern "C" void __lsan_init() { 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; } diff --git a/lib/lsan/lsan_allocator.cc b/lib/lsan/lsan_allocator.cc index 8be2a2ad92245..96a2b0428a612 100644 --- a/lib/lsan/lsan_allocator.cc +++ b/lib/lsan/lsan_allocator.cc @@ -47,7 +47,7 @@ static Allocator allocator; static THREADLOCAL AllocatorCache cache; void InitializeAllocator() { - allocator.Init(); + allocator.InitLinkerInitialized(common_flags()->allocator_may_return_null); } void AllocatorThreadFinish() { diff --git a/lib/lsan/lsan_common.cc b/lib/lsan/lsan_common.cc index c2ba52e46911c..7b3cd16397613 100644 --- a/lib/lsan/lsan_common.cc +++ b/lib/lsan/lsan_common.cc @@ -16,6 +16,7 @@ #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_flags.h" +#include "sanitizer_common/sanitizer_flag_parser.h" #include "sanitizer_common/sanitizer_placement_new.h" #include "sanitizer_common/sanitizer_procmaps.h" #include "sanitizer_common/sanitizer_stackdepot.h" @@ -36,52 +37,50 @@ bool DisabledInThisThread() { return disable_counter > 0; } Flags lsan_flags; +void Flags::SetDefaults() { +#define LSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; +#include "lsan_flags.inc" +#undef LSAN_FLAG +} + +static void RegisterLsanFlags(FlagParser *parser, Flags *f) { +#define LSAN_FLAG(Type, Name, DefaultValue, Description) \ + RegisterFlag(parser, #Name, Description, &f->Name); +#include "lsan_flags.inc" +#undef LSAN_FLAG +} + static void InitializeFlags(bool standalone) { Flags *f = flags(); - // Default values. - f->report_objects = false; - f->resolution = 0; - f->max_leaks = 0; - f->exitcode = 23; - f->use_registers = true; - f->use_globals = true; - f->use_stacks = true; - f->use_tls = true; - f->use_root_regions = true; - f->use_unaligned = false; - f->use_poisoned = false; - f->log_pointers = false; - f->log_threads = false; + FlagParser parser; + RegisterLsanFlags(&parser, f); + RegisterCommonFlags(&parser); - const char *options = GetEnv("LSAN_OPTIONS"); - if (options) { - ParseFlag(options, &f->use_registers, "use_registers", ""); - ParseFlag(options, &f->use_globals, "use_globals", ""); - ParseFlag(options, &f->use_stacks, "use_stacks", ""); - ParseFlag(options, &f->use_tls, "use_tls", ""); - ParseFlag(options, &f->use_root_regions, "use_root_regions", ""); - ParseFlag(options, &f->use_unaligned, "use_unaligned", ""); - ParseFlag(options, &f->use_poisoned, "use_poisoned", ""); - ParseFlag(options, &f->report_objects, "report_objects", ""); - ParseFlag(options, &f->resolution, "resolution", ""); - CHECK_GE(&f->resolution, 0); - ParseFlag(options, &f->max_leaks, "max_leaks", ""); - CHECK_GE(&f->max_leaks, 0); - ParseFlag(options, &f->log_pointers, "log_pointers", ""); - ParseFlag(options, &f->log_threads, "log_threads", ""); - ParseFlag(options, &f->exitcode, "exitcode", ""); - } + f->SetDefaults(); // Set defaults for common flags (only in standalone mode) and parse // them from LSAN_OPTIONS. - CommonFlags *cf = common_flags(); if (standalone) { - SetCommonFlagsDefaults(cf); - cf->external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH"); - cf->malloc_context_size = 30; - cf->detect_leaks = true; + SetCommonFlagsDefaults(); + CommonFlags cf; + cf.CopyFrom(*common_flags()); + cf.external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH"); + cf.malloc_context_size = 30; + cf.detect_leaks = true; + OverrideCommonFlags(cf); } - ParseCommonFlagsFromString(cf, options); + + bool help_before = common_flags()->help; + + const char *options = GetEnv("LSAN_OPTIONS"); + parser.ParseString(options); + + SetVerbosity(common_flags()->verbosity); + + if (Verbosity()) ReportUnrecognizedFlags(); + + if (!help_before && common_flags()->help) + parser.PrintFlagDescriptions(); } #define LOG_POINTERS(...) \ @@ -367,7 +366,7 @@ static void CollectLeaksCb(uptr chunk, void *arg) { LsanMetadata m(chunk); if (!m.allocated()) return; if (m.tag() == kDirectlyLeaked || m.tag() == kIndirectlyLeaked) { - uptr resolution = flags()->resolution; + u32 resolution = flags()->resolution; u32 stack_trace_id = 0; if (resolution > 0) { StackTrace stack = StackDepotGet(m.stack_trace_id()); diff --git a/lib/lsan/lsan_common.h b/lib/lsan/lsan_common.h index 86ff12da6e0fb..64cbef38c7a68 100644 --- a/lib/lsan/lsan_common.h +++ b/lib/lsan/lsan_common.h @@ -38,40 +38,14 @@ enum ChunkTag { }; struct Flags { +#define LSAN_FLAG(Type, Name, DefaultValue, Description) Type Name; +#include "lsan_flags.inc" +#undef LSAN_FLAG + + void SetDefaults(); uptr pointer_alignment() const { return use_unaligned ? 1 : sizeof(uptr); } - - // Print addresses of leaked objects after main leak report. - bool report_objects; - // Aggregate two objects into one leak if this many stack frames match. If - // zero, the entire stack trace must match. - int resolution; - // The number of leaks reported. - int max_leaks; - // If nonzero kill the process with this exit code upon finding leaks. - int exitcode; - - // Flags controlling the root set of reachable memory. - // Global variables (.data and .bss). - bool use_globals; - // Thread stacks. - bool use_stacks; - // Thread registers. - bool use_registers; - // TLS and thread-specific storage. - bool use_tls; - // Regions added via __lsan_register_root_region(). - bool use_root_regions; - - // Consider unaligned pointers valid. - bool use_unaligned; - // Consider pointers found in poisoned memory to be valid. - bool use_poisoned; - - // Debug logging. - bool log_pointers; - bool log_threads; }; extern Flags lsan_flags; diff --git a/lib/lsan/lsan_flags.inc b/lib/lsan/lsan_flags.inc new file mode 100644 index 0000000000000..7f00acbf91194 --- /dev/null +++ b/lib/lsan/lsan_flags.inc @@ -0,0 +1,44 @@ +//===-- lsan_flags.inc ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// LSan runtime flags. +// +//===----------------------------------------------------------------------===// +#ifndef LSAN_FLAG +# error "Define LSAN_FLAG prior to including this file!" +#endif + +// LSAN_FLAG(Type, Name, DefaultValue, Description) +// See COMMON_FLAG in sanitizer_flags.inc for more details. + +LSAN_FLAG(bool, report_objects, false, + "Print addresses of leaked objects after main leak report.") +LSAN_FLAG( + int, resolution, 0, + "Aggregate two objects into one leak if this many stack frames match. If " + "zero, the entire stack trace must match.") +LSAN_FLAG(int, max_leaks, 0, "The number of leaks reported.") +LSAN_FLAG(int, exitcode, 23, + "If nonzero kill the process with this exit code upon finding leaks.") + +// Flags controlling the root set of reachable memory. +LSAN_FLAG(bool, use_globals, true, + "Root set: include global variables (.data and .bss)") +LSAN_FLAG(bool, use_stacks, true, "Root set: include thread stacks") +LSAN_FLAG(bool, use_registers, true, "Root set: include thread registers") +LSAN_FLAG(bool, use_tls, true, + "Root set: include TLS and thread-specific storage") +LSAN_FLAG(bool, use_root_regions, true, + "Root set: include regions added via __lsan_register_root_region().") + +LSAN_FLAG(bool, use_unaligned, false, "Consider unaligned pointers valid.") +LSAN_FLAG(bool, use_poisoned, false, + "Consider pointers found in poisoned memory to be valid.") +LSAN_FLAG(bool, log_pointers, false, "Debug logging") +LSAN_FLAG(bool, log_threads, false, "Debug logging") |