| //===-- tsan_flags_test.cc ------------------------------------------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file is a part of ThreadSanitizer (TSan), a race detector. |
| // |
| //===----------------------------------------------------------------------===// |
| #include "tsan_flags.h" |
| #include "tsan_rtl.h" |
| #include "gtest/gtest.h" |
| #include <string> |
| |
| namespace __tsan { |
| |
| TEST(Flags, Basic) { |
| // At least should not crash. |
| Flags f; |
| InitializeFlags(&f, 0); |
| InitializeFlags(&f, ""); |
| } |
| |
| TEST(Flags, DefaultValues) { |
| Flags f; |
| |
| f.enable_annotations = false; |
| InitializeFlags(&f, ""); |
| EXPECT_EQ(true, f.enable_annotations); |
| } |
| |
| static const char *options1 = |
| " enable_annotations=0" |
| " suppress_equal_stacks=0" |
| " suppress_equal_addresses=0" |
| " report_bugs=0" |
| " report_thread_leaks=0" |
| " report_destroy_locked=0" |
| " report_mutex_bugs=0" |
| " report_signal_unsafe=0" |
| " report_atomic_races=0" |
| " force_seq_cst_atomics=0" |
| " print_benign=0" |
| " 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" |
| " die_after_fork=true" |
| ""; |
| |
| static const char *options2 = |
| " enable_annotations=true" |
| " suppress_equal_stacks=true" |
| " suppress_equal_addresses=true" |
| " report_bugs=true" |
| " report_thread_leaks=true" |
| " report_destroy_locked=true" |
| " report_mutex_bugs=true" |
| " report_signal_unsafe=true" |
| " report_atomic_races=true" |
| " force_seq_cst_atomics=true" |
| " print_benign=true" |
| " 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" |
| " die_after_fork=false" |
| ""; |
| |
| 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->report_bugs, 0); |
| EXPECT_EQ(f->report_thread_leaks, 0); |
| EXPECT_EQ(f->report_destroy_locked, 0); |
| EXPECT_EQ(f->report_mutex_bugs, 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->print_benign, 0); |
| 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->die_after_fork, true); |
| } |
| |
| 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->report_bugs, true); |
| EXPECT_EQ(f->report_thread_leaks, true); |
| EXPECT_EQ(f->report_destroy_locked, true); |
| EXPECT_EQ(f->report_mutex_bugs, 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->print_benign, true); |
| 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->die_after_fork, false); |
| } |
| |
| static const char *test_default_options; |
| extern "C" const char *__tsan_default_options() { |
| return test_default_options; |
| } |
| |
| TEST(Flags, ParseDefaultOptions) { |
| Flags f; |
| |
| test_default_options = options1; |
| InitializeFlags(&f, ""); |
| VerifyOptions1(&f); |
| |
| test_default_options = options2; |
| InitializeFlags(&f, ""); |
| VerifyOptions2(&f); |
| } |
| |
| TEST(Flags, ParseEnvOptions) { |
| Flags f; |
| |
| InitializeFlags(&f, options1); |
| VerifyOptions1(&f); |
| |
| InitializeFlags(&f, options2); |
| VerifyOptions2(&f); |
| } |
| |
| TEST(Flags, ParsePriority) { |
| Flags f; |
| |
| test_default_options = options2; |
| InitializeFlags(&f, options1); |
| VerifyOptions1(&f); |
| |
| test_default_options = options1; |
| InitializeFlags(&f, options2); |
| VerifyOptions2(&f); |
| } |
| |
| } // namespace __tsan |