[compiler-rt] r229519 - [LSan] Make parent tool responsible for initializing LSan flags.

Alexey Samsonov vonosmas at gmail.com
Tue Feb 17 10:50:30 PST 2015


Author: samsonov
Date: Tue Feb 17 12:50:30 2015
New Revision: 229519

URL: http://llvm.org/viewvc/llvm-project?rev=229519&view=rev
Log:
[LSan] Make parent tool responsible for initializing LSan flags.

Summary:
LSan can be combined with a parent tool (for now it's only ASan).
Also, we allow LSAN_OPTIONS to override certain common flags. It means
we have to parse LSAN_OPTIONS early enough, before the rest of the
parent tool (including chunks of sanitizer_common) is initialized.

In future, we can use the same approach for UBSan, after we embed it
into ASan runtime in a similar way.

Test Plan: regression test suite

Reviewers: earthdok, eugenis

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D7577

Modified:
    compiler-rt/trunk/lib/asan/asan_flags.cc
    compiler-rt/trunk/lib/asan/asan_rtl.cc
    compiler-rt/trunk/lib/lsan/lsan.cc
    compiler-rt/trunk/lib/lsan/lsan_common.cc
    compiler-rt/trunk/lib/lsan/lsan_common.h

Modified: compiler-rt/trunk/lib/asan/asan_flags.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_flags.cc?rev=229519&r1=229518&r2=229519&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_flags.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_flags.cc Tue Feb 17 12:50:30 2015
@@ -54,11 +54,7 @@ static void RegisterAsanFlags(FlagParser
 }
 
 void InitializeFlags() {
-  Flags *f = flags();
-  FlagParser parser;
-  RegisterAsanFlags(&parser, f);
-  RegisterCommonFlags(&parser);
-
+  // Set the default values and prepare for parsing ASan and common flags.
   SetCommonFlagsDefaults();
   {
     CommonFlags cf;
@@ -69,28 +65,44 @@ void InitializeFlags() {
     cf.intercept_tls_get_addr = true;
     OverrideCommonFlags(cf);
   }
-
-  const int kDefaultQuarantineSizeMb = (ASAN_LOW_MEMORY) ? 1UL << 6 : 1UL << 8;
+  Flags *f = flags();
   f->SetDefaults();
 
-  // Override from compile definition.
-  const char *compile_def = MaybeUseAsanDefaultOptionsCompileDefinition();
-  parser.ParseString(compile_def);
+  FlagParser asan_parser;
+  RegisterAsanFlags(&asan_parser, f);
+  RegisterCommonFlags(&asan_parser);
+
+  // Set the default values and prepare for parsing LSan flags (which can also
+  // overwrite common flags).
+#if CAN_SANITIZE_LEAKS
+  __lsan::Flags *lf = __lsan::flags();
+  lf->SetDefaults();
+
+  FlagParser lsan_parser;
+  __lsan::RegisterLsanFlags(&lsan_parser, lf);
+  RegisterCommonFlags(&lsan_parser);
+#endif
+
+  // Override from ASan compile definition.
+  const char *asan_compile_def = MaybeUseAsanDefaultOptionsCompileDefinition();
+  asan_parser.ParseString(asan_compile_def);
 
   // Override from user-specified string.
-  const char *default_options = MaybeCallAsanDefaultOptions();
-  parser.ParseString(default_options);
+  const char *asan_default_options = MaybeCallAsanDefaultOptions();
+  asan_parser.ParseString(asan_default_options);
 
   // Override from command line.
-  const char *env = GetEnv("ASAN_OPTIONS");
-  if (env) parser.ParseString(env);
+  asan_parser.ParseString(GetEnv("ASAN_OPTIONS"));
+#if CAN_SANITIZE_LEAKS
+  lsan_parser.ParseString(GetEnv("LSAN_OPTIONS"));
+#endif
 
   // Let activation flags override current settings. On Android they come
   // from a system property. On other platforms this is no-op.
   if (!flags()->start_deactivated) {
     char buf[100];
     GetExtraActivationFlags(buf, sizeof(buf));
-    parser.ParseString(buf);
+    asan_parser.ParseString(buf);
   }
 
   SetVerbosity(common_flags()->verbosity);
@@ -98,7 +110,10 @@ void InitializeFlags() {
   // TODO(eugenis): dump all flags at verbosity>=2?
   if (Verbosity()) ReportUnrecognizedFlags();
 
-  if (common_flags()->help) parser.PrintFlagDescriptions();
+  if (common_flags()->help) {
+    // TODO(samsonov): print all of the flags (ASan, LSan, common).
+    asan_parser.PrintFlagDescriptions();
+  }
 
   // Flag validation:
   if (!CAN_SANITIZE_LEAKS && common_flags()->detect_leaks) {
@@ -128,8 +143,11 @@ void InitializeFlags() {
   }
   if (f->quarantine_size >= 0)
     f->quarantine_size_mb = f->quarantine_size >> 20;
-  if (f->quarantine_size_mb < 0)
+  if (f->quarantine_size_mb < 0) {
+    const int kDefaultQuarantineSizeMb =
+        (ASAN_LOW_MEMORY) ? 1UL << 6 : 1UL << 8;
     f->quarantine_size_mb = kDefaultQuarantineSizeMb;
+  }
 }
 
 }  // namespace __asan

Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=229519&r1=229518&r2=229519&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Tue Feb 17 12:50:30 2015
@@ -440,7 +440,7 @@ static void AsanInitInternal() {
   SanitizerInitializeUnwinder();
 
 #if CAN_SANITIZE_LEAKS
-  __lsan::InitCommonLsan(false);
+  __lsan::InitCommonLsan();
   if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) {
     Atexit(__lsan::DoLeakCheck);
   }

Modified: compiler-rt/trunk/lib/lsan/lsan.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan.cc?rev=229519&r1=229518&r2=229519&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan.cc (original)
+++ compiler-rt/trunk/lib/lsan/lsan.cc Tue Feb 17 12:50:30 2015
@@ -15,6 +15,7 @@
 #include "lsan.h"
 
 #include "sanitizer_common/sanitizer_flags.h"
+#include "sanitizer_common/sanitizer_flag_parser.h"
 #include "sanitizer_common/sanitizer_stacktrace.h"
 #include "lsan_allocator.h"
 #include "lsan_common.h"
@@ -34,13 +35,42 @@ bool WordIsPoisoned(uptr addr) {
 
 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 = true;
+    OverrideCommonFlags(cf);
+  }
+
+  Flags *f = flags();
+  f->SetDefaults();
+
+  FlagParser parser;
+  RegisterLsanFlags(&parser, f);
+  RegisterCommonFlags(&parser);
+
+  parser.ParseString(GetEnv("LSAN_OPTIONS"));
+
+  SetVerbosity(common_flags()->verbosity);
+
+  if (Verbosity()) ReportUnrecognizedFlags();
+
+  if (common_flags()->help) parser.PrintFlagDescriptions();
+}
+
 extern "C" void __lsan_init() {
   CHECK(!lsan_init_is_running);
   if (lsan_inited)
     return;
   lsan_init_is_running = true;
   SanitizerToolName = "LeakSanitizer";
-  InitCommonLsan(true);
+  InitializeFlags();
+  InitCommonLsan();
   InitializeAllocator();
   InitTlsSize();
   InitializeInterceptors();

Modified: compiler-rt/trunk/lib/lsan/lsan_common.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_common.cc?rev=229519&r1=229518&r2=229519&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan_common.cc (original)
+++ compiler-rt/trunk/lib/lsan/lsan_common.cc Tue Feb 17 12:50:30 2015
@@ -43,46 +43,13 @@ void Flags::SetDefaults() {
 #undef LSAN_FLAG
 }
 
-static void RegisterLsanFlags(FlagParser *parser, Flags *f) {
+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();
-  FlagParser parser;
-  RegisterLsanFlags(&parser, f);
-  RegisterCommonFlags(&parser);
-
-  f->SetDefaults();
-
-  // Set defaults for common flags (only in standalone mode) and parse
-  // them from LSAN_OPTIONS.
-  if (standalone) {
-    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);
-  }
-
-  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(...)                           \
   do {                                              \
     if (flags()->log_pointers) Report(__VA_ARGS__); \
@@ -116,8 +83,7 @@ void InitializeRootRegions() {
   root_regions = new(placeholder) InternalMmapVector<RootRegion>(1);
 }
 
-void InitCommonLsan(bool standalone) {
-  InitializeFlags(standalone);
+void InitCommonLsan() {
   InitializeRootRegions();
   if (common_flags()->detect_leaks) {
     // Initialization which can fail or print warnings should only be done if

Modified: compiler-rt/trunk/lib/lsan/lsan_common.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_common.h?rev=229519&r1=229518&r2=229519&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan_common.h (original)
+++ compiler-rt/trunk/lib/lsan/lsan_common.h Tue Feb 17 12:50:30 2015
@@ -27,6 +27,10 @@
 #define CAN_SANITIZE_LEAKS 0
 #endif
 
+namespace __sanitizer {
+class FlagParser;
+}
+
 namespace __lsan {
 
 // Chunk tags.
@@ -50,6 +54,7 @@ struct Flags {
 
 extern Flags lsan_flags;
 inline Flags *flags() { return &lsan_flags; }
+void RegisterLsanFlags(FlagParser *parser, Flags *f);
 
 struct Leak {
   u32 id;
@@ -105,7 +110,7 @@ enum IgnoreObjectResult {
 };
 
 // Functions called from the parent tool.
-void InitCommonLsan(bool standalone);
+void InitCommonLsan();
 void DoLeakCheck();
 bool DisabledInThisThread();
 





More information about the llvm-commits mailing list