summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2013-10-29 10:30:39 +0000
committerDmitry Vyukov <dvyukov@google.com>2013-10-29 10:30:39 +0000
commit5cf2c460e96e593b1c772f1b02d3a217f4837fdc (patch)
treee7cef32475ecf17e6d2a47f6a0f3d38286294ef1
parent7996a2e2a1c461743c9216f13429c04d75050230 (diff)
downloadcompiler-rt-5cf2c460e96e593b1c772f1b02d3a217f4837fdc.tar.gz
compiler-rt-5cf2c460e96e593b1c772f1b02d3a217f4837fdc.tar.bz2
compiler-rt-5cf2c460e96e593b1c772f1b02d3a217f4837fdc.tar.xz
tsan/asan: support pthread_setname_np to set thread names
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@193602 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/asan/asan_interceptors.cc2
-rw-r--r--lib/msan/msan_interceptors.cc3
-rw-r--r--lib/sanitizer_common/sanitizer_common_interceptors.inc22
-rw-r--r--lib/sanitizer_common/sanitizer_platform_interceptors.h1
-rw-r--r--lib/sanitizer_common/sanitizer_thread_registry.cc12
-rw-r--r--lib/sanitizer_common/sanitizer_thread_registry.h1
-rw-r--r--lib/tsan/lit_tests/thread_name2.cc32
-rw-r--r--lib/tsan/rtl/tsan_interceptors.cc16
-rw-r--r--lib/tsan/rtl/tsan_stat.cc1
-rw-r--r--lib/tsan/rtl/tsan_stat.h1
10 files changed, 87 insertions, 4 deletions
diff --git a/lib/asan/asan_interceptors.cc b/lib/asan/asan_interceptors.cc
index 42bcbd8e..160afcb3 100644
--- a/lib/asan/asan_interceptors.cc
+++ b/lib/asan/asan_interceptors.cc
@@ -130,6 +130,8 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
do { \
} while (false)
#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) SetThreadName(name)
+#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
+ asanThreadRegistry().SetThreadNameByUserId(thread, name)
#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
#include "sanitizer_common/sanitizer_common_interceptors.inc"
diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc
index 0c42e047..360d5a19 100644
--- a/lib/msan/msan_interceptors.cc
+++ b/lib/msan/msan_interceptors.cc
@@ -1224,6 +1224,9 @@ extern "C" int *__errno_location(void);
#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
do { \
} while (false) // FIXME
+#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
+ do { \
+ } while (false) // FIXME
#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
#include "sanitizer_common/sanitizer_common_interceptors.inc"
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc
index f5179e24..c4b8a30d 100644
--- a/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -23,6 +23,7 @@
// COMMON_INTERCEPTOR_ON_EXIT
// COMMON_INTERCEPTOR_MUTEX_LOCK
// COMMON_INTERCEPTOR_MUTEX_UNLOCK
+// COMMON_INTERCEPTOR_SET_PTHREAD_NAME
//===----------------------------------------------------------------------===//
#include "interception/interception.h"
#include "sanitizer_platform_interceptors.h"
@@ -34,19 +35,19 @@
#endif // _WIN32
#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE
-#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, p, size)
+#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, p, size) {}
#endif
#ifndef COMMON_INTERCEPTOR_FD_ACCESS
-#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd)
+#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}
#endif
#ifndef COMMON_INTERCEPTOR_MUTEX_LOCK
-#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m)
+#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) {}
#endif
#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK
-#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m)
+#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {}
#endif
#if SANITIZER_INTERCEPT_STRCMP
@@ -2655,6 +2656,18 @@ INTERCEPTOR(char *, tempnam, char *dir, char *pfx) {
#define INIT_TEMPNAM
#endif
+#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP
+INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);
+ COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);
+ return REAL(pthread_setname_np)(thread, name);
+}
+#define INIT_PTHREAD_SETNAME_NP INTERCEPT_FUNCTION(pthread_setname_np);
+#else
+#define INIT_PTHREAD_SETNAME_NP
+#endif
+
#define SANITIZER_COMMON_INTERCEPTORS_INIT \
INIT_STRCMP; \
@@ -2757,4 +2770,5 @@ INTERCEPTOR(char *, tempnam, char *dir, char *pfx) {
INIT_TMPNAM; \
INIT_TMPNAM_R; \
INIT_TEMPNAM; \
+ INIT_PTHREAD_SETNAME_NP; \
/**/
diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h
index 3333aeb5..c2a432a6 100644
--- a/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -149,5 +149,6 @@
# define SANITIZER_INTERCEPT_PHTREAD_MUTEX SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_PTHREAD_COND SI_NOT_WINDOWS
+# define SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP SI_LINUX_NOT_ANDROID
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
diff --git a/lib/sanitizer_common/sanitizer_thread_registry.cc b/lib/sanitizer_common/sanitizer_thread_registry.cc
index ff7c9de5..bfa29a19 100644
--- a/lib/sanitizer_common/sanitizer_thread_registry.cc
+++ b/lib/sanitizer_common/sanitizer_thread_registry.cc
@@ -200,6 +200,18 @@ void ThreadRegistry::SetThreadName(u32 tid, const char *name) {
tctx->SetName(name);
}
+void ThreadRegistry::SetThreadNameByUserId(uptr user_id, const char *name) {
+ BlockingMutexLock l(&mtx_);
+ for (u32 tid = 0; tid < n_contexts_; tid++) {
+ ThreadContextBase *tctx = threads_[tid];
+ if (tctx != 0 && tctx->user_id == user_id &&
+ tctx->status != ThreadStatusInvalid) {
+ tctx->SetName(name);
+ return;
+ }
+ }
+}
+
void ThreadRegistry::DetachThread(u32 tid) {
BlockingMutexLock l(&mtx_);
CHECK_LT(tid, n_contexts_);
diff --git a/lib/sanitizer_common/sanitizer_thread_registry.h b/lib/sanitizer_common/sanitizer_thread_registry.h
index 6072e7c0..a59bba57 100644
--- a/lib/sanitizer_common/sanitizer_thread_registry.h
+++ b/lib/sanitizer_common/sanitizer_thread_registry.h
@@ -109,6 +109,7 @@ class ThreadRegistry {
ThreadContextBase *FindThreadContextByOsIDLocked(uptr os_id);
void SetThreadName(u32 tid, const char *name);
+ void SetThreadNameByUserId(uptr user_id, const char *name);
void DetachThread(u32 tid);
void JoinThread(u32 tid, void *arg);
void FinishThread(u32 tid);
diff --git a/lib/tsan/lit_tests/thread_name2.cc b/lib/tsan/lit_tests/thread_name2.cc
new file mode 100644
index 00000000..8c5cb741
--- /dev/null
+++ b/lib/tsan/lit_tests/thread_name2.cc
@@ -0,0 +1,32 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+
+int Global;
+
+void *Thread1(void *x) {
+ sleep(1);
+ Global++;
+ return 0;
+}
+
+void *Thread2(void *x) {
+ pthread_setname_np(pthread_self(), "foobar2");
+ Global--;
+ return 0;
+}
+
+int main() {
+ pthread_t t[2];
+ pthread_create(&t[0], 0, Thread1, 0);
+ pthread_create(&t[1], 0, Thread2, 0);
+ pthread_setname_np(t[0], "foobar1");
+ pthread_join(t[0], NULL);
+ pthread_join(t[1], NULL);
+}
+
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: Thread T1 'foobar1'
+// CHECK: Thread T2 'foobar2'
+
diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc
index 1131ddcb..a2033eb8 100644
--- a/lib/tsan/rtl/tsan_interceptors.cc
+++ b/lib/tsan/rtl/tsan_interceptors.cc
@@ -1837,38 +1837,54 @@ struct TsanInterceptorContext {
#define COMMON_INTERCEPTOR_UNPOISON_PARAM(ctx, count) \
do { \
} while (false)
+
#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
MemoryAccessRange(((TsanInterceptorContext *)ctx)->thr, \
((TsanInterceptorContext *)ctx)->pc, (uptr)ptr, size, \
true)
+
#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
MemoryAccessRange(((TsanInterceptorContext *) ctx)->thr, \
((TsanInterceptorContext *) ctx)->pc, (uptr) ptr, size, \
false)
+
#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
SCOPED_TSAN_INTERCEPTOR(func, __VA_ARGS__); \
TsanInterceptorContext _ctx = {thr, caller_pc, pc}; \
ctx = (void *)&_ctx; \
(void) ctx;
+
#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
FdAcquire(((TsanInterceptorContext *) ctx)->thr, pc, fd)
+
#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
FdRelease(((TsanInterceptorContext *) ctx)->thr, pc, fd)
+
#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) \
FdAccess(((TsanInterceptorContext *) ctx)->thr, pc, fd)
+
#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
FdSocketAccept(((TsanInterceptorContext *) ctx)->thr, pc, fd, newfd)
+
#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
ThreadSetName(((TsanInterceptorContext *) ctx)->thr, name)
+
+#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
+ CTX()->thread_registry->SetThreadNameByUserId(thread, name)
+
#define COMMON_INTERCEPTOR_BLOCK_REAL(name) BLOCK_REAL(name)
+
#define COMMON_INTERCEPTOR_ON_EXIT(ctx) \
OnExit(((TsanInterceptorContext *) ctx)->thr)
+
#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) \
MutexLock(((TsanInterceptorContext *)ctx)->thr, \
((TsanInterceptorContext *)ctx)->pc, (uptr)m)
+
#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) \
MutexUnlock(((TsanInterceptorContext *)ctx)->thr, \
((TsanInterceptorContext *)ctx)->pc, (uptr)m)
+
#include "sanitizer_common/sanitizer_common_interceptors.inc"
#define TSAN_SYSCALL() \
diff --git a/lib/tsan/rtl/tsan_stat.cc b/lib/tsan/rtl/tsan_stat.cc
index eb34be2e..ee1e3c16 100644
--- a/lib/tsan/rtl/tsan_stat.cc
+++ b/lib/tsan/rtl/tsan_stat.cc
@@ -182,6 +182,7 @@ void StatOutput(u64 *stat) {
name[StatInt_pthread_barrier_wait] = " pthread_barrier_wait ";
name[StatInt_pthread_once] = " pthread_once ";
name[StatInt_pthread_getschedparam] = " pthread_getschedparam ";
+ name[StatInt_pthread_setname_np] = " pthread_setname_np ";
name[StatInt_sem_init] = " sem_init ";
name[StatInt_sem_destroy] = " sem_destroy ";
name[StatInt_sem_wait] = " sem_wait ";
diff --git a/lib/tsan/rtl/tsan_stat.h b/lib/tsan/rtl/tsan_stat.h
index cad6b870..5e6679a7 100644
--- a/lib/tsan/rtl/tsan_stat.h
+++ b/lib/tsan/rtl/tsan_stat.h
@@ -177,6 +177,7 @@ enum StatType {
StatInt_pthread_barrier_wait,
StatInt_pthread_once,
StatInt_pthread_getschedparam,
+ StatInt_pthread_setname_np,
StatInt_sem_init,
StatInt_sem_destroy,
StatInt_sem_wait,