diff options
-rw-r--r-- | lib/asan/asan_interceptors.cc | 2 | ||||
-rw-r--r-- | lib/msan/msan_interceptors.cc | 3 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_common_interceptors.inc | 22 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_interceptors.h | 1 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_thread_registry.cc | 12 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_thread_registry.h | 1 | ||||
-rw-r--r-- | lib/tsan/lit_tests/thread_name2.cc | 32 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_interceptors.cc | 16 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_stat.cc | 1 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_stat.h | 1 |
10 files changed, 87 insertions, 4 deletions
diff --git a/lib/asan/asan_interceptors.cc b/lib/asan/asan_interceptors.cc index 42bcbd8e1..160afcb37 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 0c42e047b..360d5a194 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 f5179e244..c4b8a30d8 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 3333aeb56..c2a432a63 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 ff7c9de5c..bfa29a19c 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 6072e7c0a..a59bba570 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 000000000..8c5cb741f --- /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 1131ddcb2..a2033eb8d 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 eb34be2ea..ee1e3c167 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 cad6b8709..5e6679a74 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, |