Skip to content

Commit 236820c

Browse files
committed
[RTSan][Darwin] Fix OSSpinLock interceptors and tests
These changes align with these lock types and allows builds and tests to pass with various SDKS. rdar://147067322
1 parent 8d3dc1e commit 236820c

File tree

2 files changed

+27
-44
lines changed

2 files changed

+27
-44
lines changed

compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,6 @@
2121
#include "rtsan/rtsan.h"
2222

2323
#if SANITIZER_APPLE
24-
25-
#if TARGET_OS_MAC
26-
// On MacOS OSSpinLockLock is deprecated and no longer present in the headers,
27-
// but the symbol still exists on the system. Forward declare here so we
28-
// don't get compilation errors.
29-
#include <stdint.h>
30-
extern "C" {
31-
typedef int32_t OSSpinLock;
32-
void OSSpinLockLock(volatile OSSpinLock *__lock);
33-
// A pointer to this type is in the interface for `_os_nospin_lock_lock`, but
34-
// it's an internal implementation detail of `os/lock.c` on Darwin, and
35-
// therefore not available in any headers. As a workaround, we forward declare
36-
// it here, which is enough to facilitate interception of _os_nospin_lock_lock.
37-
struct _os_nospin_lock_s;
38-
using _os_nospin_lock_t = _os_nospin_lock_s *;
39-
}
40-
#endif // TARGET_OS_MAC
41-
4224
#include <libkern/OSAtomic.h>
4325
#include <os/lock.h>
4426
#endif // SANITIZER_APPLE
@@ -706,26 +688,34 @@ INTERCEPTOR(mode_t, umask, mode_t cmask) {
706688
#pragma clang diagnostic push
707689
// OSSpinLockLock is deprecated, but still in use in libc++
708690
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
691+
#undef OSSpinLockLock
692+
709693
INTERCEPTOR(void, OSSpinLockLock, volatile OSSpinLock *lock) {
710694
__rtsan_notify_intercepted_call("OSSpinLockLock");
711695
return REAL(OSSpinLockLock)(lock);
712696
}
713-
#pragma clang diagnostic pop
697+
714698
#define RTSAN_MAYBE_INTERCEPT_OSSPINLOCKLOCK INTERCEPT_FUNCTION(OSSpinLockLock)
715699
#else
716700
#define RTSAN_MAYBE_INTERCEPT_OSSPINLOCKLOCK
717701
#endif // SANITIZER_APPLE
718702

719703
#if SANITIZER_APPLE
720-
INTERCEPTOR(void, os_unfair_lock_lock, os_unfair_lock_t lock) {
721-
__rtsan_notify_intercepted_call("os_unfair_lock_lock");
722-
return REAL(os_unfair_lock_lock)(lock);
723-
}
704+
typedef volatile OSSpinLock *_os_nospin_lock_t;
724705

725706
INTERCEPTOR(void, _os_nospin_lock_lock, _os_nospin_lock_t lock) {
726707
__rtsan_notify_intercepted_call("_os_nospin_lock_lock");
727708
return REAL(_os_nospin_lock_lock)(lock);
728709
}
710+
#endif // SANITIZER_APPLE
711+
#pragma clang diagnostic pop // "-Wdeprecated-declarations"
712+
713+
#if SANITIZER_APPLE
714+
INTERCEPTOR(void, os_unfair_lock_lock, os_unfair_lock_t lock) {
715+
__rtsan_notify_intercepted_call("os_unfair_lock_lock");
716+
return REAL(os_unfair_lock_lock)(lock);
717+
}
718+
729719
#define RTSAN_MAYBE_INTERCEPT_OS_UNFAIR_LOCK_LOCK \
730720
INTERCEPT_FUNCTION(os_unfair_lock_lock)
731721
#else

compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,11 @@ TEST(TestRtsanInterceptors, PthreadJoinDiesWhenRealtime) {
11131113
#pragma clang diagnostic push
11141114
// OSSpinLockLock is deprecated, but still in use in libc++
11151115
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
1116+
#undef OSSpinLockLock
1117+
extern "C" {
1118+
typedef int32_t OSSpinLock;
1119+
void OSSpinLockLock(volatile OSSpinLock *__lock);
1120+
}
11161121
TEST(TestRtsanInterceptors, OsSpinLockLockDiesWhenRealtime) {
11171122
auto Func = []() {
11181123
OSSpinLock spin_lock{};
@@ -1121,7 +1126,15 @@ TEST(TestRtsanInterceptors, OsSpinLockLockDiesWhenRealtime) {
11211126
ExpectRealtimeDeath(Func, "OSSpinLockLock");
11221127
ExpectNonRealtimeSurvival(Func);
11231128
}
1124-
#pragma clang diagnostic pop
1129+
1130+
TEST(TestRtsanInterceptors, OsNoSpinLockLockDiesWhenRealtime) {
1131+
OSSpinLock lock{};
1132+
auto Func = [&]() { _os_nospin_lock_lock(&lock); };
1133+
ExpectRealtimeDeath(Func, "_os_nospin_lock_lock");
1134+
ExpectNonRealtimeSurvival(Func);
1135+
}
1136+
#endif // SANITIZER_APPLE
1137+
#pragma clang diagnostic pop //"-Wdeprecated-declarations"
11251138

11261139
TEST(TestRtsanInterceptors, OsUnfairLockLockDiesWhenRealtime) {
11271140
auto Func = []() {
@@ -1132,26 +1145,6 @@ TEST(TestRtsanInterceptors, OsUnfairLockLockDiesWhenRealtime) {
11321145
ExpectNonRealtimeSurvival(Func);
11331146
}
11341147

1135-
// We intercept _os_nospin_lock_lock because it's the internal
1136-
// locking mechanism for MacOS's atomic implementation for data
1137-
// types that are larger than the hardware's maximum lock-free size.
1138-
// However, it's a private implementation detail and not visible in any headers,
1139-
// so we must duplicate the required type definitions to forward declaration
1140-
// what we need here.
1141-
extern "C" {
1142-
struct _os_nospin_lock_s {
1143-
unsigned int oul_value;
1144-
};
1145-
void _os_nospin_lock_lock(_os_nospin_lock_s *);
1146-
}
1147-
TEST(TestRtsanInterceptors, OsNoSpinLockLockDiesWhenRealtime) {
1148-
_os_nospin_lock_s lock{};
1149-
auto Func = [&]() { _os_nospin_lock_lock(&lock); };
1150-
ExpectRealtimeDeath(Func, "_os_nospin_lock_lock");
1151-
ExpectNonRealtimeSurvival(Func);
1152-
}
1153-
#endif
1154-
11551148
#if SANITIZER_LINUX
11561149
TEST(TestRtsanInterceptors, SpinLockLockDiesWhenRealtime) {
11571150
pthread_spinlock_t spin_lock;

0 commit comments

Comments
 (0)