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
17namespace __tsan {
18
19TEST(Flags, Basic) {
20  // At least should not crash.
21  Flags f;
22  InitializeFlags(&f, 0);
23  InitializeFlags(&f, "");
24}
25
26TEST(Flags, DefaultValues) {
27  Flags f;
28
29  f.enable_annotations = false;
30  InitializeFlags(&f, "");
31  EXPECT_EQ(true, f.enable_annotations);
32}
33
34static const char *options1 =
35  " enable_annotations=0"
36  " suppress_equal_stacks=0"
37  " report_bugs=0"
38  " report_thread_leaks=0"
39  " report_destroy_locked=0"
40  " report_mutex_bugs=0"
41  " report_signal_unsafe=0"
42  " report_atomic_races=0"
43  " force_seq_cst_atomics=0"
44  " halt_on_error=0"
45  " atexit_sleep_ms=222"
46  " profile_memory=qqq"
47  " flush_memory_ms=444"
48  " flush_symbolizer_ms=555"
49  " memory_limit_mb=666"
50  " stop_on_start=0"
51  " running_on_valgrind=0"
52  " history_size=5"
53  " io_sync=1"
54  " die_after_fork=true"
55  "";
56
57static const char *options2 =
58  " enable_annotations=true"
59  " suppress_equal_stacks=true"
60  " report_bugs=true"
61  " report_thread_leaks=true"
62  " report_destroy_locked=true"
63  " report_mutex_bugs=true"
64  " report_signal_unsafe=true"
65  " report_atomic_races=true"
66  " force_seq_cst_atomics=true"
67  " halt_on_error=true"
68  " atexit_sleep_ms=123"
69  " profile_memory=bbbbb"
70  " flush_memory_ms=234"
71  " flush_symbolizer_ms=345"
72  " memory_limit_mb=456"
73  " stop_on_start=true"
74  " running_on_valgrind=true"
75  " history_size=6"
76  " io_sync=2"
77  " die_after_fork=false"
78  "";
79
80void VerifyOptions1(Flags *f) {
81  EXPECT_EQ(f->enable_annotations, 0);
82  EXPECT_EQ(f->suppress_equal_stacks, 0);
83  EXPECT_EQ(f->report_bugs, 0);
84  EXPECT_EQ(f->report_thread_leaks, 0);
85  EXPECT_EQ(f->report_destroy_locked, 0);
86  EXPECT_EQ(f->report_mutex_bugs, 0);
87  EXPECT_EQ(f->report_signal_unsafe, 0);
88  EXPECT_EQ(f->report_atomic_races, 0);
89  EXPECT_EQ(f->force_seq_cst_atomics, 0);
90  EXPECT_EQ(f->halt_on_error, 0);
91  EXPECT_EQ(f->atexit_sleep_ms, 222);
92  EXPECT_EQ(f->profile_memory, std::string("qqq"));
93  EXPECT_EQ(f->flush_memory_ms, 444);
94  EXPECT_EQ(f->flush_symbolizer_ms, 555);
95  EXPECT_EQ(f->memory_limit_mb, 666);
96  EXPECT_EQ(f->stop_on_start, 0);
97  EXPECT_EQ(f->running_on_valgrind, 0);
98  EXPECT_EQ(f->history_size, (uptr)5);
99  EXPECT_EQ(f->io_sync, 1);
100  EXPECT_EQ(f->die_after_fork, true);
101}
102
103void VerifyOptions2(Flags *f) {
104  EXPECT_EQ(f->enable_annotations, true);
105  EXPECT_EQ(f->suppress_equal_stacks, true);
106  EXPECT_EQ(f->report_bugs, true);
107  EXPECT_EQ(f->report_thread_leaks, true);
108  EXPECT_EQ(f->report_destroy_locked, true);
109  EXPECT_EQ(f->report_mutex_bugs, true);
110  EXPECT_EQ(f->report_signal_unsafe, true);
111  EXPECT_EQ(f->report_atomic_races, true);
112  EXPECT_EQ(f->force_seq_cst_atomics, true);
113  EXPECT_EQ(f->halt_on_error, true);
114  EXPECT_EQ(f->atexit_sleep_ms, 123);
115  EXPECT_EQ(f->profile_memory, std::string("bbbbb"));
116  EXPECT_EQ(f->flush_memory_ms, 234);
117  EXPECT_EQ(f->flush_symbolizer_ms, 345);
118  EXPECT_EQ(f->memory_limit_mb, 456);
119  EXPECT_EQ(f->stop_on_start, true);
120  EXPECT_EQ(f->running_on_valgrind, true);
121  EXPECT_EQ(f->history_size, 6ul);
122  EXPECT_EQ(f->io_sync, 2);
123  EXPECT_EQ(f->die_after_fork, false);
124}
125
126static const char *test_default_options;
127extern "C" const char *__tsan_default_options() {
128  return test_default_options;
129}
130
131TEST(Flags, ParseDefaultOptions) {
132  Flags f;
133
134  test_default_options = options1;
135  InitializeFlags(&f, "");
136  VerifyOptions1(&f);
137
138  test_default_options = options2;
139  InitializeFlags(&f, "");
140  VerifyOptions2(&f);
141}
142
143TEST(Flags, ParseEnvOptions) {
144  Flags f;
145
146  InitializeFlags(&f, options1);
147  VerifyOptions1(&f);
148
149  InitializeFlags(&f, options2);
150  VerifyOptions2(&f);
151}
152
153TEST(Flags, ParsePriority) {
154  Flags f;
155
156  test_default_options = options2;
157  InitializeFlags(&f, options1);
158  VerifyOptions1(&f);
159
160  test_default_options = options1;
161  InitializeFlags(&f, options2);
162  VerifyOptions2(&f);
163}
164
165}  // namespace __tsan
166