1 //===-- tsan_flags_test.cpp -----------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file is a part of ThreadSanitizer (TSan), a race detector. 10 // 11 //===----------------------------------------------------------------------===// 12 #include "tsan_flags.h" 13 #include "tsan_rtl.h" 14 #include "gtest/gtest.h" 15 #include <string> 16 17 namespace __tsan { 18 19 TEST(Flags, Basic) { 20 // At least should not crash. 21 Flags f; 22 InitializeFlags(&f, 0); 23 InitializeFlags(&f, ""); 24 } 25 26 TEST(Flags, DefaultValues) { 27 Flags f; 28 29 f.enable_annotations = false; 30 InitializeFlags(&f, ""); 31 EXPECT_EQ(true, f.enable_annotations); 32 } 33 34 static const char *options1 = 35 " enable_annotations=0" 36 " suppress_equal_stacks=0" 37 " suppress_equal_addresses=0" 38 " report_bugs=0" 39 " report_thread_leaks=0" 40 " report_destroy_locked=0" 41 " report_mutex_bugs=0" 42 " report_signal_unsafe=0" 43 " report_atomic_races=0" 44 " force_seq_cst_atomics=0" 45 " halt_on_error=0" 46 " atexit_sleep_ms=222" 47 " profile_memory=qqq" 48 " flush_memory_ms=444" 49 " flush_symbolizer_ms=555" 50 " memory_limit_mb=666" 51 " stop_on_start=0" 52 " running_on_valgrind=0" 53 " history_size=5" 54 " io_sync=1" 55 " die_after_fork=true" 56 ""; 57 58 static const char *options2 = 59 " enable_annotations=true" 60 " suppress_equal_stacks=true" 61 " suppress_equal_addresses=true" 62 " report_bugs=true" 63 " report_thread_leaks=true" 64 " report_destroy_locked=true" 65 " report_mutex_bugs=true" 66 " report_signal_unsafe=true" 67 " report_atomic_races=true" 68 " force_seq_cst_atomics=true" 69 " halt_on_error=true" 70 " atexit_sleep_ms=123" 71 " profile_memory=bbbbb" 72 " flush_memory_ms=234" 73 " flush_symbolizer_ms=345" 74 " memory_limit_mb=456" 75 " stop_on_start=true" 76 " running_on_valgrind=true" 77 " history_size=6" 78 " io_sync=2" 79 " die_after_fork=false" 80 ""; 81 82 void VerifyOptions1(Flags *f) { 83 EXPECT_EQ(f->enable_annotations, 0); 84 EXPECT_EQ(f->suppress_equal_stacks, 0); 85 EXPECT_EQ(f->suppress_equal_addresses, 0); 86 EXPECT_EQ(f->report_bugs, 0); 87 EXPECT_EQ(f->report_thread_leaks, 0); 88 EXPECT_EQ(f->report_destroy_locked, 0); 89 EXPECT_EQ(f->report_mutex_bugs, 0); 90 EXPECT_EQ(f->report_signal_unsafe, 0); 91 EXPECT_EQ(f->report_atomic_races, 0); 92 EXPECT_EQ(f->force_seq_cst_atomics, 0); 93 EXPECT_EQ(f->halt_on_error, 0); 94 EXPECT_EQ(f->atexit_sleep_ms, 222); 95 EXPECT_EQ(f->profile_memory, std::string("qqq")); 96 EXPECT_EQ(f->flush_memory_ms, 444); 97 EXPECT_EQ(f->flush_symbolizer_ms, 555); 98 EXPECT_EQ(f->memory_limit_mb, 666); 99 EXPECT_EQ(f->stop_on_start, 0); 100 EXPECT_EQ(f->running_on_valgrind, 0); 101 EXPECT_EQ(f->history_size, (uptr)5); 102 EXPECT_EQ(f->io_sync, 1); 103 EXPECT_EQ(f->die_after_fork, true); 104 } 105 106 void VerifyOptions2(Flags *f) { 107 EXPECT_EQ(f->enable_annotations, true); 108 EXPECT_EQ(f->suppress_equal_stacks, true); 109 EXPECT_EQ(f->suppress_equal_addresses, true); 110 EXPECT_EQ(f->report_bugs, true); 111 EXPECT_EQ(f->report_thread_leaks, true); 112 EXPECT_EQ(f->report_destroy_locked, true); 113 EXPECT_EQ(f->report_mutex_bugs, true); 114 EXPECT_EQ(f->report_signal_unsafe, true); 115 EXPECT_EQ(f->report_atomic_races, true); 116 EXPECT_EQ(f->force_seq_cst_atomics, true); 117 EXPECT_EQ(f->halt_on_error, true); 118 EXPECT_EQ(f->atexit_sleep_ms, 123); 119 EXPECT_EQ(f->profile_memory, std::string("bbbbb")); 120 EXPECT_EQ(f->flush_memory_ms, 234); 121 EXPECT_EQ(f->flush_symbolizer_ms, 345); 122 EXPECT_EQ(f->memory_limit_mb, 456); 123 EXPECT_EQ(f->stop_on_start, true); 124 EXPECT_EQ(f->running_on_valgrind, true); 125 EXPECT_EQ(f->history_size, 6ul); 126 EXPECT_EQ(f->io_sync, 2); 127 EXPECT_EQ(f->die_after_fork, false); 128 } 129 130 static const char *test_default_options; 131 extern "C" const char *__tsan_default_options() { 132 return test_default_options; 133 } 134 135 TEST(Flags, ParseDefaultOptions) { 136 Flags f; 137 138 test_default_options = options1; 139 InitializeFlags(&f, ""); 140 VerifyOptions1(&f); 141 142 test_default_options = options2; 143 InitializeFlags(&f, ""); 144 VerifyOptions2(&f); 145 } 146 147 TEST(Flags, ParseEnvOptions) { 148 Flags f; 149 150 InitializeFlags(&f, options1); 151 VerifyOptions1(&f); 152 153 InitializeFlags(&f, options2); 154 VerifyOptions2(&f); 155 } 156 157 TEST(Flags, ParsePriority) { 158 Flags f; 159 160 test_default_options = options2; 161 InitializeFlags(&f, options1); 162 VerifyOptions1(&f); 163 164 test_default_options = options1; 165 InitializeFlags(&f, options2); 166 VerifyOptions2(&f); 167 } 168 169 } // namespace __tsan 170