forked from OSchip/llvm-project
tsan: fix flags parsing
- running_on_valgrind was not parsed in some contexts - refactor code a bit - add comprehensive tests for flags parsing llvm-svn: 195831
This commit is contained in:
parent
ee882ba4a1
commit
7bd319cc08
|
@ -88,8 +88,9 @@ static const char *MaybeUseAsanDefaultOptionsCompileDefiniton() {
|
|||
}
|
||||
|
||||
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 *f, const char *str) {
|
|||
|
||||
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 char *env) {
|
|||
|
||||
// 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());
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -123,7 +123,8 @@ static uptr StackOriginPC[kNumStackOriginDescrs];
|
|||
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 *f, const char *str) {
|
|||
|
||||
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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ static void ParseFlags(Flags *f, const char *env) {
|
|||
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 char *env) {
|
|||
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) {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue