Skip to content

Commit 7cc4472

Browse files
[RTSan][Darwin] Adjust OSSpinLock/_os_nospin_lock interceptor and tests (llvm#132867)
These changes align with these lock types and allows builds and tests to pass with various SDKS. rdar://147067322
1 parent 3191cfd commit 7cc4472

File tree

2 files changed

+32
-45
lines changed

2 files changed

+32
-45
lines changed

compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp

+14-23
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
@@ -717,26 +699,35 @@ INTERCEPTOR(mode_t, umask, mode_t cmask) {
717699
#pragma clang diagnostic push
718700
// OSSpinLockLock is deprecated, but still in use in libc++
719701
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
702+
#undef OSSpinLockLock
703+
720704
INTERCEPTOR(void, OSSpinLockLock, volatile OSSpinLock *lock) {
721705
__rtsan_notify_intercepted_call("OSSpinLockLock");
722706
return REAL(OSSpinLockLock)(lock);
723707
}
724-
#pragma clang diagnostic pop
708+
725709
#define RTSAN_MAYBE_INTERCEPT_OSSPINLOCKLOCK INTERCEPT_FUNCTION(OSSpinLockLock)
726710
#else
727711
#define RTSAN_MAYBE_INTERCEPT_OSSPINLOCKLOCK
728712
#endif // SANITIZER_APPLE
729713

730714
#if SANITIZER_APPLE
731-
INTERCEPTOR(void, os_unfair_lock_lock, os_unfair_lock_t lock) {
732-
__rtsan_notify_intercepted_call("os_unfair_lock_lock");
733-
return REAL(os_unfair_lock_lock)(lock);
734-
}
715+
// _os_nospin_lock_lock may replace OSSpinLockLock due to deprecation macro.
716+
typedef volatile OSSpinLock *_os_nospin_lock_t;
735717

736718
INTERCEPTOR(void, _os_nospin_lock_lock, _os_nospin_lock_t lock) {
737719
__rtsan_notify_intercepted_call("_os_nospin_lock_lock");
738720
return REAL(_os_nospin_lock_lock)(lock);
739721
}
722+
#pragma clang diagnostic pop // "-Wdeprecated-declarations"
723+
#endif // SANITIZER_APPLE
724+
725+
#if SANITIZER_APPLE
726+
INTERCEPTOR(void, os_unfair_lock_lock, os_unfair_lock_t lock) {
727+
__rtsan_notify_intercepted_call("os_unfair_lock_lock");
728+
return REAL(os_unfair_lock_lock)(lock);
729+
}
730+
740731
#define RTSAN_MAYBE_INTERCEPT_OS_UNFAIR_LOCK_LOCK \
741732
INTERCEPT_FUNCTION(os_unfair_lock_lock)
742733
#else

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

+18-22
Original file line numberDiff line numberDiff line change
@@ -1126,10 +1126,18 @@ TEST(TestRtsanInterceptors, PthreadJoinDiesWhenRealtime) {
11261126
}
11271127

11281128
#if SANITIZER_APPLE
1129-
11301129
#pragma clang diagnostic push
11311130
// OSSpinLockLock is deprecated, but still in use in libc++
11321131
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
1132+
#undef OSSpinLockLock
1133+
extern "C" {
1134+
typedef int32_t OSSpinLock;
1135+
void OSSpinLockLock(volatile OSSpinLock *__lock);
1136+
// _os_nospin_lock_lock may replace OSSpinLockLock due to deprecation macro.
1137+
typedef volatile OSSpinLock *_os_nospin_lock_t;
1138+
void _os_nospin_lock_lock(_os_nospin_lock_t lock);
1139+
}
1140+
11331141
TEST(TestRtsanInterceptors, OsSpinLockLockDiesWhenRealtime) {
11341142
auto Func = []() {
11351143
OSSpinLock spin_lock{};
@@ -1138,7 +1146,14 @@ TEST(TestRtsanInterceptors, OsSpinLockLockDiesWhenRealtime) {
11381146
ExpectRealtimeDeath(Func, "OSSpinLockLock");
11391147
ExpectNonRealtimeSurvival(Func);
11401148
}
1141-
#pragma clang diagnostic pop
1149+
1150+
TEST(TestRtsanInterceptors, OsNoSpinLockLockDiesWhenRealtime) {
1151+
OSSpinLock lock{};
1152+
auto Func = [&]() { _os_nospin_lock_lock(&lock); };
1153+
ExpectRealtimeDeath(Func, "_os_nospin_lock_lock");
1154+
ExpectNonRealtimeSurvival(Func);
1155+
}
1156+
#pragma clang diagnostic pop //"-Wdeprecated-declarations"
11421157

11431158
TEST(TestRtsanInterceptors, OsUnfairLockLockDiesWhenRealtime) {
11441159
auto Func = []() {
@@ -1148,26 +1163,7 @@ TEST(TestRtsanInterceptors, OsUnfairLockLockDiesWhenRealtime) {
11481163
ExpectRealtimeDeath(Func, "os_unfair_lock_lock");
11491164
ExpectNonRealtimeSurvival(Func);
11501165
}
1151-
1152-
// We intercept _os_nospin_lock_lock because it's the internal
1153-
// locking mechanism for MacOS's atomic implementation for data
1154-
// types that are larger than the hardware's maximum lock-free size.
1155-
// However, it's a private implementation detail and not visible in any headers,
1156-
// so we must duplicate the required type definitions to forward declaration
1157-
// what we need here.
1158-
extern "C" {
1159-
struct _os_nospin_lock_s {
1160-
unsigned int oul_value;
1161-
};
1162-
void _os_nospin_lock_lock(_os_nospin_lock_s *);
1163-
}
1164-
TEST(TestRtsanInterceptors, OsNoSpinLockLockDiesWhenRealtime) {
1165-
_os_nospin_lock_s lock{};
1166-
auto Func = [&]() { _os_nospin_lock_lock(&lock); };
1167-
ExpectRealtimeDeath(Func, "_os_nospin_lock_lock");
1168-
ExpectNonRealtimeSurvival(Func);
1169-
}
1170-
#endif
1166+
#endif // SANITIZER_APPLE
11711167

11721168
#if SANITIZER_LINUX
11731169
TEST(TestRtsanInterceptors, SpinLockLockDiesWhenRealtime) {

0 commit comments

Comments
 (0)