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