[compiler-rt] r195831 - tsan: fix flags parsing

Dmitry Vyukov dvyukov at google.com
Wed Nov 27 01:54:11 PST 2013


Author: dvyukov
Date: Wed Nov 27 03:54:10 2013
New Revision: 195831

URL: http://llvm.org/viewvc/llvm-project?rev=195831&view=rev
Log:
tsan: fix flags parsing

- running_on_valgrind was not parsed in some contexts
- refactor code a bit
- add comprehensive tests for flags parsing


Modified:
    compiler-rt/trunk/lib/asan/asan_rtl.cc
    compiler-rt/trunk/lib/lsan/lsan.cc
    compiler-rt/trunk/lib/msan/msan.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc
    compiler-rt/trunk/lib/tsan/tests/unit/tsan_flags_test.cc

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=195831&r1=195830&r2=195831&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Wed Nov 27 03:54:10 2013
@@ -88,8 +88,9 @@ static const char *MaybeUseAsanDefaultOp
 }
 
 static void ParseFlagsFromString(Flags *f, const char *str) {
-  ParseCommonFlagsFromString(str);
-  CHECK((uptr)common_flags()->malloc_context_size <= kStackTraceMax);
+  CommonFlags *cf = common_flags();
+  ParseCommonFlagsFromString(cf, str);
+  CHECK((uptr)cf->malloc_context_size <= kStackTraceMax);
 
   ParseFlag(str, &f->quarantine_size, "quarantine_size");
   ParseFlag(str, &f->redzone, "redzone");
@@ -133,7 +134,7 @@ static void ParseFlagsFromString(Flags *
 
 void InitializeFlags(Flags *f, const char *env) {
   CommonFlags *cf = common_flags();
-  SetCommonFlagDefaults();
+  SetCommonFlagsDefaults(cf);
   cf->external_symbolizer_path = GetEnv("ASAN_SYMBOLIZER_PATH");
   cf->malloc_context_size = kDefaultMallocContextSize;
 
@@ -179,7 +180,7 @@ void InitializeFlags(Flags *f, const cha
 
   // Override from user-specified string.
   ParseFlagsFromString(f, MaybeCallAsanDefaultOptions());
-  if (common_flags()->verbosity) {
+  if (cf->verbosity) {
     Report("Using the defaults from __asan_default_options: %s\n",
            MaybeCallAsanDefaultOptions());
   }

Modified: compiler-rt/trunk/lib/lsan/lsan.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan.cc?rev=195831&r1=195830&r2=195831&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan.cc (original)
+++ compiler-rt/trunk/lib/lsan/lsan.cc Wed Nov 27 03:54:10 2013
@@ -27,12 +27,12 @@ namespace __lsan {
 
 static void InitializeCommonFlags() {
   CommonFlags *cf = common_flags();
-  SetCommonFlagDefaults();
+  SetCommonFlagsDefaults(cf);
   cf->external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH");
   cf->malloc_context_size = 30;
   cf->detect_leaks = true;
 
-  ParseCommonFlagsFromString(GetEnv("LSAN_OPTIONS"));
+  ParseCommonFlagsFromString(cf, GetEnv("LSAN_OPTIONS"));
 }
 
 }  // namespace __lsan

Modified: compiler-rt/trunk/lib/msan/msan.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan.cc?rev=195831&r1=195830&r2=195831&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan.cc (original)
+++ compiler-rt/trunk/lib/msan/msan.cc Wed Nov 27 03:54:10 2013
@@ -123,7 +123,8 @@ static uptr StackOriginPC[kNumStackOrigi
 static atomic_uint32_t NumStackOriginDescrs;
 
 static void ParseFlagsFromString(Flags *f, const char *str) {
-  ParseCommonFlagsFromString(str);
+  CommonFlags *cf = common_flags();
+  ParseCommonFlagsFromString(cf, str);
   ParseFlag(str, &f->poison_heap_with_zeroes, "poison_heap_with_zeroes");
   ParseFlag(str, &f->poison_stack_with_zeroes, "poison_stack_with_zeroes");
   ParseFlag(str, &f->poison_in_malloc, "poison_in_malloc");
@@ -146,7 +147,7 @@ static void ParseFlagsFromString(Flags *
 
 static void InitializeFlags(Flags *f, const char *options) {
   CommonFlags *cf = common_flags();
-  SetCommonFlagDefaults();
+  SetCommonFlagsDefaults(cf);
   cf->external_symbolizer_path = GetEnv("MSAN_SYMBOLIZER_PATH");
   cf->malloc_context_size = 20;
   cf->handle_ioctl = true;

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc?rev=195831&r1=195830&r2=195831&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc Wed Nov 27 03:54:10 2013
@@ -18,8 +18,7 @@
 
 namespace __sanitizer {
 
-void SetCommonFlagDefaults() {
-  CommonFlags *f = common_flags();
+void SetCommonFlagsDefaults(CommonFlags *f) {
   f->symbolize = true;
   f->external_symbolizer_path = 0;
   f->strip_path_prefix = "";
@@ -35,8 +34,7 @@ void SetCommonFlagDefaults() {
   f->print_summary = true;
 }
 
-void ParseCommonFlagsFromString(const char *str) {
-  CommonFlags *f = common_flags();
+void ParseCommonFlagsFromString(CommonFlags *f, const char *str) {
   ParseFlag(str, &f->symbolize, "symbolize");
   ParseFlag(str, &f->external_symbolizer_path, "external_symbolizer_path");
   ParseFlag(str, &f->strip_path_prefix, "strip_path_prefix");

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h?rev=195831&r1=195830&r2=195831&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h Wed Nov 27 03:54:10 2013
@@ -61,8 +61,8 @@ inline CommonFlags *common_flags() {
   return &f;
 }
 
-void SetCommonFlagDefaults();
-void ParseCommonFlagsFromString(const char *str);
+void SetCommonFlagsDefaults(CommonFlags *f);
+void ParseCommonFlagsFromString(CommonFlags *f, const char *str);
 
 }  // namespace __sanitizer
 

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc?rev=195831&r1=195830&r2=195831&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc Wed Nov 27 03:54:10 2013
@@ -58,6 +58,7 @@ static void ParseFlags(Flags *f, const c
   ParseFlag(env, &f->flush_symbolizer_ms, "flush_symbolizer_ms");
   ParseFlag(env, &f->memory_limit_mb, "memory_limit_mb");
   ParseFlag(env, &f->stop_on_start, "stop_on_start");
+  ParseFlag(env, &f->running_on_valgrind, "running_on_valgrind");
   ParseFlag(env, &f->history_size, "history_size");
   ParseFlag(env, &f->io_sync, "io_sync");
 }
@@ -91,18 +92,18 @@ void InitializeFlags(Flags *f, const cha
   f->history_size = kGoMode ? 1 : 2;  // There are a lot of goroutines in Go.
   f->io_sync = 1;
 
-  CommonFlags *cf = common_flags();
-  SetCommonFlagDefaults();
-  *static_cast<CommonFlags*>(f) = *cf;
+  SetCommonFlagsDefaults(f);
 
   // Let a frontend override.
   OverrideFlags(f);
   ParseFlags(f, __tsan_default_options());
-  ParseCommonFlagsFromString(__tsan_default_options());
+  ParseCommonFlagsFromString(f, __tsan_default_options());
   // Override from command line.
   ParseFlags(f, env);
-  ParseCommonFlagsFromString(env);
-  *static_cast<CommonFlags*>(f) = *cf;
+  ParseCommonFlagsFromString(f, env);
+
+  // Copy back to common flags.
+  *common_flags() = *f;
 
   // Sanity check.
   if (!f->report_bugs) {

Modified: compiler-rt/trunk/lib/tsan/tests/unit/tsan_flags_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/tests/unit/tsan_flags_test.cc?rev=195831&r1=195830&r2=195831&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/tests/unit/tsan_flags_test.cc (original)
+++ compiler-rt/trunk/lib/tsan/tests/unit/tsan_flags_test.cc Wed Nov 27 03:54:10 2013
@@ -13,6 +13,7 @@
 #include "tsan_flags.h"
 #include "tsan_rtl.h"
 #include "gtest/gtest.h"
+#include <string>
 
 namespace __tsan {
 
@@ -35,4 +36,210 @@ TEST(Flags, DefaultValues) {
   EXPECT_EQ(true, f.enable_annotations);
 }
 
+static const char *options1 =
+  " enable_annotations=0"
+  " suppress_equal_stacks=0"
+  " suppress_equal_addresses=0"
+  " suppress_java=0"
+  " report_bugs=0"
+  " report_thread_leaks=0"
+  " report_destroy_locked=0"
+  " report_signal_unsafe=0"
+  " report_atomic_races=0"
+  " force_seq_cst_atomics=0"
+  " suppressions=qwerty"
+  " print_suppressions=0"
+  " print_benign=0"
+  " exitcode=111"
+  " halt_on_error=0"
+  " atexit_sleep_ms=222"
+  " profile_memory=qqq"
+  " flush_memory_ms=444"
+  " flush_symbolizer_ms=555"
+  " memory_limit_mb=666"
+  " stop_on_start=0"
+  " running_on_valgrind=0"
+  " history_size=5"
+  " io_sync=1"
+
+  " symbolize=0"
+  " external_symbolizer_path=asdfgh"
+  " strip_path_prefix=zxcvb"
+  " fast_unwind_on_fatal=0"
+  " fast_unwind_on_malloc=0"
+  " handle_ioctl=0"
+  " malloc_context_size=777"
+  " log_path=aaa"
+  " verbosity=2"
+  " detect_leaks=0"
+  " leak_check_at_exit=0"
+  " allocator_may_return_null=0"
+  " print_summary=0"
+  "";
+
+static const char *options2 =
+  " enable_annotations=true"
+  " suppress_equal_stacks=true"
+  " suppress_equal_addresses=true"
+  " suppress_java=true"
+  " report_bugs=true"
+  " report_thread_leaks=true"
+  " report_destroy_locked=true"
+  " report_signal_unsafe=true"
+  " report_atomic_races=true"
+  " force_seq_cst_atomics=true"
+  " suppressions=aaaaa"
+  " print_suppressions=true"
+  " print_benign=true"
+  " exitcode=222"
+  " halt_on_error=true"
+  " atexit_sleep_ms=123"
+  " profile_memory=bbbbb"
+  " flush_memory_ms=234"
+  " flush_symbolizer_ms=345"
+  " memory_limit_mb=456"
+  " stop_on_start=true"
+  " running_on_valgrind=true"
+  " history_size=6"
+  " io_sync=2"
+
+  " symbolize=true"
+  " external_symbolizer_path=cccccc"
+  " strip_path_prefix=ddddddd"
+  " fast_unwind_on_fatal=true"
+  " fast_unwind_on_malloc=true"
+  " handle_ioctl=true"
+  " malloc_context_size=567"
+  " log_path=eeeeeee"
+  " verbosity=3"
+  " detect_leaks=true"
+  " leak_check_at_exit=true"
+  " allocator_may_return_null=true"
+  " print_summary=true"
+  "";
+
+void VerifyOptions1(Flags *f) {
+  EXPECT_EQ(f->enable_annotations, 0);
+  EXPECT_EQ(f->suppress_equal_stacks, 0);
+  EXPECT_EQ(f->suppress_equal_addresses, 0);
+  EXPECT_EQ(f->suppress_java, 0);
+  EXPECT_EQ(f->report_bugs, 0);
+  EXPECT_EQ(f->report_thread_leaks, 0);
+  EXPECT_EQ(f->report_destroy_locked, 0);
+  EXPECT_EQ(f->report_signal_unsafe, 0);
+  EXPECT_EQ(f->report_atomic_races, 0);
+  EXPECT_EQ(f->force_seq_cst_atomics, 0);
+  EXPECT_EQ(f->suppressions, std::string("qwerty"));
+  EXPECT_EQ(f->print_suppressions, 0);
+  EXPECT_EQ(f->print_benign, 0);
+  EXPECT_EQ(f->exitcode, 111);
+  EXPECT_EQ(f->halt_on_error, 0);
+  EXPECT_EQ(f->atexit_sleep_ms, 222);
+  EXPECT_EQ(f->profile_memory, std::string("qqq"));
+  EXPECT_EQ(f->flush_memory_ms, 444);
+  EXPECT_EQ(f->flush_symbolizer_ms, 555);
+  EXPECT_EQ(f->memory_limit_mb, 666);
+  EXPECT_EQ(f->stop_on_start, 0);
+  EXPECT_EQ(f->running_on_valgrind, 0);
+  EXPECT_EQ(f->history_size, 5);
+  EXPECT_EQ(f->io_sync, 1);
+
+  EXPECT_EQ(f->symbolize, 0);
+  EXPECT_EQ(f->external_symbolizer_path, std::string("asdfgh"));
+  EXPECT_EQ(f->strip_path_prefix, std::string("zxcvb"));
+  EXPECT_EQ(f->fast_unwind_on_fatal, 0);
+  EXPECT_EQ(f->fast_unwind_on_malloc, 0);
+  EXPECT_EQ(f->handle_ioctl, 0);
+  EXPECT_EQ(f->malloc_context_size, 777);
+  EXPECT_EQ(f->log_path, std::string("aaa"));
+  EXPECT_EQ(f->verbosity, 2);
+  EXPECT_EQ(f->detect_leaks, 0);
+  EXPECT_EQ(f->leak_check_at_exit, 0);
+  EXPECT_EQ(f->allocator_may_return_null, 0);
+  EXPECT_EQ(f->print_summary, 0);
+}
+
+void VerifyOptions2(Flags *f) {
+  EXPECT_EQ(f->enable_annotations, true);
+  EXPECT_EQ(f->suppress_equal_stacks, true);
+  EXPECT_EQ(f->suppress_equal_addresses, true);
+  EXPECT_EQ(f->suppress_java, true);
+  EXPECT_EQ(f->report_bugs, true);
+  EXPECT_EQ(f->report_thread_leaks, true);
+  EXPECT_EQ(f->report_destroy_locked, true);
+  EXPECT_EQ(f->report_signal_unsafe, true);
+  EXPECT_EQ(f->report_atomic_races, true);
+  EXPECT_EQ(f->force_seq_cst_atomics, true);
+  EXPECT_EQ(f->suppressions, std::string("aaaaa"));
+  EXPECT_EQ(f->print_suppressions, true);
+  EXPECT_EQ(f->print_benign, true);
+  EXPECT_EQ(f->exitcode, 222);
+  EXPECT_EQ(f->halt_on_error, true);
+  EXPECT_EQ(f->atexit_sleep_ms, 123);
+  EXPECT_EQ(f->profile_memory, std::string("bbbbb"));
+  EXPECT_EQ(f->flush_memory_ms, 234);
+  EXPECT_EQ(f->flush_symbolizer_ms, 345);
+  EXPECT_EQ(f->memory_limit_mb, 456);
+  EXPECT_EQ(f->stop_on_start, true);
+  EXPECT_EQ(f->running_on_valgrind, true);
+  EXPECT_EQ(f->history_size, 6);
+  EXPECT_EQ(f->io_sync, 2);
+
+  EXPECT_EQ(f->symbolize, true);
+  EXPECT_EQ(f->external_symbolizer_path, std::string("cccccc"));
+  EXPECT_EQ(f->strip_path_prefix, std::string("ddddddd"));
+  EXPECT_EQ(f->fast_unwind_on_fatal, true);
+  EXPECT_EQ(f->fast_unwind_on_malloc, true);
+  EXPECT_EQ(f->handle_ioctl, true);
+  EXPECT_EQ(f->malloc_context_size, 567);
+  EXPECT_EQ(f->log_path, std::string("eeeeeee"));
+  EXPECT_EQ(f->verbosity, 3);
+  EXPECT_EQ(f->detect_leaks, true);
+  EXPECT_EQ(f->leak_check_at_exit, true);
+  EXPECT_EQ(f->allocator_may_return_null, true);
+  EXPECT_EQ(f->print_summary, true);
+}
+
+static const char *test_default_options;
+extern "C" const char *__tsan_default_options() {
+  return test_default_options;
+}
+
+TEST(Flags, ParseDefaultOptions) {
+  ScopedInRtl in_rtl;
+  Flags f;
+
+  test_default_options = options1;
+  InitializeFlags(&f, "");
+  VerifyOptions1(&f);
+
+  test_default_options = options2;
+  InitializeFlags(&f, "");
+  VerifyOptions2(&f);
+}
+
+TEST(Flags, ParseEnvOptions) {
+  ScopedInRtl in_rtl;
+  Flags f;
+
+  InitializeFlags(&f, options1);
+  VerifyOptions1(&f);
+
+  InitializeFlags(&f, options2);
+  VerifyOptions2(&f);
+}
+
+TEST(Flags, ParsePriority) {
+  ScopedInRtl in_rtl;
+  Flags f;
+
+  test_default_options = options2;
+  InitializeFlags(&f, options1);
+  VerifyOptions1(&f);
+
+  test_default_options = options1;
+  InitializeFlags(&f, options2);
+  VerifyOptions2(&f);
+}
+
 }  // namespace __tsan





More information about the llvm-commits mailing list