diff options
author | Alexey Samsonov <vonosmas@gmail.com> | 2014-12-19 21:40:04 +0000 |
---|---|---|
committer | Alexey Samsonov <vonosmas@gmail.com> | 2014-12-19 21:40:04 +0000 |
commit | 2682c35c75b78d569293e7653359c18a51aac8fa (patch) | |
tree | 1a73bd55f4d808dcb2b580efdbd14ba4e0245e5b | |
parent | a7d265546807ffc763cb634fe0c1efaa74955ed9 (diff) |
[Sanitizer] Refactor CommonFlags interface. NFC.
Add CommonFlags::SetDefaults() and CommonFlags::ParseFromString(),
so that this object can be easily tested. Enforce
that ParseCommonFlagsFromString() and SetCommonFlagsDefaults()
work only with singleton CommonFlags, shared across all sanitizer
runtimes.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@224617 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/asan/asan_activation.cc | 2 | ||||
-rw-r--r-- | lib/asan/asan_flags.cc | 10 | ||||
-rw-r--r-- | lib/lsan/lsan_common.cc | 4 | ||||
-rw-r--r-- | lib/msan/msan.cc | 10 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_flags.cc | 146 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_flags.h | 15 | ||||
-rw-r--r-- | lib/sanitizer_common/tests/sanitizer_flags_test.cc | 18 | ||||
-rw-r--r-- | lib/tsan/dd/dd_rtl.cc | 4 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_flags.cc | 6 | ||||
-rw-r--r-- | lib/ubsan/ubsan_flags.cc | 6 |
10 files changed, 125 insertions, 96 deletions
diff --git a/lib/asan/asan_activation.cc b/lib/asan/asan_activation.cc index a5fa9c8a3..010cf319b 100644 --- a/lib/asan/asan_activation.cc +++ b/lib/asan/asan_activation.cc @@ -41,7 +41,7 @@ static struct AsanDeactivatedFlags { // contain any other flags. char buf[100]; GetExtraActivationFlags(buf, sizeof(buf)); - ParseCommonFlagsFromString(&cf, buf); + cf.ParseFromString(buf); ParseFlagsFromString(&f, buf); allocator_options.SetFrom(&f, &cf); diff --git a/lib/asan/asan_flags.cc b/lib/asan/asan_flags.cc index c0635dfae..6b0decad0 100644 --- a/lib/asan/asan_flags.cc +++ b/lib/asan/asan_flags.cc @@ -177,7 +177,7 @@ void ParseFlagsFromString(Flags *f, const char *str) { void InitializeFlags(Flags *f) { CommonFlags *cf = common_flags(); - SetCommonFlagsDefaults(cf); + SetCommonFlagsDefaults(); cf->detect_leaks = CAN_SANITIZE_LEAKS; cf->external_symbolizer_path = GetEnv("ASAN_SYMBOLIZER_PATH"); cf->malloc_context_size = kDefaultMallocContextSize; @@ -230,19 +230,19 @@ void InitializeFlags(Flags *f) { // Override from compile definition. const char *compile_def = MaybeUseAsanDefaultOptionsCompileDefinition(); - ParseCommonFlagsFromString(cf, compile_def); + ParseCommonFlagsFromString(compile_def); ParseFlagsFromString(f, compile_def); // Override from user-specified string. const char *default_options = MaybeCallAsanDefaultOptions(); - ParseCommonFlagsFromString(cf, default_options); + ParseCommonFlagsFromString(default_options); ParseFlagsFromString(f, default_options); VReport(1, "Using the defaults from __asan_default_options: %s\n", MaybeCallAsanDefaultOptions()); // Override from command line. if (const char *env = GetEnv("ASAN_OPTIONS")) { - ParseCommonFlagsFromString(cf, env); + ParseCommonFlagsFromString(env); ParseFlagsFromString(f, env); VReport(1, "Parsed ASAN_OPTIONS: %s\n", env); } @@ -252,7 +252,7 @@ void InitializeFlags(Flags *f) { if (!flags()->start_deactivated) { char buf[100]; GetExtraActivationFlags(buf, sizeof(buf)); - ParseCommonFlagsFromString(cf, buf); + ParseCommonFlagsFromString(buf); ParseFlagsFromString(f, buf); if (buf[0] != '\0') VReport(1, "Parsed activation flags: %s\n", buf); diff --git a/lib/lsan/lsan_common.cc b/lib/lsan/lsan_common.cc index c2ba52e46..89fef773b 100644 --- a/lib/lsan/lsan_common.cc +++ b/lib/lsan/lsan_common.cc @@ -76,12 +76,12 @@ static void InitializeFlags(bool standalone) { // them from LSAN_OPTIONS. CommonFlags *cf = common_flags(); if (standalone) { - SetCommonFlagsDefaults(cf); + SetCommonFlagsDefaults(); cf->external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH"); cf->malloc_context_size = 30; cf->detect_leaks = true; } - ParseCommonFlagsFromString(cf, options); + ParseCommonFlagsFromString(options); } #define LOG_POINTERS(...) \ diff --git a/lib/msan/msan.cc b/lib/msan/msan.cc index 853e448fa..fb1829614 100644 --- a/lib/msan/msan.cc +++ b/lib/msan/msan.cc @@ -97,8 +97,6 @@ static uptr StackOriginPC[kNumStackOriginDescrs]; static atomic_uint32_t NumStackOriginDescrs; static void ParseFlagsFromString(Flags *f, const char *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", ""); @@ -147,7 +145,7 @@ static void ParseFlagsFromString(Flags *f, const char *str) { static void InitializeFlags(Flags *f, const char *options) { CommonFlags *cf = common_flags(); - SetCommonFlagsDefaults(cf); + SetCommonFlagsDefaults(); cf->external_symbolizer_path = GetEnv("MSAN_SYMBOLIZER_PATH"); cf->malloc_context_size = 20; cf->handle_ioctl = true; @@ -171,9 +169,13 @@ static void InitializeFlags(Flags *f, const char *options) { f->store_context_size = 20; // Override from user-specified string. - if (__msan_default_options) + if (__msan_default_options) { ParseFlagsFromString(f, __msan_default_options()); + ParseCommonFlagsFromString(__msan_default_options()); + } + ParseFlagsFromString(f, options); + ParseCommonFlagsFromString(options); } void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp, diff --git a/lib/sanitizer_common/sanitizer_flags.cc b/lib/sanitizer_common/sanitizer_flags.cc index 81d57e0f7..c7e8dca48 100644 --- a/lib/sanitizer_common/sanitizer_flags.cc +++ b/lib/sanitizer_common/sanitizer_flags.cc @@ -34,147 +34,147 @@ IntrusiveList<FlagDescription> flag_descriptions; # define SANITIZER_NEEDS_SEGV 1 #endif -void SetCommonFlagsDefaults(CommonFlags *f) { - f->symbolize = true; - f->external_symbolizer_path = 0; - f->allow_addr2line = false; - f->strip_path_prefix = ""; - f->fast_unwind_on_check = false; - f->fast_unwind_on_fatal = false; - f->fast_unwind_on_malloc = true; - f->handle_ioctl = false; - f->malloc_context_size = 1; - f->log_path = "stderr"; - f->verbosity = 0; - f->detect_leaks = true; - f->leak_check_at_exit = true; - f->allocator_may_return_null = false; - f->print_summary = true; - f->check_printf = true; +void CommonFlags::SetDefaults() { + symbolize = true; + external_symbolizer_path = 0; + allow_addr2line = false; + strip_path_prefix = ""; + fast_unwind_on_check = false; + fast_unwind_on_fatal = false; + fast_unwind_on_malloc = true; + handle_ioctl = false; + malloc_context_size = 1; + log_path = "stderr"; + verbosity = 0; + detect_leaks = true; + leak_check_at_exit = true; + allocator_may_return_null = false; + print_summary = true; + check_printf = true; // TODO(glider): tools may want to set different defaults for handle_segv. - f->handle_segv = SANITIZER_NEEDS_SEGV; - f->allow_user_segv_handler = false; - f->use_sigaltstack = true; - f->detect_deadlocks = false; - f->clear_shadow_mmap_threshold = 64 * 1024; - f->color = "auto"; - f->legacy_pthread_cond = false; - f->intercept_tls_get_addr = false; - f->coverage = false; - f->coverage_direct = SANITIZER_ANDROID; - f->coverage_dir = "."; - f->full_address_space = false; - f->suppressions = ""; - f->print_suppressions = true; - f->disable_coredump = (SANITIZER_WORDSIZE == 64); - f->symbolize_inline_frames = true; - f->stack_trace_format = "DEFAULT"; + handle_segv = SANITIZER_NEEDS_SEGV; + allow_user_segv_handler = false; + use_sigaltstack = true; + detect_deadlocks = false; + clear_shadow_mmap_threshold = 64 * 1024; + color = "auto"; + legacy_pthread_cond = false; + intercept_tls_get_addr = false; + coverage = false; + coverage_direct = SANITIZER_ANDROID; + coverage_dir = "."; + full_address_space = false; + suppressions = ""; + print_suppressions = true; + disable_coredump = (SANITIZER_WORDSIZE == 64); + symbolize_inline_frames = true; + stack_trace_format = "DEFAULT"; } -void ParseCommonFlagsFromString(CommonFlags *f, const char *str) { - ParseFlag(str, &f->symbolize, "symbolize", +void CommonFlags::ParseFromString(const char *str) { + ParseFlag(str, &symbolize, "symbolize", "If set, use the online symbolizer from common sanitizer runtime to turn " "virtual addresses to file/line locations."); - ParseFlag(str, &f->external_symbolizer_path, "external_symbolizer_path", + ParseFlag(str, &external_symbolizer_path, "external_symbolizer_path", "Path to external symbolizer. If empty, the tool will search $PATH for " "the symbolizer."); - ParseFlag(str, &f->allow_addr2line, "allow_addr2line", + ParseFlag(str, &allow_addr2line, "allow_addr2line", "If set, allows online symbolizer to run addr2line binary to symbolize " "stack traces (addr2line will only be used if llvm-symbolizer binary is " "unavailable."); - ParseFlag(str, &f->strip_path_prefix, "strip_path_prefix", + ParseFlag(str, &strip_path_prefix, "strip_path_prefix", "Strips this prefix from file paths in error reports."); - ParseFlag(str, &f->fast_unwind_on_check, "fast_unwind_on_check", + ParseFlag(str, &fast_unwind_on_check, "fast_unwind_on_check", "If available, use the fast frame-pointer-based unwinder on " "internal CHECK failures."); - ParseFlag(str, &f->fast_unwind_on_fatal, "fast_unwind_on_fatal", + ParseFlag(str, &fast_unwind_on_fatal, "fast_unwind_on_fatal", "If available, use the fast frame-pointer-based unwinder on fatal " "errors."); - ParseFlag(str, &f->fast_unwind_on_malloc, "fast_unwind_on_malloc", + ParseFlag(str, &fast_unwind_on_malloc, "fast_unwind_on_malloc", "If available, use the fast frame-pointer-based unwinder on " "malloc/free."); - ParseFlag(str, &f->handle_ioctl, "handle_ioctl", + ParseFlag(str, &handle_ioctl, "handle_ioctl", "Intercept and handle ioctl requests."); - ParseFlag(str, &f->malloc_context_size, "malloc_context_size", + ParseFlag(str, &malloc_context_size, "malloc_context_size", "Max number of stack frames kept for each allocation/deallocation."); - ParseFlag(str, &f->log_path, "log_path", + ParseFlag(str, &log_path, "log_path", "Write logs to \"log_path.pid\". The special values are \"stdout\" and " "\"stderr\". The default is \"stderr\"."); - ParseFlag(str, &f->verbosity, "verbosity", + ParseFlag(str, &verbosity, "verbosity", "Verbosity level (0 - silent, 1 - a bit of output, 2+ - more output)."); - ParseFlag(str, &f->detect_leaks, "detect_leaks", + ParseFlag(str, &detect_leaks, "detect_leaks", "Enable memory leak detection."); - ParseFlag(str, &f->leak_check_at_exit, "leak_check_at_exit", + ParseFlag(str, &leak_check_at_exit, "leak_check_at_exit", "Invoke leak checking in an atexit handler. Has no effect if " "detect_leaks=false, or if __lsan_do_leak_check() is called before the " "handler has a chance to run."); - ParseFlag(str, &f->allocator_may_return_null, "allocator_may_return_null", + ParseFlag(str, &allocator_may_return_null, "allocator_may_return_null", "If false, the allocator will crash instead of returning 0 on " "out-of-memory."); - ParseFlag(str, &f->print_summary, "print_summary", + ParseFlag(str, &print_summary, "print_summary", "If false, disable printing error summaries in addition to error " "reports."); - ParseFlag(str, &f->check_printf, "check_printf", + ParseFlag(str, &check_printf, "check_printf", "Check printf arguments."); - ParseFlag(str, &f->handle_segv, "handle_segv", + ParseFlag(str, &handle_segv, "handle_segv", "If set, registers the tool's custom SEGV handler (both SIGBUS and " "SIGSEGV on OSX)."); - ParseFlag(str, &f->allow_user_segv_handler, "allow_user_segv_handler", + ParseFlag(str, &allow_user_segv_handler, "allow_user_segv_handler", "If set, allows user to register a SEGV handler even if the tool " "registers one."); - ParseFlag(str, &f->use_sigaltstack, "use_sigaltstack", + ParseFlag(str, &use_sigaltstack, "use_sigaltstack", "If set, uses alternate stack for signal handling."); - ParseFlag(str, &f->detect_deadlocks, "detect_deadlocks", + ParseFlag(str, &detect_deadlocks, "detect_deadlocks", "If set, deadlock detection is enabled."); - ParseFlag(str, &f->clear_shadow_mmap_threshold, + ParseFlag(str, &clear_shadow_mmap_threshold, "clear_shadow_mmap_threshold", "Large shadow regions are zero-filled using mmap(NORESERVE) instead of " "memset(). This is the threshold size in bytes."); - ParseFlag(str, &f->color, "color", + ParseFlag(str, &color, "color", "Colorize reports: (always|never|auto)."); - ParseFlag(str, &f->legacy_pthread_cond, "legacy_pthread_cond", + ParseFlag(str, &legacy_pthread_cond, "legacy_pthread_cond", "Enables support for dynamic libraries linked with libpthread 2.2.5."); - ParseFlag(str, &f->intercept_tls_get_addr, "intercept_tls_get_addr", + ParseFlag(str, &intercept_tls_get_addr, "intercept_tls_get_addr", "Intercept __tls_get_addr."); - ParseFlag(str, &f->help, "help", "Print the flag descriptions."); - ParseFlag(str, &f->mmap_limit_mb, "mmap_limit_mb", + ParseFlag(str, &help, "help", "Print the flag descriptions."); + ParseFlag(str, &mmap_limit_mb, "mmap_limit_mb", "Limit the amount of mmap-ed memory (excluding shadow) in Mb; " "not a user-facing flag, used mosly for testing the tools"); - ParseFlag(str, &f->hard_rss_limit_mb, "hard_rss_limit_mb", + ParseFlag(str, &hard_rss_limit_mb, "hard_rss_limit_mb", "RSS limit in Mb." " If non-zero, a background thread is spawned at startup" " which periodically reads RSS and aborts the process if the" " limit is reached"); - ParseFlag(str, &f->coverage, "coverage", + ParseFlag(str, &coverage, "coverage", "If set, coverage information will be dumped at program shutdown (if the " "coverage instrumentation was enabled at compile time)."); - ParseFlag(str, &f->coverage_direct, "coverage_direct", + ParseFlag(str, &coverage_direct, "coverage_direct", "If set, coverage information will be dumped directly to a memory " "mapped file. This way data is not lost even if the process is " "suddenly killed."); - ParseFlag(str, &f->coverage_dir, "coverage_dir", + ParseFlag(str, &coverage_dir, "coverage_dir", "Target directory for coverage dumps. Defaults to the current " "directory."); - ParseFlag(str, &f->full_address_space, "full_address_space", + ParseFlag(str, &full_address_space, "full_address_space", "Sanitize complete address space; " "by default kernel area on 32-bit platforms will not be sanitized"); - ParseFlag(str, &f->suppressions, "suppressions", "Suppressions file name."); - ParseFlag(str, &f->print_suppressions, "print_suppressions", + ParseFlag(str, &suppressions, "suppressions", "Suppressions file name."); + ParseFlag(str, &print_suppressions, "print_suppressions", "Print matched suppressions at exit."); - ParseFlag(str, &f->disable_coredump, "disable_coredump", + ParseFlag(str, &disable_coredump, "disable_coredump", "Disable core dumping. By default, disable_core=1 on 64-bit to avoid " "dumping a 16T+ core file. Ignored on OSes that don't dump core by" "default and for sanitizers that don't reserve lots of virtual memory."); - ParseFlag(str, &f->symbolize_inline_frames, "symbolize_inline_frames", + ParseFlag(str, &symbolize_inline_frames, "symbolize_inline_frames", "Print inlined frames in stacktraces. Defaults to true."); - ParseFlag(str, &f->stack_trace_format, "stack_trace_format", + ParseFlag(str, &stack_trace_format, "stack_trace_format", "Format string used to render stack frames. " "See sanitizer_stacktrace_printer.h for the format description. " "Use DEFAULT to get default format."); // Do a sanity check for certain flags. - if (f->malloc_context_size < 1) - f->malloc_context_size = 1; + if (malloc_context_size < 1) + malloc_context_size = 1; } static bool GetFlagValue(const char *env, const char *name, diff --git a/lib/sanitizer_common/sanitizer_flags.h b/lib/sanitizer_common/sanitizer_flags.h index 334635c06..698fc9c3d 100644 --- a/lib/sanitizer_common/sanitizer_flags.h +++ b/lib/sanitizer_common/sanitizer_flags.h @@ -64,15 +64,24 @@ struct CommonFlags { bool disable_coredump; bool symbolize_inline_frames; const char *stack_trace_format; + + void SetDefaults(); + void ParseFromString(const char *str); }; +// Functions to get/set global CommonFlags shared by all sanitizer runtimes: +extern CommonFlags common_flags_dont_use; inline CommonFlags *common_flags() { - extern CommonFlags common_flags_dont_use; return &common_flags_dont_use; } -void SetCommonFlagsDefaults(CommonFlags *f); -void ParseCommonFlagsFromString(CommonFlags *f, const char *str); +inline void SetCommonFlagsDefaults() { + common_flags_dont_use.SetDefaults(); +} + +inline void ParseCommonFlagsFromString(const char *str) { + common_flags_dont_use.ParseFromString(str); +} void PrintFlagDescriptions(); } // namespace __sanitizer diff --git a/lib/sanitizer_common/tests/sanitizer_flags_test.cc b/lib/sanitizer_common/tests/sanitizer_flags_test.cc index 1055f5d24..484ed446e 100644 --- a/lib/sanitizer_common/tests/sanitizer_flags_test.cc +++ b/lib/sanitizer_common/tests/sanitizer_flags_test.cc @@ -83,4 +83,22 @@ TEST(SanitizerCommon, MultipleFlags) { TestTwoFlags("flag2=qxx:flag1=yes", true, "qxx"); } +TEST(SanitizerCommon, CommonFlags) { + CommonFlags cf; + cf.SetDefaults(); + EXPECT_TRUE(cf.symbolize); + EXPECT_STREQ(".", cf.coverage_dir); + + cf.symbolize = false; + cf.coverage = true; + cf.coverage_direct = true; + cf.log_path = "path/one"; + + cf.ParseFromString("symbolize=1:coverage_direct=false log_path='path/two'"); + EXPECT_TRUE(cf.symbolize); + EXPECT_TRUE(cf.coverage); + EXPECT_FALSE(cf.coverage_direct); + EXPECT_STREQ("path/two", cf.log_path); +} + } // namespace __sanitizer diff --git a/lib/tsan/dd/dd_rtl.cc b/lib/tsan/dd/dd_rtl.cc index 41b75bf75..cc8e5a0c4 100644 --- a/lib/tsan/dd/dd_rtl.cc +++ b/lib/tsan/dd/dd_rtl.cc @@ -71,13 +71,13 @@ void InitializeFlags(Flags *f, const char *env) { f->second_deadlock_stack = false; CommonFlags *cf = common_flags(); - SetCommonFlagsDefaults(cf); + SetCommonFlagsDefaults(); // Override some common flags defaults. cf->allow_addr2line = true; // Override from command line. ParseFlag(env, &f->second_deadlock_stack, "second_deadlock_stack", ""); - ParseCommonFlagsFromString(cf, env); + ParseCommonFlagsFromString(env); } void Initialize() { diff --git a/lib/tsan/rtl/tsan_flags.cc b/lib/tsan/rtl/tsan_flags.cc index 5dc331f59..ec74a24b0 100644 --- a/lib/tsan/rtl/tsan_flags.cc +++ b/lib/tsan/rtl/tsan_flags.cc @@ -94,7 +94,7 @@ void InitializeFlags(Flags *f, const char *env) { f->second_deadlock_stack = false; CommonFlags *cf = common_flags(); - SetCommonFlagsDefaults(cf); + SetCommonFlagsDefaults(); // Override some common flags defaults. cf->allow_addr2line = true; cf->detect_deadlocks = true; @@ -103,10 +103,10 @@ void InitializeFlags(Flags *f, const char *env) { // Let a frontend override. ParseFlags(f, __tsan_default_options()); - ParseCommonFlagsFromString(cf, __tsan_default_options()); + ParseCommonFlagsFromString(__tsan_default_options()); // Override from command line. ParseFlags(f, env); - ParseCommonFlagsFromString(cf, env); + ParseCommonFlagsFromString(env); // Sanity check. if (!f->report_bugs) { diff --git a/lib/ubsan/ubsan_flags.cc b/lib/ubsan/ubsan_flags.cc index eda11f1b2..db0e29bb2 100644 --- a/lib/ubsan/ubsan_flags.cc +++ b/lib/ubsan/ubsan_flags.cc @@ -23,12 +23,12 @@ static const char *MaybeCallUbsanDefaultOptions() { void InitializeCommonFlags() { CommonFlags *cf = common_flags(); - SetCommonFlagsDefaults(cf); + SetCommonFlagsDefaults(); cf->print_summary = false; // Override from user-specified string. - ParseCommonFlagsFromString(cf, MaybeCallUbsanDefaultOptions()); + ParseCommonFlagsFromString(MaybeCallUbsanDefaultOptions()); // Override from environment variable. - ParseCommonFlagsFromString(cf, GetEnv("UBSAN_OPTIONS")); + ParseCommonFlagsFromString(GetEnv("UBSAN_OPTIONS")); } Flags ubsan_flags; |