Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/compiler-rt/lib/rtsan/tests/rtsan_test_functional.cpp
35266 views
1
//===--- rtsan_test.cpp - Realtime Sanitizer --------------------*- C++ -*-===//
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
// Introduces basic functional tests for the realtime sanitizer.
10
// Not meant to be exhaustive, testing all interceptors, please see
11
// test_rtsan_interceptors.cpp for those tests.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#include "gtest/gtest.h"
16
17
#include "rtsan_test_utilities.h"
18
#include <rtsan.h>
19
#include <sanitizer_common/sanitizer_platform.h>
20
#include <sanitizer_common/sanitizer_platform_interceptors.h>
21
22
#include <array>
23
#include <atomic>
24
#include <chrono>
25
#include <fstream>
26
#include <mutex>
27
#include <shared_mutex>
28
#include <thread>
29
30
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
31
__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101200
32
#define SI_MAC_DEPLOYMENT_AT_LEAST_10_12 1
33
#else
34
#define SI_MAC_DEPLOYMENT_AT_LEAST_10_12 0
35
#endif
36
37
#define RTSAN_TEST_SHARED_MUTEX (!(SI_MAC) || SI_MAC_DEPLOYMENT_AT_LEAST_10_12)
38
39
using namespace testing;
40
using namespace rtsan_testing;
41
using namespace std::chrono_literals;
42
43
TEST(TestRtsan, VectorPushBackAllocationDiesWhenRealtime) {
44
std::vector<float> vec;
45
auto Func = [&vec]() { vec.push_back(0.4f); };
46
ExpectRealtimeDeath(Func);
47
ASSERT_EQ(0u, vec.size());
48
ExpectNonRealtimeSurvival(Func);
49
ASSERT_EQ(1u, vec.size());
50
}
51
52
TEST(TestRtsan, DestructionOfObjectOnHeapDiesWhenRealtime) {
53
auto allocated_ptr = std::make_unique<std::array<float, 256>>();
54
auto Func = [&allocated_ptr]() { allocated_ptr.reset(); };
55
ExpectRealtimeDeath(Func);
56
ASSERT_NE(nullptr, allocated_ptr.get());
57
ExpectNonRealtimeSurvival(Func);
58
ASSERT_EQ(nullptr, allocated_ptr.get());
59
}
60
61
TEST(TestRtsan, SleepingAThreadDiesWhenRealtime) {
62
auto Func = []() { std::this_thread::sleep_for(1us); };
63
ExpectRealtimeDeath(Func);
64
ExpectNonRealtimeSurvival(Func);
65
}
66
67
TEST(TestRtsan, IfstreamCreationDiesWhenRealtime) {
68
auto Func = []() { std::ifstream ifs{"./file.txt"}; };
69
ExpectRealtimeDeath(Func);
70
ExpectNonRealtimeSurvival(Func);
71
std::remove("./file.txt");
72
}
73
74
TEST(TestRtsan, OfstreamCreationDiesWhenRealtime) {
75
auto Func = []() { std::ofstream ofs{"./file.txt"}; };
76
ExpectRealtimeDeath(Func);
77
ExpectNonRealtimeSurvival(Func);
78
std::remove("./file.txt");
79
}
80
81
TEST(TestRtsan, LockingAMutexDiesWhenRealtime) {
82
std::mutex mutex;
83
auto Func = [&]() { mutex.lock(); };
84
ExpectRealtimeDeath(Func);
85
ExpectNonRealtimeSurvival(Func);
86
}
87
88
TEST(TestRtsan, UnlockingAMutexDiesWhenRealtime) {
89
std::mutex mutex;
90
mutex.lock();
91
auto Func = [&]() { mutex.unlock(); };
92
ExpectRealtimeDeath(Func);
93
ExpectNonRealtimeSurvival(Func);
94
}
95
96
#if RTSAN_TEST_SHARED_MUTEX
97
98
TEST(TestRtsan, LockingASharedMutexDiesWhenRealtime) {
99
std::shared_mutex mutex;
100
auto Func = [&]() { mutex.lock(); };
101
ExpectRealtimeDeath(Func);
102
ExpectNonRealtimeSurvival(Func);
103
}
104
105
TEST(TestRtsan, UnlockingASharedMutexDiesWhenRealtime) {
106
std::shared_mutex mutex;
107
mutex.lock();
108
auto Func = [&]() { mutex.unlock(); };
109
ExpectRealtimeDeath(Func);
110
ExpectNonRealtimeSurvival(Func);
111
}
112
113
TEST(TestRtsan, SharedLockingASharedMutexDiesWhenRealtime) {
114
std::shared_mutex mutex;
115
auto Func = [&]() { mutex.lock_shared(); };
116
ExpectRealtimeDeath(Func);
117
ExpectNonRealtimeSurvival(Func);
118
}
119
120
TEST(TestRtsan, SharedUnlockingASharedMutexDiesWhenRealtime) {
121
std::shared_mutex mutex;
122
mutex.lock_shared();
123
auto Func = [&]() { mutex.unlock_shared(); };
124
ExpectRealtimeDeath(Func);
125
ExpectNonRealtimeSurvival(Func);
126
}
127
128
#endif // RTSAN_TEST_SHARED_MUTEX
129
130
TEST(TestRtsan, LaunchingAThreadDiesWhenRealtime) {
131
auto Func = [&]() {
132
std::thread Thread{[]() {}};
133
Thread.join();
134
};
135
ExpectRealtimeDeath(Func);
136
ExpectNonRealtimeSurvival(Func);
137
}
138
139
namespace {
140
void InvokeStdFunction(std::function<void()> &&function) { function(); }
141
} // namespace
142
143
TEST(TestRtsan, CopyingALambdaWithLargeCaptureDiesWhenRealtime) {
144
std::array<float, 16> lots_of_data;
145
auto lambda = [lots_of_data]() mutable {
146
// Stop everything getting optimised out
147
lots_of_data[3] = 0.25f;
148
EXPECT_EQ(16, lots_of_data.size());
149
EXPECT_EQ(0.25f, lots_of_data[3]);
150
};
151
auto Func = [&]() { InvokeStdFunction(lambda); };
152
ExpectRealtimeDeath(Func);
153
ExpectNonRealtimeSurvival(Func);
154
}
155
156
TEST(TestRtsan, AccessingALargeAtomicVariableDiesWhenRealtime) {
157
std::atomic<float> small_atomic{0.0f};
158
ASSERT_TRUE(small_atomic.is_lock_free());
159
RealtimeInvoke([&small_atomic]() { float x = small_atomic.load(); });
160
161
std::atomic<std::array<float, 2048>> large_atomic;
162
ASSERT_FALSE(large_atomic.is_lock_free());
163
auto Func = [&]() { auto x = large_atomic.load(); };
164
ExpectRealtimeDeath(Func);
165
ExpectNonRealtimeSurvival(Func);
166
}
167
168
TEST(TestRtsan, FirstCoutDiesWhenRealtime) {
169
auto Func = []() { std::cout << "Hello, world!" << std::endl; };
170
ExpectRealtimeDeath(Func);
171
ExpectNonRealtimeSurvival(Func);
172
}
173
174
TEST(TestRtsan, SecondCoutDiesWhenRealtime) {
175
std::cout << "Hello, world";
176
auto Func = []() { std::cout << "Hello, again!" << std::endl; };
177
ExpectRealtimeDeath(Func);
178
ExpectNonRealtimeSurvival(Func);
179
}
180
181
TEST(TestRtsan, PrintfDiesWhenRealtime) {
182
auto Func = []() { printf("Hello, world!\n"); };
183
ExpectRealtimeDeath(Func);
184
ExpectNonRealtimeSurvival(Func);
185
}
186
187
TEST(TestRtsan, ThrowingAnExceptionDiesWhenRealtime) {
188
auto Func = [&]() {
189
try {
190
throw std::exception();
191
} catch (std::exception &) {
192
}
193
};
194
ExpectRealtimeDeath(Func);
195
ExpectNonRealtimeSurvival(Func);
196
}
197
198
TEST(TestRtsan, DoesNotDieIfTurnedOff) {
199
std::mutex mutex;
200
auto RealtimeUnsafeFunc = [&]() {
201
__rtsan_off();
202
mutex.lock();
203
mutex.unlock();
204
__rtsan_on();
205
};
206
RealtimeInvoke(RealtimeUnsafeFunc);
207
}
208
209