Skip to content

Commit e2a5aa2

Browse files
committed
[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 (cherry picked from commit 7cc4472)
1 parent 2453cd2 commit e2a5aa2

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
@@ -633,26 +615,35 @@ INTERCEPTOR(mode_t, umask, mode_t cmask) {
633615
#pragma clang diagnostic push
634616
// OSSpinLockLock is deprecated, but still in use in libc++
635617
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
618+
#undef OSSpinLockLock
619+
636620
INTERCEPTOR(void, OSSpinLockLock, volatile OSSpinLock *lock) {
637621
__rtsan_notify_intercepted_call("OSSpinLockLock");
638622
return REAL(OSSpinLockLock)(lock);
639623
}
640-
#pragma clang diagnostic pop
624+
641625
#define RTSAN_MAYBE_INTERCEPT_OSSPINLOCKLOCK INTERCEPT_FUNCTION(OSSpinLockLock)
642626
#else
643627
#define RTSAN_MAYBE_INTERCEPT_OSSPINLOCKLOCK
644628
#endif // SANITIZER_APPLE
645629

646630
#if SANITIZER_APPLE
647-
INTERCEPTOR(void, os_unfair_lock_lock, os_unfair_lock_t lock) {
648-
__rtsan_notify_intercepted_call("os_unfair_lock_lock");
649-
return REAL(os_unfair_lock_lock)(lock);
650-
}
631+
// _os_nospin_lock_lock may replace OSSpinLockLock due to deprecation macro.
632+
typedef volatile OSSpinLock *_os_nospin_lock_t;
651633

652634
INTERCEPTOR(void, _os_nospin_lock_lock, _os_nospin_lock_t lock) {
653635
__rtsan_notify_intercepted_call("_os_nospin_lock_lock");
654636
return REAL(_os_nospin_lock_lock)(lock);
655637
}
638+
#pragma clang diagnostic pop // "-Wdeprecated-declarations"
639+
#endif // SANITIZER_APPLE
640+
641+
#if SANITIZER_APPLE
642+
INTERCEPTOR(void, os_unfair_lock_lock, os_unfair_lock_t lock) {
643+
__rtsan_notify_intercepted_call("os_unfair_lock_lock");
644+
return REAL(os_unfair_lock_lock)(lock);
645+
}
646+
656647
#define RTSAN_MAYBE_INTERCEPT_OS_UNFAIR_LOCK_LOCK \
657648
INTERCEPT_FUNCTION(os_unfair_lock_lock)
658649
#else

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

+18-22
Original file line numberDiff line numberDiff line change
@@ -1036,10 +1036,18 @@ TEST(TestRtsanInterceptors, PthreadJoinDiesWhenRealtime) {
10361036
}
10371037

10381038
#if SANITIZER_APPLE
1039-
10401039
#pragma clang diagnostic push
10411040
// OSSpinLockLock is deprecated, but still in use in libc++
10421041
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
1042+
#undef OSSpinLockLock
1043+
extern "C" {
1044+
typedef int32_t OSSpinLock;
1045+
void OSSpinLockLock(volatile OSSpinLock *__lock);
1046+
// _os_nospin_lock_lock may replace OSSpinLockLock due to deprecation macro.
1047+
typedef volatile OSSpinLock *_os_nospin_lock_t;
1048+
void _os_nospin_lock_lock(_os_nospin_lock_t lock);
1049+
}
1050+
10431051
TEST(TestRtsanInterceptors, OsSpinLockLockDiesWhenRealtime) {
10441052
auto Func = []() {
10451053
OSSpinLock spin_lock{};
@@ -1048,7 +1056,14 @@ TEST(TestRtsanInterceptors, OsSpinLockLockDiesWhenRealtime) {
10481056
ExpectRealtimeDeath(Func, "OSSpinLockLock");
10491057
ExpectNonRealtimeSurvival(Func);
10501058
}
1051-
#pragma clang diagnostic pop
1059+
1060+
TEST(TestRtsanInterceptors, OsNoSpinLockLockDiesWhenRealtime) {
1061+
OSSpinLock lock{};
1062+
auto Func = [&]() { _os_nospin_lock_lock(&lock); };
1063+
ExpectRealtimeDeath(Func, "_os_nospin_lock_lock");
1064+
ExpectNonRealtimeSurvival(Func);
1065+
}
1066+
#pragma clang diagnostic pop //"-Wdeprecated-declarations"
10521067

10531068
TEST(TestRtsanInterceptors, OsUnfairLockLockDiesWhenRealtime) {
10541069
auto Func = []() {
@@ -1058,26 +1073,7 @@ TEST(TestRtsanInterceptors, OsUnfairLockLockDiesWhenRealtime) {
10581073
ExpectRealtimeDeath(Func, "os_unfair_lock_lock");
10591074
ExpectNonRealtimeSurvival(Func);
10601075
}
1061-
1062-
// We intercept _os_nospin_lock_lock because it's the internal
1063-
// locking mechanism for MacOS's atomic implementation for data
1064-
// types that are larger than the hardware's maximum lock-free size.
1065-
// However, it's a private implementation detail and not visible in any headers,
1066-
// so we must duplicate the required type definitions to forward declaration
1067-
// what we need here.
1068-
extern "C" {
1069-
struct _os_nospin_lock_s {
1070-
unsigned int oul_value;
1071-
};
1072-
void _os_nospin_lock_lock(_os_nospin_lock_s *);
1073-
}
1074-
TEST(TestRtsanInterceptors, OsNoSpinLockLockDiesWhenRealtime) {
1075-
_os_nospin_lock_s lock{};
1076-
auto Func = [&]() { _os_nospin_lock_lock(&lock); };
1077-
ExpectRealtimeDeath(Func, "_os_nospin_lock_lock");
1078-
ExpectNonRealtimeSurvival(Func);
1079-
}
1080-
#endif
1076+
#endif // SANITIZER_APPLE
10811077

10821078
#if SANITIZER_LINUX
10831079
TEST(TestRtsanInterceptors, SpinLockLockDiesWhenRealtime) {

0 commit comments

Comments
 (0)