Skip to content

Commit

Permalink
[tsan] Add pthread_cond_clockwait interceptor
Browse files Browse the repository at this point in the history
Disable the test on old systems.
pthread_cond_clockwait is supported by glibc-2.30.
It also supported by Android api 30 even though we
do not run tsan on Android.

Fixes google/sanitizers#1259

Reviewed By: dvyukov
  • Loading branch information
vitalybuka authored and jrtc27 committed Jan 18, 2022
1 parent d5dfcb5 commit 195b0fe
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 7 deletions.
17 changes: 17 additions & 0 deletions lib/tsan/rtl/tsan_interceptors_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,21 @@ INTERCEPTOR(int, pthread_cond_timedwait, void *c, void *m, void *abstime) {
m);
}

#if SANITIZER_LINUX
INTERCEPTOR(int, pthread_cond_clockwait, void *c, void *m,
__sanitizer_clockid_t clock, void *abstime) {
void *cond = init_cond(c);
SCOPED_TSAN_INTERCEPTOR(pthread_cond_clockwait, cond, m, clock, abstime);
return cond_wait(
thr, pc, &si,
[=]() { return REAL(pthread_cond_clockwait)(cond, m, clock, abstime); },
cond, m);
}
#define TSAN_MAYBE_PTHREAD_COND_CLOCKWAIT TSAN_INTERCEPT(pthread_cond_clockwait)
#else
#define TSAN_MAYBE_PTHREAD_COND_CLOCKWAIT
#endif

#if SANITIZER_MAC
INTERCEPTOR(int, pthread_cond_timedwait_relative_np, void *c, void *m,
void *reltime) {
Expand Down Expand Up @@ -2716,6 +2731,8 @@ void InitializeInterceptors() {
TSAN_INTERCEPT_VER(pthread_cond_timedwait, PTHREAD_ABI_BASE);
TSAN_INTERCEPT_VER(pthread_cond_destroy, PTHREAD_ABI_BASE);

TSAN_MAYBE_PTHREAD_COND_CLOCKWAIT;

TSAN_INTERCEPT(pthread_mutex_init);
TSAN_INTERCEPT(pthread_mutex_destroy);
TSAN_INTERCEPT(pthread_mutex_trylock);
Expand Down
14 changes: 7 additions & 7 deletions test/lit.common.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,10 +360,10 @@ def get_macos_aligned_version(macos_vers):
except ValueError:
lit_config.fatal("Failed to read ro.build.version.sdk (using '%s' as adb): got '%s'" % (adb, android_api_level_str))
android_api_level = min(android_api_level, int(config.android_api_level))
if android_api_level >= 26:
config.available_features.add('android-26')
if android_api_level >= 28:
config.available_features.add('android-28')
for required in [26, 28, 30]:
if android_api_level >= required:
config.available_features.add('android-%s' % required)
# FIXME: Replace with appropriate version when availible.
if android_api_level > 30 or (android_api_level == 30 and android_api_codename == 'S'):
config.available_features.add('android-thread-properties-api')

Expand All @@ -389,9 +389,9 @@ def get_macos_aligned_version(macos_vers):
if not config.android and ver_line.startswith(b"ldd "):
from distutils.version import LooseVersion
ver = LooseVersion(ver_line.split()[-1].decode())
# 2.27 introduced some incompatibilities
if ver >= LooseVersion("2.27"):
config.available_features.add("glibc-2.27")
for required in ["2.27", "2.30"]:
if ver >= LooseVersion(required):
config.available_features.add("glibc-" + required)

sancovcc_path = os.path.join(config.llvm_tools_dir, "sancov")
if os.path.exists(sancovcc_path):
Expand Down
32 changes: 32 additions & 0 deletions test/tsan/Linux/clockwait_double_lock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Regression test for https://github.com/google/sanitizers/issues/1259
// RUN: %clang_tsan -O1 %s -o %t && %run %t
// REQUIRES: glibc-2.30 || android-30

#define _GNU_SOURCE
#include <pthread.h>

pthread_cond_t cv;
pthread_mutex_t mtx;

void *fn(void *vp) {
pthread_mutex_lock(&mtx);
pthread_cond_signal(&cv);
pthread_mutex_unlock(&mtx);
return NULL;
}

int main() {
pthread_mutex_lock(&mtx);

pthread_t tid;
pthread_create(&tid, NULL, fn, NULL);

struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
ts.tv_sec += 10;
pthread_cond_clockwait(&cv, &mtx, CLOCK_MONOTONIC, &ts);
pthread_mutex_unlock(&mtx);

pthread_join(tid, NULL);
return 0;
}

0 comments on commit 195b0fe

Please sign in to comment.