[llvm-commits] [compiler-rt] r163006 - in /compiler-rt/trunk/lib/tsan: output_tests/race_on_heap.cc output_tests/sleep_sync.cc output_tests/sleep_sync2.cc rtl/tsan_interceptors.cc rtl/tsan_mman.cc rtl/tsan_report.cc rtl/tsan_report.h rtl/tsan_rtl.cc rtl/tsan_rtl.h rtl/tsan_rtl_mutex.cc rtl/tsan_rtl_report.cc rtl/tsan_stat.h
Dmitry Vyukov
dvyukov at google.com
Fri Aug 31 10:27:50 PDT 2012
Author: dvyukov
Date: Fri Aug 31 12:27:49 2012
New Revision: 163006
URL: http://llvm.org/viewvc/llvm-project?rev=163006&view=rev
Log:
tsan: add "as if synchronized via sleep" feature
Added:
compiler-rt/trunk/lib/tsan/output_tests/sleep_sync.cc
compiler-rt/trunk/lib/tsan/output_tests/sleep_sync2.cc
Modified:
compiler-rt/trunk/lib/tsan/output_tests/race_on_heap.cc
compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc
compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
compiler-rt/trunk/lib/tsan/rtl/tsan_report.h
compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc
compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h
compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc
compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc
compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h
Modified: compiler-rt/trunk/lib/tsan/output_tests/race_on_heap.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/output_tests/race_on_heap.cc?rev=163006&r1=163005&r2=163006&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/output_tests/race_on_heap.cc (original)
+++ compiler-rt/trunk/lib/tsan/output_tests/race_on_heap.cc Fri Aug 31 12:27:49 2012
@@ -37,8 +37,9 @@
// CHECK: WARNING: ThreadSanitizer: data race
// ...
// CHECK: Location is heap block of size 99 at [[ADDR]] allocated by thread 1:
-// CHECK: #0 alloc
-// CHECK: #1 AllocThread
+// CHCEKL #0 malloc
+// CHECK: #1 alloc
+// CHECK: #2 AllocThread
// ...
// CHECK: Thread 1 (finished) created at:
// CHECK: #0 pthread_create
Added: compiler-rt/trunk/lib/tsan/output_tests/sleep_sync.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/output_tests/sleep_sync.cc?rev=163006&view=auto
==============================================================================
--- compiler-rt/trunk/lib/tsan/output_tests/sleep_sync.cc (added)
+++ compiler-rt/trunk/lib/tsan/output_tests/sleep_sync.cc Fri Aug 31 12:27:49 2012
@@ -0,0 +1,30 @@
+#include <pthread.h>
+#include <unistd.h>
+
+int X = 0;
+
+void *Thread(void *p) {
+ X = 42;
+ return 0;
+}
+
+void MySleep() {
+ usleep(100*1000);
+}
+
+int main() {
+ pthread_t t;
+ pthread_create(&t, 0, Thread, 0);
+ MySleep(); // Assume the thread has done the write.
+ X = 43;
+ pthread_join(t, 0);
+ return 0;
+}
+
+// CHECK: WARNING: ThreadSanitizer: data race
+// ...
+// CHECK: As if synchronized via sleep:
+// CHECK-NEXT: #0 usleep
+// CHECK-NEXT: #1 MySleep
+// CHECK-NEXT: #2 main
+
Added: compiler-rt/trunk/lib/tsan/output_tests/sleep_sync2.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/output_tests/sleep_sync2.cc?rev=163006&view=auto
==============================================================================
--- compiler-rt/trunk/lib/tsan/output_tests/sleep_sync2.cc (added)
+++ compiler-rt/trunk/lib/tsan/output_tests/sleep_sync2.cc Fri Aug 31 12:27:49 2012
@@ -0,0 +1,21 @@
+#include <pthread.h>
+#include <unistd.h>
+
+int X = 0;
+
+void *Thread(void *p) {
+ X = 42;
+ return 0;
+}
+
+int main() {
+ pthread_t t;
+ usleep(100*1000);
+ pthread_create(&t, 0, Thread, 0);
+ X = 43;
+ pthread_join(t, 0);
+ return 0;
+}
+
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK-NOT: As if synchronized via sleep
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc?rev=163006&r1=163005&r2=163006&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Fri Aug 31 12:27:49 2012
@@ -51,7 +51,6 @@
extern "C" void _exit(int status);
extern "C" int __cxa_atexit(void (*func)(void *arg), void *arg, void *dso);
extern "C" int *__errno_location();
-extern "C" int usleep(unsigned usec);
const int PTHREAD_MUTEX_RECURSIVE = 1;
const int PTHREAD_MUTEX_RECURSIVE_NP = 1;
const int kPthreadAttrSize = 56;
@@ -213,6 +212,27 @@
__tsan_free_hook(ptr);
}
+TSAN_INTERCEPTOR(unsigned, sleep, unsigned sec) {
+ SCOPED_TSAN_INTERCEPTOR(sleep, sec);
+ unsigned res = sleep(sec);
+ AfterSleep(thr, pc);
+ return res;
+}
+
+TSAN_INTERCEPTOR(int, usleep, long_t usec) {
+ SCOPED_TSAN_INTERCEPTOR(usleep, usec);
+ int res = usleep(usec);
+ AfterSleep(thr, pc);
+ return res;
+}
+
+TSAN_INTERCEPTOR(int, nanosleep, void *req, void *rem) {
+ SCOPED_TSAN_INTERCEPTOR(nanosleep, req, rem);
+ int res = nanosleep(req, rem);
+ AfterSleep(thr, pc);
+ return res;
+}
+
class AtExitContext {
public:
AtExitContext()
@@ -269,7 +289,7 @@
{
ScopedInRtl in_rtl;
DestroyAndFree(atexit_ctx);
- usleep(flags()->atexit_sleep_ms * 1000);
+ REAL(usleep)(flags()->atexit_sleep_ms * 1000);
}
int status = Finalize(cur_thread());
if (status)
@@ -1572,6 +1592,9 @@
TSAN_INTERCEPT(raise);
TSAN_INTERCEPT(kill);
TSAN_INTERCEPT(pthread_kill);
+ TSAN_INTERCEPT(sleep);
+ TSAN_INTERCEPT(usleep);
+ TSAN_INTERCEPT(nanosleep);
atexit_ctx = new(internal_alloc(MBlockAtExit, sizeof(AtExitContext)))
AtExitContext();
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc?rev=163006&r1=163005&r2=163006&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc Fri Aug 31 12:27:49 2012
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_placement_new.h"
-#include "sanitizer_common/sanitizer_stackdepot.h"
#include "tsan_mman.h"
#include "tsan_rtl.h"
#include "tsan_report.h"
@@ -51,10 +50,7 @@
MBlock *b = (MBlock*)allocator()->GetMetaData(p);
b->size = sz;
b->alloc_tid = thr->unique_id;
- b->alloc_stack_id = 0;
- if (thr->shadow_stack_pos) // May happen during bootstrap.
- b->alloc_stack_id = StackDepotPut(thr->shadow_stack,
- thr->shadow_stack_pos - thr->shadow_stack);
+ b->alloc_stack_id = CurrentStackId(thr, pc);
if (CTX() && CTX()->initialized) {
MemoryRangeImitateWrite(thr, pc, (uptr)p, sz);
}
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc?rev=163006&r1=163005&r2=163006&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc Fri Aug 31 12:27:49 2012
@@ -21,7 +21,8 @@
, mops(MBlockReportMop)
, locs(MBlockReportLoc)
, mutexes(MBlockReportMutex)
- , threads(MBlockReportThread) {
+ , threads(MBlockReportThread)
+ , sleep() {
}
ReportDesc::~ReportDesc() {
@@ -110,6 +111,11 @@
PrintStack(rt->stack);
}
+static void PrintSleep(const ReportStack *s) {
+ TsanPrintf(" As if synchronized via sleep:\n");
+ PrintStack(s);
+}
+
void PrintReport(const ReportDesc *rep) {
TsanPrintf("==================\n");
PrintHeader(rep->typ);
@@ -123,6 +129,9 @@
for (uptr i = 0; i < rep->mops.Size(); i++)
PrintMop(rep->mops[i], i == 0);
+ if (rep->sleep)
+ PrintSleep(rep->sleep);
+
for (uptr i = 0; i < rep->locs.Size(); i++)
PrintLocation(rep->locs[i]);
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_report.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.h?rev=163006&r1=163005&r2=163006&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.h Fri Aug 31 12:27:49 2012
@@ -85,6 +85,7 @@
Vector<ReportLocation*> locs;
Vector<ReportMutex*> mutexes;
Vector<ReportThread*> threads;
+ ReportStack *sleep;
ReportDesc();
~ReportDesc();
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc?rev=163006&r1=163005&r2=163006&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc Fri Aug 31 12:27:49 2012
@@ -15,6 +15,7 @@
#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_libc.h"
+#include "sanitizer_common/sanitizer_stackdepot.h"
#include "sanitizer_common/sanitizer_placement_new.h"
#include "tsan_defs.h"
#include "tsan_platform.h"
@@ -223,6 +224,20 @@
return failed ? flags()->exitcode : 0;
}
+u32 CurrentStackId(ThreadState *thr, uptr pc) {
+ if (thr->shadow_stack_pos == 0) // May happen during bootstrap.
+ return 0;
+ if (pc) {
+ thr->shadow_stack_pos[0] = pc;
+ thr->shadow_stack_pos++;
+ }
+ u32 id = StackDepotPut(thr->shadow_stack,
+ thr->shadow_stack_pos - thr->shadow_stack);
+ if (pc)
+ thr->shadow_stack_pos--;
+ return id;
+}
+
void TraceSwitch(ThreadState *thr) {
thr->nomalloc++;
ScopedInRtl in_rtl;
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h?rev=163006&r1=163005&r2=163006&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h Fri Aug 31 12:27:49 2012
@@ -286,6 +286,11 @@
bool in_signal_handler;
SignalContext *signal_ctx;
+#ifndef TSAN_GO
+ u32 last_sleep_stack_id;
+ ThreadClock last_sleep_clock;
+#endif
+
// Set in regions of runtime that must be signal-safe and fork-safe.
// If set, malloc must not be called.
int nomalloc;
@@ -405,6 +410,7 @@
void AddThread(const ThreadContext *tctx);
void AddMutex(const SyncVar *s);
void AddLocation(uptr addr, uptr size);
+ void AddSleep(u32 stack_id);
const ReportDesc *GetReport() const;
@@ -446,6 +452,8 @@
# define DPrintf2(...)
#endif
+u32 CurrentStackId(ThreadState *thr, uptr pc);
+
void Initialize(ThreadState *thr);
int Finalize(ThreadState *thr);
@@ -489,6 +497,7 @@
void Acquire(ThreadState *thr, uptr pc, uptr addr);
void Release(ThreadState *thr, uptr pc, uptr addr);
void ReleaseStore(ThreadState *thr, uptr pc, uptr addr);
+void AfterSleep(ThreadState *thr, uptr pc);
// The hacky call uses custom calling convention and an assembly thunk.
// It is considerably faster that a normal call for the caller
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc?rev=163006&r1=163005&r2=163006&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc Fri Aug 31 12:27:49 2012
@@ -230,4 +230,21 @@
s->mtx.Unlock();
}
+#ifndef TSAN_GO
+void AfterSleep(ThreadState *thr, uptr pc) {
+ Context *ctx = CTX();
+ thr->last_sleep_stack_id = CurrentStackId(thr, pc);
+ Lock l(&ctx->thread_mtx);
+ for (unsigned i = 0; i < kMaxTid; i++) {
+ ThreadContext *tctx = ctx->threads[i];
+ if (tctx == 0)
+ continue;
+ if (tctx->status == ThreadStatusRunning)
+ thr->last_sleep_clock.set(i, tctx->thr->fast_state.epoch());
+ else
+ thr->last_sleep_clock.set(i, tctx->epoch1);
+ }
+}
+#endif
+
} // namespace __tsan
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc?rev=163006&r1=163005&r2=163006&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc Fri Aug 31 12:27:49 2012
@@ -230,6 +230,16 @@
}
}
+void ScopedReport::AddSleep(u32 stack_id) {
+ uptr ssz = 0;
+ const uptr *stack = StackDepotGet(stack_id, &ssz);
+ if (stack) {
+ StackTrace trace;
+ trace.Init(stack, ssz);
+ rep_->sleep = SymbolizeStack(trace);
+ }
+}
+
const ReportDesc *ScopedReport::GetReport() const {
return rep_;
}
@@ -411,6 +421,14 @@
rep.AddLocation(addr_min, addr_max - addr_min);
+#ifndef TSAN_GO
+ { // NOLINT
+ Shadow s(thr->racy_state[1]);
+ if (s.epoch() <= thr->last_sleep_clock.get(s.tid()))
+ rep.AddSleep(thr->last_sleep_stack_id);
+ }
+#endif
+
if (!OutputReport(rep, rep.GetReport()->mops[0]->stack))
return;
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h?rev=163006&r1=163005&r2=163006&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h Fri Aug 31 12:27:49 2012
@@ -199,6 +199,9 @@
StatInt_raise,
StatInt_kill,
StatInt_pthread_kill,
+ StatInt_sleep,
+ StatInt_usleep,
+ StatInt_nanosleep,
// Dynamic annotations.
StatAnnotation,
More information about the llvm-commits
mailing list