Skip to content

Commit 4f6a6ba

Browse files
author
Ahsan Saghir
committed
Revert "tsan: fix trace tests on darwin"
This reverts commit 94ea366. Reverting due to errors on buildbots.
1 parent 5df9112 commit 4f6a6ba

File tree

2 files changed

+177
-165
lines changed

2 files changed

+177
-165
lines changed

compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -456,12 +456,14 @@ static void InitializeLongjmpXorKey() {
456456
extern "C" void __tsan_tls_initialization() {}
457457

458458
void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size) {
459+
// Check that the thr object is in tls;
459460
const uptr thr_beg = (uptr)thr;
460461
const uptr thr_end = (uptr)thr + sizeof(*thr);
461-
// ThreadState is normally allocated in TLS and is large,
462-
// so we skip it. But unit tests allocate ThreadState outside of TLS.
463-
if (thr_beg < tls_addr || thr_end >= tls_addr + tls_size)
464-
return;
462+
CHECK_GE(thr_beg, tls_addr);
463+
CHECK_LE(thr_beg, tls_addr + tls_size);
464+
CHECK_GE(thr_end, tls_addr);
465+
CHECK_LE(thr_end, tls_addr + tls_size);
466+
// Since the thr object is huge, skip it.
465467
const uptr pc = StackTrace::GetNextInstructionPc(
466468
reinterpret_cast<uptr>(__tsan_tls_initialization));
467469
MemoryRangeImitateWrite(thr, pc, tls_addr, thr_beg - tls_addr);

compiler-rt/lib/tsan/tests/unit/tsan_trace_test.cpp

Lines changed: 171 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -22,115 +22,102 @@ using namespace v3;
2222

2323
// We need to run all trace tests in a new thread,
2424
// so that the thread trace is empty initially.
25-
template <uptr N>
26-
struct ThreadArray {
27-
ThreadArray() {
28-
for (auto *&thr : threads) {
29-
thr = static_cast<ThreadState *>(
30-
MmapOrDie(sizeof(ThreadState), "ThreadState"));
31-
Tid tid = ThreadCreate(cur_thread(), 0, 0, true);
32-
Processor *proc = ProcCreate();
33-
ProcWire(proc, thr);
34-
ThreadStart(thr, tid, 0, ThreadType::Regular);
35-
}
36-
}
37-
38-
~ThreadArray() {
39-
for (uptr i = 0; i < N; i++) {
40-
if (threads[i])
41-
Finish(i);
42-
}
43-
}
44-
45-
void Finish(uptr i) {
46-
auto *thr = threads[i];
47-
threads[i] = nullptr;
48-
Processor *proc = thr->proc();
49-
ThreadFinish(thr);
50-
ProcUnwire(proc, thr);
51-
ProcDestroy(proc);
52-
UnmapOrDie(thr, sizeof(ThreadState));
53-
}
25+
static void run_in_thread(void *(*f)(void *), void *arg = nullptr) {
26+
pthread_t th;
27+
pthread_create(&th, nullptr, f, arg);
28+
pthread_join(th, nullptr);
29+
}
5430

55-
ThreadState *threads[N];
56-
ThreadState *operator[](uptr i) { return threads[i]; }
57-
ThreadState *operator->() { return threads[0]; }
58-
operator ThreadState *() { return threads[0]; }
59-
};
31+
#if SANITIZER_MAC
32+
// These tests are currently failing on Mac.
33+
// See https://reviews.llvm.org/D107911 for more details.
34+
# define MAYBE_RestoreAccess DISABLED_RestoreAccess
35+
# define MAYBE_MemoryAccessSize DISABLED_MemoryAccessSize
36+
# define MAYBE_RestoreMutexLock DISABLED_RestoreMutexLock
37+
# define MAYBE_MultiPart DISABLED_MultiPart
38+
#else
39+
# define MAYBE_RestoreAccess RestoreAccess
40+
# define MAYBE_MemoryAccessSize MemoryAccessSize
41+
# define MAYBE_RestoreMutexLock RestoreMutexLock
42+
# define MAYBE_MultiPart MultiPart
43+
#endif
6044

61-
TEST(Trace, RestoreAccess) {
62-
// A basic test with some function entry/exit events,
63-
// some mutex lock/unlock events and some other distracting
64-
// memory events.
65-
ThreadArray<1> thr;
66-
TraceFunc(thr, 0x1000);
67-
TraceFunc(thr, 0x1001);
68-
TraceMutexLock(thr, v3::EventType::kLock, 0x4000, 0x5000, 0x6000);
69-
TraceMutexLock(thr, v3::EventType::kLock, 0x4001, 0x5001, 0x6001);
70-
TraceMutexUnlock(thr, 0x5000);
71-
TraceFunc(thr);
72-
CHECK(TryTraceMemoryAccess(thr, 0x2001, 0x3001, 8, kAccessRead));
73-
TraceMutexLock(thr, v3::EventType::kRLock, 0x4002, 0x5002, 0x6002);
74-
TraceFunc(thr, 0x1002);
75-
CHECK(TryTraceMemoryAccess(thr, 0x2000, 0x3000, 8, kAccessRead));
76-
// This is the access we want to find.
77-
// The previous one is equivalent, but RestoreStack must prefer
78-
// the last of the matchig accesses.
79-
CHECK(TryTraceMemoryAccess(thr, 0x2002, 0x3000, 8, kAccessRead));
80-
Lock lock1(&ctx->slot_mtx);
81-
ThreadRegistryLock lock2(&ctx->thread_registry);
82-
VarSizeStackTrace stk;
83-
MutexSet mset;
84-
uptr tag = kExternalTagNone;
85-
bool res =
86-
RestoreStack(thr->tid, v3::EventType::kAccessExt, thr->sid, thr->epoch,
87-
0x3000, 8, kAccessRead, &stk, &mset, &tag);
88-
CHECK(res);
89-
CHECK_EQ(stk.size, 3);
90-
CHECK_EQ(stk.trace[0], 0x1000);
91-
CHECK_EQ(stk.trace[1], 0x1002);
92-
CHECK_EQ(stk.trace[2], 0x2002);
93-
CHECK_EQ(mset.Size(), 2);
94-
CHECK_EQ(mset.Get(0).addr, 0x5001);
95-
CHECK_EQ(mset.Get(0).stack_id, 0x6001);
96-
CHECK_EQ(mset.Get(0).write, true);
97-
CHECK_EQ(mset.Get(1).addr, 0x5002);
98-
CHECK_EQ(mset.Get(1).stack_id, 0x6002);
99-
CHECK_EQ(mset.Get(1).write, false);
100-
CHECK_EQ(tag, kExternalTagNone);
45+
TEST(Trace, MAYBE_RestoreAccess) {
46+
struct Thread {
47+
static void *Func(void *arg) {
48+
// A basic test with some function entry/exit events,
49+
// some mutex lock/unlock events and some other distracting
50+
// memory events.
51+
ThreadState *thr = cur_thread();
52+
TraceFunc(thr, 0x1000);
53+
TraceFunc(thr, 0x1001);
54+
TraceMutexLock(thr, v3::EventType::kLock, 0x4000, 0x5000, 0x6000);
55+
TraceMutexLock(thr, v3::EventType::kLock, 0x4001, 0x5001, 0x6001);
56+
TraceMutexUnlock(thr, 0x5000);
57+
TraceFunc(thr);
58+
CHECK(TryTraceMemoryAccess(thr, 0x2001, 0x3001, 8, kAccessRead));
59+
TraceMutexLock(thr, v3::EventType::kRLock, 0x4002, 0x5002, 0x6002);
60+
TraceFunc(thr, 0x1002);
61+
CHECK(TryTraceMemoryAccess(thr, 0x2000, 0x3000, 8, kAccessRead));
62+
// This is the access we want to find.
63+
// The previous one is equivalent, but RestoreStack must prefer
64+
// the last of the matchig accesses.
65+
CHECK(TryTraceMemoryAccess(thr, 0x2002, 0x3000, 8, kAccessRead));
66+
Lock lock1(&ctx->slot_mtx);
67+
ThreadRegistryLock lock2(&ctx->thread_registry);
68+
VarSizeStackTrace stk;
69+
MutexSet mset;
70+
uptr tag = kExternalTagNone;
71+
bool res =
72+
RestoreStack(thr->tid, v3::EventType::kAccessExt, thr->sid,
73+
thr->epoch, 0x3000, 8, kAccessRead, &stk, &mset, &tag);
74+
CHECK(res);
75+
CHECK_EQ(stk.size, 3);
76+
CHECK_EQ(stk.trace[0], 0x1000);
77+
CHECK_EQ(stk.trace[1], 0x1002);
78+
CHECK_EQ(stk.trace[2], 0x2002);
79+
CHECK_EQ(mset.Size(), 2);
80+
CHECK_EQ(mset.Get(0).addr, 0x5001);
81+
CHECK_EQ(mset.Get(0).stack_id, 0x6001);
82+
CHECK_EQ(mset.Get(0).write, true);
83+
CHECK_EQ(mset.Get(1).addr, 0x5002);
84+
CHECK_EQ(mset.Get(1).stack_id, 0x6002);
85+
CHECK_EQ(mset.Get(1).write, false);
86+
CHECK_EQ(tag, kExternalTagNone);
87+
return nullptr;
88+
}
89+
};
90+
run_in_thread(Thread::Func);
10191
}
10292

103-
TEST(Trace, MemoryAccessSize) {
104-
// Test tracing and matching of accesses of different sizes.
105-
struct Params {
106-
uptr access_size, offset, size;
107-
bool res;
108-
};
109-
Params tests[] = {
110-
{1, 0, 1, true}, {4, 0, 2, true},
111-
{4, 2, 2, true}, {8, 3, 1, true},
112-
{2, 1, 1, true}, {1, 1, 1, false},
113-
{8, 5, 4, false}, {4, static_cast<uptr>(-1l), 4, false},
114-
};
115-
for (auto params : tests) {
116-
for (int type = 0; type < 3; type++) {
117-
ThreadArray<1> thr;
93+
TEST(Trace, MAYBE_MemoryAccessSize) {
94+
struct Thread {
95+
struct Params {
96+
uptr access_size, offset, size;
97+
bool res;
98+
int type;
99+
};
100+
static void *Func(void *arg) {
101+
// Test tracing and matching of accesses of different sizes.
102+
const Params *params = static_cast<Params *>(arg);
118103
Printf("access_size=%zu, offset=%zu, size=%zu, res=%d, type=%d\n",
119-
params.access_size, params.offset, params.size, params.res, type);
104+
params->access_size, params->offset, params->size, params->res,
105+
params->type);
106+
ThreadState *thr = cur_thread();
120107
TraceFunc(thr, 0x1000);
121-
switch (type) {
108+
switch (params->type) {
122109
case 0:
123110
// This should emit compressed event.
124-
CHECK(TryTraceMemoryAccess(thr, 0x2000, 0x3000, params.access_size,
111+
CHECK(TryTraceMemoryAccess(thr, 0x2000, 0x3000, params->access_size,
125112
kAccessRead));
126113
break;
127114
case 1:
128115
// This should emit full event.
129-
CHECK(TryTraceMemoryAccess(thr, 0x2000000, 0x3000, params.access_size,
130-
kAccessRead));
116+
CHECK(TryTraceMemoryAccess(thr, 0x2000000, 0x3000,
117+
params->access_size, kAccessRead));
131118
break;
132119
case 2:
133-
TraceMemoryAccessRange(thr, 0x2000000, 0x3000, params.access_size,
120+
TraceMemoryAccessRange(thr, 0x2000000, 0x3000, params->access_size,
134121
kAccessRead);
135122
break;
136123
}
@@ -140,82 +127,105 @@ TEST(Trace, MemoryAccessSize) {
140127
MutexSet mset;
141128
uptr tag = kExternalTagNone;
142129
bool res = RestoreStack(thr->tid, v3::EventType::kAccessExt, thr->sid,
143-
thr->epoch, 0x3000 + params.offset, params.size,
130+
thr->epoch, 0x3000 + params->offset, params->size,
144131
kAccessRead, &stk, &mset, &tag);
145-
CHECK_EQ(res, params.res);
146-
if (params.res) {
132+
CHECK_EQ(res, params->res);
133+
if (params->res) {
147134
CHECK_EQ(stk.size, 2);
148135
CHECK_EQ(stk.trace[0], 0x1000);
149-
CHECK_EQ(stk.trace[1], type ? 0x2000000 : 0x2000);
136+
CHECK_EQ(stk.trace[1], params->type ? 0x2000000 : 0x2000);
150137
}
138+
return nullptr;
151139
}
140+
};
141+
Thread::Params tests[] = {
142+
{1, 0, 1, true, 0}, {4, 0, 2, true, 0},
143+
{4, 2, 2, true, 0}, {8, 3, 1, true, 0},
144+
{2, 1, 1, true, 0}, {1, 1, 1, false, 0},
145+
{8, 5, 4, false, 0}, {4, static_cast<uptr>(-1l), 4, false, 0},
146+
};
147+
for (auto params : tests) {
148+
for (params.type = 0; params.type < 3; params.type++)
149+
run_in_thread(Thread::Func, &params);
152150
}
153151
}
154152

155-
TEST(Trace, RestoreMutexLock) {
156-
// Check of restoration of a mutex lock event.
157-
ThreadArray<1> thr;
158-
TraceFunc(thr, 0x1000);
159-
TraceMutexLock(thr, v3::EventType::kLock, 0x4000, 0x5000, 0x6000);
160-
TraceMutexLock(thr, v3::EventType::kRLock, 0x4001, 0x5001, 0x6001);
161-
TraceMutexLock(thr, v3::EventType::kRLock, 0x4002, 0x5001, 0x6002);
162-
Lock lock1(&ctx->slot_mtx);
163-
ThreadRegistryLock lock2(&ctx->thread_registry);
164-
VarSizeStackTrace stk;
165-
MutexSet mset;
166-
uptr tag = kExternalTagNone;
167-
bool res = RestoreStack(thr->tid, v3::EventType::kLock, thr->sid, thr->epoch,
168-
0x5001, 0, 0, &stk, &mset, &tag);
169-
CHECK(res);
170-
CHECK_EQ(stk.size, 2);
171-
CHECK_EQ(stk.trace[0], 0x1000);
172-
CHECK_EQ(stk.trace[1], 0x4002);
173-
CHECK_EQ(mset.Size(), 2);
174-
CHECK_EQ(mset.Get(0).addr, 0x5000);
175-
CHECK_EQ(mset.Get(0).stack_id, 0x6000);
176-
CHECK_EQ(mset.Get(0).write, true);
177-
CHECK_EQ(mset.Get(1).addr, 0x5001);
178-
CHECK_EQ(mset.Get(1).stack_id, 0x6001);
179-
CHECK_EQ(mset.Get(1).write, false);
153+
TEST(Trace, MAYBE_RestoreMutexLock) {
154+
struct Thread {
155+
static void *Func(void *arg) {
156+
// Check of restoration of a mutex lock event.
157+
ThreadState *thr = cur_thread();
158+
TraceFunc(thr, 0x1000);
159+
TraceMutexLock(thr, v3::EventType::kLock, 0x4000, 0x5000, 0x6000);
160+
TraceMutexLock(thr, v3::EventType::kRLock, 0x4001, 0x5001, 0x6001);
161+
TraceMutexLock(thr, v3::EventType::kRLock, 0x4002, 0x5001, 0x6002);
162+
Lock lock1(&ctx->slot_mtx);
163+
ThreadRegistryLock lock2(&ctx->thread_registry);
164+
VarSizeStackTrace stk;
165+
MutexSet mset;
166+
uptr tag = kExternalTagNone;
167+
bool res = RestoreStack(thr->tid, v3::EventType::kLock, thr->sid,
168+
thr->epoch, 0x5001, 0, 0, &stk, &mset, &tag);
169+
CHECK(res);
170+
CHECK_EQ(stk.size, 2);
171+
CHECK_EQ(stk.trace[0], 0x1000);
172+
CHECK_EQ(stk.trace[1], 0x4002);
173+
CHECK_EQ(mset.Size(), 2);
174+
CHECK_EQ(mset.Get(0).addr, 0x5000);
175+
CHECK_EQ(mset.Get(0).stack_id, 0x6000);
176+
CHECK_EQ(mset.Get(0).write, true);
177+
CHECK_EQ(mset.Get(1).addr, 0x5001);
178+
CHECK_EQ(mset.Get(1).stack_id, 0x6001);
179+
CHECK_EQ(mset.Get(1).write, false);
180+
return nullptr;
181+
}
182+
};
183+
run_in_thread(Thread::Func);
180184
}
181185

182-
TEST(Trace, MultiPart) {
183-
// Check replay of a trace with multiple parts.
184-
ThreadArray<1> thr;
185-
TraceFunc(thr, 0x1000);
186-
TraceFunc(thr, 0x2000);
187-
TraceMutexLock(thr, v3::EventType::kLock, 0x4000, 0x5000, 0x6000);
188-
const uptr kEvents = 3 * sizeof(TracePart) / sizeof(v3::Event);
189-
for (uptr i = 0; i < kEvents; i++) {
190-
TraceFunc(thr, 0x3000);
191-
TraceMutexLock(thr, v3::EventType::kLock, 0x4002, 0x5002, 0x6002);
192-
TraceMutexUnlock(thr, 0x5002);
193-
TraceFunc(thr);
194-
}
195-
TraceFunc(thr, 0x4000);
196-
TraceMutexLock(thr, v3::EventType::kRLock, 0x4001, 0x5001, 0x6001);
197-
CHECK(TryTraceMemoryAccess(thr, 0x2002, 0x3000, 8, kAccessRead));
198-
Lock lock1(&ctx->slot_mtx);
199-
ThreadRegistryLock lock2(&ctx->thread_registry);
200-
VarSizeStackTrace stk;
201-
MutexSet mset;
202-
uptr tag = kExternalTagNone;
203-
bool res =
204-
RestoreStack(thr->tid, v3::EventType::kAccessExt, thr->sid, thr->epoch,
205-
0x3000, 8, kAccessRead, &stk, &mset, &tag);
206-
CHECK(res);
207-
CHECK_EQ(stk.size, 4);
208-
CHECK_EQ(stk.trace[0], 0x1000);
209-
CHECK_EQ(stk.trace[1], 0x2000);
210-
CHECK_EQ(stk.trace[2], 0x4000);
211-
CHECK_EQ(stk.trace[3], 0x2002);
212-
CHECK_EQ(mset.Size(), 2);
213-
CHECK_EQ(mset.Get(0).addr, 0x5000);
214-
CHECK_EQ(mset.Get(0).stack_id, 0x6000);
215-
CHECK_EQ(mset.Get(0).write, true);
216-
CHECK_EQ(mset.Get(1).addr, 0x5001);
217-
CHECK_EQ(mset.Get(1).stack_id, 0x6001);
218-
CHECK_EQ(mset.Get(1).write, false);
186+
TEST(Trace, MAYBE_MultiPart) {
187+
struct Thread {
188+
static void *Func(void *arg) {
189+
// Check replay of a trace with multiple parts.
190+
ThreadState *thr = cur_thread();
191+
TraceFunc(thr, 0x1000);
192+
TraceFunc(thr, 0x2000);
193+
TraceMutexLock(thr, v3::EventType::kLock, 0x4000, 0x5000, 0x6000);
194+
const uptr kEvents = 3 * sizeof(TracePart) / sizeof(v3::Event);
195+
for (uptr i = 0; i < kEvents; i++) {
196+
TraceFunc(thr, 0x3000);
197+
TraceMutexLock(thr, v3::EventType::kLock, 0x4002, 0x5002, 0x6002);
198+
TraceMutexUnlock(thr, 0x5002);
199+
TraceFunc(thr);
200+
}
201+
TraceFunc(thr, 0x4000);
202+
TraceMutexLock(thr, v3::EventType::kRLock, 0x4001, 0x5001, 0x6001);
203+
CHECK(TryTraceMemoryAccess(thr, 0x2002, 0x3000, 8, kAccessRead));
204+
Lock lock1(&ctx->slot_mtx);
205+
ThreadRegistryLock lock2(&ctx->thread_registry);
206+
VarSizeStackTrace stk;
207+
MutexSet mset;
208+
uptr tag = kExternalTagNone;
209+
bool res =
210+
RestoreStack(thr->tid, v3::EventType::kAccessExt, thr->sid,
211+
thr->epoch, 0x3000, 8, kAccessRead, &stk, &mset, &tag);
212+
CHECK(res);
213+
CHECK_EQ(stk.size, 4);
214+
CHECK_EQ(stk.trace[0], 0x1000);
215+
CHECK_EQ(stk.trace[1], 0x2000);
216+
CHECK_EQ(stk.trace[2], 0x4000);
217+
CHECK_EQ(stk.trace[3], 0x2002);
218+
CHECK_EQ(mset.Size(), 2);
219+
CHECK_EQ(mset.Get(0).addr, 0x5000);
220+
CHECK_EQ(mset.Get(0).stack_id, 0x6000);
221+
CHECK_EQ(mset.Get(0).write, true);
222+
CHECK_EQ(mset.Get(1).addr, 0x5001);
223+
CHECK_EQ(mset.Get(1).stack_id, 0x6001);
224+
CHECK_EQ(mset.Get(1).write, false);
225+
return nullptr;
226+
}
227+
};
228+
run_in_thread(Thread::Func);
219229
}
220230

221231
} // namespace __tsan

0 commit comments

Comments
 (0)