summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2012-12-04 15:46:05 +0000
committerDmitry Vyukov <dvyukov@google.com>2012-12-04 15:46:05 +0000
commit1b4699359868ef38a938995e42326ac64095820e (patch)
tree50fd4c8bafe257b2bbf2b1bb9258e896179f682c
parent0ea8e107fc70de3012a349807643649aea8046e4 (diff)
downloadbcm5719-llvm-1b4699359868ef38a938995e42326ac64095820e.tar.gz
bcm5719-llvm-1b4699359868ef38a938995e42326ac64095820e.zip
tsan: output thread names
llvm-svn: 169279
-rw-r--r--compiler-rt/lib/tsan/lit_tests/thread_name.cc34
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_interface_ann.cc3
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_report.cc1
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_rtl.cc3
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_rtl.h2
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc4
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc20
7 files changed, 63 insertions, 4 deletions
diff --git a/compiler-rt/lib/tsan/lit_tests/thread_name.cc b/compiler-rt/lib/tsan/lit_tests/thread_name.cc
new file mode 100644
index 00000000000..76ca99390c7
--- /dev/null
+++ b/compiler-rt/lib/tsan/lit_tests/thread_name.cc
@@ -0,0 +1,34 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+
+extern "C" void AnnotateThreadName(const char *f, int l, const char *name);
+
+int Global;
+
+void *Thread1(void *x) {
+ usleep(100*1000);
+ AnnotateThreadName(__FILE__, __LINE__, "Thread1");
+ Global++;
+ return NULL;
+}
+
+void *Thread2(void *x) {
+ AnnotateThreadName(__FILE__, __LINE__, "Thread2");
+ Global--;
+ return NULL;
+}
+
+int main() {
+ pthread_t t[2];
+ pthread_create(&t[0], NULL, Thread1, NULL);
+ pthread_create(&t[1], NULL, Thread2, NULL);
+ pthread_join(t[0], NULL);
+ pthread_join(t[1], NULL);
+}
+
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: Thread 1 'Thread1'
+// CHECK: Thread 2 'Thread2'
+
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cc b/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cc
index b0b9f606534..51ebbf2266d 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cc
@@ -338,7 +338,7 @@ void INTERFACE_ATTRIBUTE AnnotateIgnoreWritesBegin(char *f, int l) {
void INTERFACE_ATTRIBUTE AnnotateIgnoreWritesEnd(char *f, int l) {
SCOPED_ANNOTATION(AnnotateIgnoreWritesEnd);
- IgnoreCtl(cur_thread(), true, false);
+ IgnoreCtl(thr, true, false);
}
void INTERFACE_ATTRIBUTE AnnotatePublishMemoryRange(
@@ -354,6 +354,7 @@ void INTERFACE_ATTRIBUTE AnnotateUnpublishMemoryRange(
void INTERFACE_ATTRIBUTE AnnotateThreadName(
char *f, int l, char *name) {
SCOPED_ANNOTATION(AnnotateThreadName);
+ ThreadSetName(thr, name);
}
void INTERFACE_ATTRIBUTE WTFAnnotateHappensBefore(char *f, int l, uptr addr) {
diff --git a/compiler-rt/lib/tsan/rtl/tsan_report.cc b/compiler-rt/lib/tsan/rtl/tsan_report.cc
index 67ae5a95a44..3324320aa24 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_report.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_report.cc
@@ -26,6 +26,7 @@ ReportDesc::ReportDesc()
}
ReportDesc::~ReportDesc() {
+ // FIXME(dvyukov): it must be leaking a lot of memory.
}
#ifndef TSAN_GO
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl.cc
index 904558809b1..17e7bd53c76 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cc
@@ -84,7 +84,8 @@ ThreadContext::ThreadContext(int tid)
, epoch0()
, epoch1()
, dead_info()
- , dead_next() {
+ , dead_next()
+ , name() {
}
static void WriteMemoryProfile(char *buf, uptr buf_size, int num) {
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
index af8951bab2d..c1b28fcc4a1 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
@@ -373,6 +373,7 @@ struct ThreadContext {
StackTrace creation_stack;
ThreadDeadInfo *dead_info;
ThreadContext *dead_next; // In dead thread list.
+ char *name; // As annotated by user.
explicit ThreadContext(int tid);
};
@@ -529,6 +530,7 @@ int ThreadTid(ThreadState *thr, uptr pc, uptr uid);
void ThreadJoin(ThreadState *thr, uptr pc, int tid);
void ThreadDetach(ThreadState *thr, uptr pc, int tid);
void ThreadFinalize(ThreadState *thr);
+void ThreadSetName(ThreadState *thr, const char *name);
int ThreadCount(ThreadState *thr);
void ProcessPendingSignals(ThreadState *thr);
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc
index dd967b9ab1b..488019fa2c3 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc
@@ -125,8 +125,7 @@ ScopedReport::ScopedReport(ReportType typ) {
ScopedReport::~ScopedReport() {
ctx_->report_mtx.Unlock();
- rep_->~ReportDesc();
- internal_free(rep_);
+ DestroyAndFree(rep_);
}
void ScopedReport::AddStack(const StackTrace *stack) {
@@ -158,6 +157,7 @@ void ScopedReport::AddThread(const ThreadContext *tctx) {
rt->id = tctx->tid;
rt->pid = tctx->os_id;
rt->running = (tctx->status == ThreadStatusRunning);
+ rt->name = tctx->name ? internal_strdup(tctx->name) : 0;
rt->stack = SymbolizeStack(tctx->creation_stack);
}
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc
index 75568def815..7d80066257a 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc
@@ -98,6 +98,7 @@ int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached) {
ThreadContext *tctx = 0;
if (ctx->dead_list_size > kThreadQuarantineSize
|| ctx->thread_seq >= kMaxTid) {
+ // Reusing old thread descriptor and tid.
if (ctx->dead_list_size == 0) {
Printf("ThreadSanitizer: %d thread limit exceeded. Dying.\n",
kMaxTid);
@@ -117,7 +118,12 @@ int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached) {
tctx->sync.Reset();
tid = tctx->tid;
DestroyAndFree(tctx->dead_info);
+ if (tctx->name) {
+ internal_free(tctx->name);
+ tctx->name = 0;
+ }
} else {
+ // Allocating new thread descriptor and tid.
StatInc(thr, StatThreadMaxTid);
tid = ctx->thread_seq++;
void *mem = internal_alloc(MBlockThreadContex, sizeof(ThreadContext));
@@ -324,6 +330,20 @@ void ThreadDetach(ThreadState *thr, uptr pc, int tid) {
}
}
+void ThreadSetName(ThreadState *thr, const char *name) {
+ Context *ctx = CTX();
+ Lock l(&ctx->thread_mtx);
+ ThreadContext *tctx = ctx->threads[thr->tid];
+ CHECK_NE(tctx, 0);
+ CHECK_EQ(tctx->status, ThreadStatusRunning);
+ if (tctx->name) {
+ internal_free(tctx->name);
+ tctx->name = 0;
+ }
+ if (name)
+ tctx->name = internal_strdup(name);
+}
+
void MemoryAccessRange(ThreadState *thr, uptr pc, uptr addr,
uptr size, bool is_write) {
if (size == 0)
OpenPOWER on IntegriCloud