[compiler-rt] 4f6a6ba - Revert "tsan: fix trace tests on darwin"
Ahsan Saghir via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 27 18:17:39 PDT 2021
Author: Ahsan Saghir
Date: 2021-09-27T20:17:17-05:00
New Revision: 4f6a6ba1265daedbceedf5dd4449a4e9fbf3a300
URL: https://github.com/llvm/llvm-project/commit/4f6a6ba1265daedbceedf5dd4449a4e9fbf3a300
DIFF: https://github.com/llvm/llvm-project/commit/4f6a6ba1265daedbceedf5dd4449a4e9fbf3a300.diff
LOG: Revert "tsan: fix trace tests on darwin"
This reverts commit 94ea36649ecc854d290c6797e6adb91bdfac756d.
Reverting due to errors on buildbots.
Added:
Modified:
compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp
compiler-rt/lib/tsan/tests/unit/tsan_trace_test.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp
index 6134a1be2bf5c..c4545130d3cad 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp
@@ -456,12 +456,14 @@ static void InitializeLongjmpXorKey() {
extern "C" void __tsan_tls_initialization() {}
void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size) {
+ // Check that the thr object is in tls;
const uptr thr_beg = (uptr)thr;
const uptr thr_end = (uptr)thr + sizeof(*thr);
- // ThreadState is normally allocated in TLS and is large,
- // so we skip it. But unit tests allocate ThreadState outside of TLS.
- if (thr_beg < tls_addr || thr_end >= tls_addr + tls_size)
- return;
+ CHECK_GE(thr_beg, tls_addr);
+ CHECK_LE(thr_beg, tls_addr + tls_size);
+ CHECK_GE(thr_end, tls_addr);
+ CHECK_LE(thr_end, tls_addr + tls_size);
+ // Since the thr object is huge, skip it.
const uptr pc = StackTrace::GetNextInstructionPc(
reinterpret_cast<uptr>(__tsan_tls_initialization));
MemoryRangeImitateWrite(thr, pc, tls_addr, thr_beg - tls_addr);
diff --git a/compiler-rt/lib/tsan/tests/unit/tsan_trace_test.cpp b/compiler-rt/lib/tsan/tests/unit/tsan_trace_test.cpp
index fb0b2b3a08f0c..0863850e4f114 100644
--- a/compiler-rt/lib/tsan/tests/unit/tsan_trace_test.cpp
+++ b/compiler-rt/lib/tsan/tests/unit/tsan_trace_test.cpp
@@ -22,115 +22,102 @@ using namespace v3;
// We need to run all trace tests in a new thread,
// so that the thread trace is empty initially.
-template <uptr N>
-struct ThreadArray {
- ThreadArray() {
- for (auto *&thr : threads) {
- thr = static_cast<ThreadState *>(
- MmapOrDie(sizeof(ThreadState), "ThreadState"));
- Tid tid = ThreadCreate(cur_thread(), 0, 0, true);
- Processor *proc = ProcCreate();
- ProcWire(proc, thr);
- ThreadStart(thr, tid, 0, ThreadType::Regular);
- }
- }
-
- ~ThreadArray() {
- for (uptr i = 0; i < N; i++) {
- if (threads[i])
- Finish(i);
- }
- }
-
- void Finish(uptr i) {
- auto *thr = threads[i];
- threads[i] = nullptr;
- Processor *proc = thr->proc();
- ThreadFinish(thr);
- ProcUnwire(proc, thr);
- ProcDestroy(proc);
- UnmapOrDie(thr, sizeof(ThreadState));
- }
+static void run_in_thread(void *(*f)(void *), void *arg = nullptr) {
+ pthread_t th;
+ pthread_create(&th, nullptr, f, arg);
+ pthread_join(th, nullptr);
+}
- ThreadState *threads[N];
- ThreadState *operator[](uptr i) { return threads[i]; }
- ThreadState *operator->() { return threads[0]; }
- operator ThreadState *() { return threads[0]; }
-};
+#if SANITIZER_MAC
+// These tests are currently failing on Mac.
+// See https://reviews.llvm.org/D107911 for more details.
+# define MAYBE_RestoreAccess DISABLED_RestoreAccess
+# define MAYBE_MemoryAccessSize DISABLED_MemoryAccessSize
+# define MAYBE_RestoreMutexLock DISABLED_RestoreMutexLock
+# define MAYBE_MultiPart DISABLED_MultiPart
+#else
+# define MAYBE_RestoreAccess RestoreAccess
+# define MAYBE_MemoryAccessSize MemoryAccessSize
+# define MAYBE_RestoreMutexLock RestoreMutexLock
+# define MAYBE_MultiPart MultiPart
+#endif
-TEST(Trace, RestoreAccess) {
- // A basic test with some function entry/exit events,
- // some mutex lock/unlock events and some other distracting
- // memory events.
- ThreadArray<1> thr;
- TraceFunc(thr, 0x1000);
- TraceFunc(thr, 0x1001);
- TraceMutexLock(thr, v3::EventType::kLock, 0x4000, 0x5000, 0x6000);
- TraceMutexLock(thr, v3::EventType::kLock, 0x4001, 0x5001, 0x6001);
- TraceMutexUnlock(thr, 0x5000);
- TraceFunc(thr);
- CHECK(TryTraceMemoryAccess(thr, 0x2001, 0x3001, 8, kAccessRead));
- TraceMutexLock(thr, v3::EventType::kRLock, 0x4002, 0x5002, 0x6002);
- TraceFunc(thr, 0x1002);
- CHECK(TryTraceMemoryAccess(thr, 0x2000, 0x3000, 8, kAccessRead));
- // This is the access we want to find.
- // The previous one is equivalent, but RestoreStack must prefer
- // the last of the matchig accesses.
- CHECK(TryTraceMemoryAccess(thr, 0x2002, 0x3000, 8, kAccessRead));
- Lock lock1(&ctx->slot_mtx);
- ThreadRegistryLock lock2(&ctx->thread_registry);
- VarSizeStackTrace stk;
- MutexSet mset;
- uptr tag = kExternalTagNone;
- bool res =
- RestoreStack(thr->tid, v3::EventType::kAccessExt, thr->sid, thr->epoch,
- 0x3000, 8, kAccessRead, &stk, &mset, &tag);
- CHECK(res);
- CHECK_EQ(stk.size, 3);
- CHECK_EQ(stk.trace[0], 0x1000);
- CHECK_EQ(stk.trace[1], 0x1002);
- CHECK_EQ(stk.trace[2], 0x2002);
- CHECK_EQ(mset.Size(), 2);
- CHECK_EQ(mset.Get(0).addr, 0x5001);
- CHECK_EQ(mset.Get(0).stack_id, 0x6001);
- CHECK_EQ(mset.Get(0).write, true);
- CHECK_EQ(mset.Get(1).addr, 0x5002);
- CHECK_EQ(mset.Get(1).stack_id, 0x6002);
- CHECK_EQ(mset.Get(1).write, false);
- CHECK_EQ(tag, kExternalTagNone);
+TEST(Trace, MAYBE_RestoreAccess) {
+ struct Thread {
+ static void *Func(void *arg) {
+ // A basic test with some function entry/exit events,
+ // some mutex lock/unlock events and some other distracting
+ // memory events.
+ ThreadState *thr = cur_thread();
+ TraceFunc(thr, 0x1000);
+ TraceFunc(thr, 0x1001);
+ TraceMutexLock(thr, v3::EventType::kLock, 0x4000, 0x5000, 0x6000);
+ TraceMutexLock(thr, v3::EventType::kLock, 0x4001, 0x5001, 0x6001);
+ TraceMutexUnlock(thr, 0x5000);
+ TraceFunc(thr);
+ CHECK(TryTraceMemoryAccess(thr, 0x2001, 0x3001, 8, kAccessRead));
+ TraceMutexLock(thr, v3::EventType::kRLock, 0x4002, 0x5002, 0x6002);
+ TraceFunc(thr, 0x1002);
+ CHECK(TryTraceMemoryAccess(thr, 0x2000, 0x3000, 8, kAccessRead));
+ // This is the access we want to find.
+ // The previous one is equivalent, but RestoreStack must prefer
+ // the last of the matchig accesses.
+ CHECK(TryTraceMemoryAccess(thr, 0x2002, 0x3000, 8, kAccessRead));
+ Lock lock1(&ctx->slot_mtx);
+ ThreadRegistryLock lock2(&ctx->thread_registry);
+ VarSizeStackTrace stk;
+ MutexSet mset;
+ uptr tag = kExternalTagNone;
+ bool res =
+ RestoreStack(thr->tid, v3::EventType::kAccessExt, thr->sid,
+ thr->epoch, 0x3000, 8, kAccessRead, &stk, &mset, &tag);
+ CHECK(res);
+ CHECK_EQ(stk.size, 3);
+ CHECK_EQ(stk.trace[0], 0x1000);
+ CHECK_EQ(stk.trace[1], 0x1002);
+ CHECK_EQ(stk.trace[2], 0x2002);
+ CHECK_EQ(mset.Size(), 2);
+ CHECK_EQ(mset.Get(0).addr, 0x5001);
+ CHECK_EQ(mset.Get(0).stack_id, 0x6001);
+ CHECK_EQ(mset.Get(0).write, true);
+ CHECK_EQ(mset.Get(1).addr, 0x5002);
+ CHECK_EQ(mset.Get(1).stack_id, 0x6002);
+ CHECK_EQ(mset.Get(1).write, false);
+ CHECK_EQ(tag, kExternalTagNone);
+ return nullptr;
+ }
+ };
+ run_in_thread(Thread::Func);
}
-TEST(Trace, MemoryAccessSize) {
- // Test tracing and matching of accesses of
diff erent sizes.
- struct Params {
- uptr access_size, offset, size;
- bool res;
- };
- Params tests[] = {
- {1, 0, 1, true}, {4, 0, 2, true},
- {4, 2, 2, true}, {8, 3, 1, true},
- {2, 1, 1, true}, {1, 1, 1, false},
- {8, 5, 4, false}, {4, static_cast<uptr>(-1l), 4, false},
- };
- for (auto params : tests) {
- for (int type = 0; type < 3; type++) {
- ThreadArray<1> thr;
+TEST(Trace, MAYBE_MemoryAccessSize) {
+ struct Thread {
+ struct Params {
+ uptr access_size, offset, size;
+ bool res;
+ int type;
+ };
+ static void *Func(void *arg) {
+ // Test tracing and matching of accesses of
diff erent sizes.
+ const Params *params = static_cast<Params *>(arg);
Printf("access_size=%zu, offset=%zu, size=%zu, res=%d, type=%d\n",
- params.access_size, params.offset, params.size, params.res, type);
+ params->access_size, params->offset, params->size, params->res,
+ params->type);
+ ThreadState *thr = cur_thread();
TraceFunc(thr, 0x1000);
- switch (type) {
+ switch (params->type) {
case 0:
// This should emit compressed event.
- CHECK(TryTraceMemoryAccess(thr, 0x2000, 0x3000, params.access_size,
+ CHECK(TryTraceMemoryAccess(thr, 0x2000, 0x3000, params->access_size,
kAccessRead));
break;
case 1:
// This should emit full event.
- CHECK(TryTraceMemoryAccess(thr, 0x2000000, 0x3000, params.access_size,
- kAccessRead));
+ CHECK(TryTraceMemoryAccess(thr, 0x2000000, 0x3000,
+ params->access_size, kAccessRead));
break;
case 2:
- TraceMemoryAccessRange(thr, 0x2000000, 0x3000, params.access_size,
+ TraceMemoryAccessRange(thr, 0x2000000, 0x3000, params->access_size,
kAccessRead);
break;
}
@@ -140,82 +127,105 @@ TEST(Trace, MemoryAccessSize) {
MutexSet mset;
uptr tag = kExternalTagNone;
bool res = RestoreStack(thr->tid, v3::EventType::kAccessExt, thr->sid,
- thr->epoch, 0x3000 + params.offset, params.size,
+ thr->epoch, 0x3000 + params->offset, params->size,
kAccessRead, &stk, &mset, &tag);
- CHECK_EQ(res, params.res);
- if (params.res) {
+ CHECK_EQ(res, params->res);
+ if (params->res) {
CHECK_EQ(stk.size, 2);
CHECK_EQ(stk.trace[0], 0x1000);
- CHECK_EQ(stk.trace[1], type ? 0x2000000 : 0x2000);
+ CHECK_EQ(stk.trace[1], params->type ? 0x2000000 : 0x2000);
}
+ return nullptr;
}
+ };
+ Thread::Params tests[] = {
+ {1, 0, 1, true, 0}, {4, 0, 2, true, 0},
+ {4, 2, 2, true, 0}, {8, 3, 1, true, 0},
+ {2, 1, 1, true, 0}, {1, 1, 1, false, 0},
+ {8, 5, 4, false, 0}, {4, static_cast<uptr>(-1l), 4, false, 0},
+ };
+ for (auto params : tests) {
+ for (params.type = 0; params.type < 3; params.type++)
+ run_in_thread(Thread::Func, ¶ms);
}
}
-TEST(Trace, RestoreMutexLock) {
- // Check of restoration of a mutex lock event.
- ThreadArray<1> thr;
- TraceFunc(thr, 0x1000);
- TraceMutexLock(thr, v3::EventType::kLock, 0x4000, 0x5000, 0x6000);
- TraceMutexLock(thr, v3::EventType::kRLock, 0x4001, 0x5001, 0x6001);
- TraceMutexLock(thr, v3::EventType::kRLock, 0x4002, 0x5001, 0x6002);
- Lock lock1(&ctx->slot_mtx);
- ThreadRegistryLock lock2(&ctx->thread_registry);
- VarSizeStackTrace stk;
- MutexSet mset;
- uptr tag = kExternalTagNone;
- bool res = RestoreStack(thr->tid, v3::EventType::kLock, thr->sid, thr->epoch,
- 0x5001, 0, 0, &stk, &mset, &tag);
- CHECK(res);
- CHECK_EQ(stk.size, 2);
- CHECK_EQ(stk.trace[0], 0x1000);
- CHECK_EQ(stk.trace[1], 0x4002);
- CHECK_EQ(mset.Size(), 2);
- CHECK_EQ(mset.Get(0).addr, 0x5000);
- CHECK_EQ(mset.Get(0).stack_id, 0x6000);
- CHECK_EQ(mset.Get(0).write, true);
- CHECK_EQ(mset.Get(1).addr, 0x5001);
- CHECK_EQ(mset.Get(1).stack_id, 0x6001);
- CHECK_EQ(mset.Get(1).write, false);
+TEST(Trace, MAYBE_RestoreMutexLock) {
+ struct Thread {
+ static void *Func(void *arg) {
+ // Check of restoration of a mutex lock event.
+ ThreadState *thr = cur_thread();
+ TraceFunc(thr, 0x1000);
+ TraceMutexLock(thr, v3::EventType::kLock, 0x4000, 0x5000, 0x6000);
+ TraceMutexLock(thr, v3::EventType::kRLock, 0x4001, 0x5001, 0x6001);
+ TraceMutexLock(thr, v3::EventType::kRLock, 0x4002, 0x5001, 0x6002);
+ Lock lock1(&ctx->slot_mtx);
+ ThreadRegistryLock lock2(&ctx->thread_registry);
+ VarSizeStackTrace stk;
+ MutexSet mset;
+ uptr tag = kExternalTagNone;
+ bool res = RestoreStack(thr->tid, v3::EventType::kLock, thr->sid,
+ thr->epoch, 0x5001, 0, 0, &stk, &mset, &tag);
+ CHECK(res);
+ CHECK_EQ(stk.size, 2);
+ CHECK_EQ(stk.trace[0], 0x1000);
+ CHECK_EQ(stk.trace[1], 0x4002);
+ CHECK_EQ(mset.Size(), 2);
+ CHECK_EQ(mset.Get(0).addr, 0x5000);
+ CHECK_EQ(mset.Get(0).stack_id, 0x6000);
+ CHECK_EQ(mset.Get(0).write, true);
+ CHECK_EQ(mset.Get(1).addr, 0x5001);
+ CHECK_EQ(mset.Get(1).stack_id, 0x6001);
+ CHECK_EQ(mset.Get(1).write, false);
+ return nullptr;
+ }
+ };
+ run_in_thread(Thread::Func);
}
-TEST(Trace, MultiPart) {
- // Check replay of a trace with multiple parts.
- ThreadArray<1> thr;
- TraceFunc(thr, 0x1000);
- TraceFunc(thr, 0x2000);
- TraceMutexLock(thr, v3::EventType::kLock, 0x4000, 0x5000, 0x6000);
- const uptr kEvents = 3 * sizeof(TracePart) / sizeof(v3::Event);
- for (uptr i = 0; i < kEvents; i++) {
- TraceFunc(thr, 0x3000);
- TraceMutexLock(thr, v3::EventType::kLock, 0x4002, 0x5002, 0x6002);
- TraceMutexUnlock(thr, 0x5002);
- TraceFunc(thr);
- }
- TraceFunc(thr, 0x4000);
- TraceMutexLock(thr, v3::EventType::kRLock, 0x4001, 0x5001, 0x6001);
- CHECK(TryTraceMemoryAccess(thr, 0x2002, 0x3000, 8, kAccessRead));
- Lock lock1(&ctx->slot_mtx);
- ThreadRegistryLock lock2(&ctx->thread_registry);
- VarSizeStackTrace stk;
- MutexSet mset;
- uptr tag = kExternalTagNone;
- bool res =
- RestoreStack(thr->tid, v3::EventType::kAccessExt, thr->sid, thr->epoch,
- 0x3000, 8, kAccessRead, &stk, &mset, &tag);
- CHECK(res);
- CHECK_EQ(stk.size, 4);
- CHECK_EQ(stk.trace[0], 0x1000);
- CHECK_EQ(stk.trace[1], 0x2000);
- CHECK_EQ(stk.trace[2], 0x4000);
- CHECK_EQ(stk.trace[3], 0x2002);
- CHECK_EQ(mset.Size(), 2);
- CHECK_EQ(mset.Get(0).addr, 0x5000);
- CHECK_EQ(mset.Get(0).stack_id, 0x6000);
- CHECK_EQ(mset.Get(0).write, true);
- CHECK_EQ(mset.Get(1).addr, 0x5001);
- CHECK_EQ(mset.Get(1).stack_id, 0x6001);
- CHECK_EQ(mset.Get(1).write, false);
+TEST(Trace, MAYBE_MultiPart) {
+ struct Thread {
+ static void *Func(void *arg) {
+ // Check replay of a trace with multiple parts.
+ ThreadState *thr = cur_thread();
+ TraceFunc(thr, 0x1000);
+ TraceFunc(thr, 0x2000);
+ TraceMutexLock(thr, v3::EventType::kLock, 0x4000, 0x5000, 0x6000);
+ const uptr kEvents = 3 * sizeof(TracePart) / sizeof(v3::Event);
+ for (uptr i = 0; i < kEvents; i++) {
+ TraceFunc(thr, 0x3000);
+ TraceMutexLock(thr, v3::EventType::kLock, 0x4002, 0x5002, 0x6002);
+ TraceMutexUnlock(thr, 0x5002);
+ TraceFunc(thr);
+ }
+ TraceFunc(thr, 0x4000);
+ TraceMutexLock(thr, v3::EventType::kRLock, 0x4001, 0x5001, 0x6001);
+ CHECK(TryTraceMemoryAccess(thr, 0x2002, 0x3000, 8, kAccessRead));
+ Lock lock1(&ctx->slot_mtx);
+ ThreadRegistryLock lock2(&ctx->thread_registry);
+ VarSizeStackTrace stk;
+ MutexSet mset;
+ uptr tag = kExternalTagNone;
+ bool res =
+ RestoreStack(thr->tid, v3::EventType::kAccessExt, thr->sid,
+ thr->epoch, 0x3000, 8, kAccessRead, &stk, &mset, &tag);
+ CHECK(res);
+ CHECK_EQ(stk.size, 4);
+ CHECK_EQ(stk.trace[0], 0x1000);
+ CHECK_EQ(stk.trace[1], 0x2000);
+ CHECK_EQ(stk.trace[2], 0x4000);
+ CHECK_EQ(stk.trace[3], 0x2002);
+ CHECK_EQ(mset.Size(), 2);
+ CHECK_EQ(mset.Get(0).addr, 0x5000);
+ CHECK_EQ(mset.Get(0).stack_id, 0x6000);
+ CHECK_EQ(mset.Get(0).write, true);
+ CHECK_EQ(mset.Get(1).addr, 0x5001);
+ CHECK_EQ(mset.Get(1).stack_id, 0x6001);
+ CHECK_EQ(mset.Get(1).write, false);
+ return nullptr;
+ }
+ };
+ run_in_thread(Thread::Func);
}
} // namespace __tsan
More information about the llvm-commits
mailing list