[RTSan][Darwin] Adjust OSSpinLock/_os_nospin_lock interceptor and tests (#132867)
These changes align with these lock types and allows builds and tests to pass with various SDKS. rdar://147067322
This commit is contained in:
parent
3191cfd824
commit
7cc4472037
@ -21,24 +21,6 @@
|
||||
#include "rtsan/rtsan.h"
|
||||
|
||||
#if SANITIZER_APPLE
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
// On MacOS OSSpinLockLock is deprecated and no longer present in the headers,
|
||||
// but the symbol still exists on the system. Forward declare here so we
|
||||
// don't get compilation errors.
|
||||
#include <stdint.h>
|
||||
extern "C" {
|
||||
typedef int32_t OSSpinLock;
|
||||
void OSSpinLockLock(volatile OSSpinLock *__lock);
|
||||
// A pointer to this type is in the interface for `_os_nospin_lock_lock`, but
|
||||
// it's an internal implementation detail of `os/lock.c` on Darwin, and
|
||||
// therefore not available in any headers. As a workaround, we forward declare
|
||||
// it here, which is enough to facilitate interception of _os_nospin_lock_lock.
|
||||
struct _os_nospin_lock_s;
|
||||
using _os_nospin_lock_t = _os_nospin_lock_s *;
|
||||
}
|
||||
#endif // TARGET_OS_MAC
|
||||
|
||||
#include <libkern/OSAtomic.h>
|
||||
#include <os/lock.h>
|
||||
#endif // SANITIZER_APPLE
|
||||
@ -717,26 +699,35 @@ INTERCEPTOR(mode_t, umask, mode_t cmask) {
|
||||
#pragma clang diagnostic push
|
||||
// OSSpinLockLock is deprecated, but still in use in libc++
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
#undef OSSpinLockLock
|
||||
|
||||
INTERCEPTOR(void, OSSpinLockLock, volatile OSSpinLock *lock) {
|
||||
__rtsan_notify_intercepted_call("OSSpinLockLock");
|
||||
return REAL(OSSpinLockLock)(lock);
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
#define RTSAN_MAYBE_INTERCEPT_OSSPINLOCKLOCK INTERCEPT_FUNCTION(OSSpinLockLock)
|
||||
#else
|
||||
#define RTSAN_MAYBE_INTERCEPT_OSSPINLOCKLOCK
|
||||
#endif // SANITIZER_APPLE
|
||||
|
||||
#if SANITIZER_APPLE
|
||||
// _os_nospin_lock_lock may replace OSSpinLockLock due to deprecation macro.
|
||||
typedef volatile OSSpinLock *_os_nospin_lock_t;
|
||||
|
||||
INTERCEPTOR(void, _os_nospin_lock_lock, _os_nospin_lock_t lock) {
|
||||
__rtsan_notify_intercepted_call("_os_nospin_lock_lock");
|
||||
return REAL(_os_nospin_lock_lock)(lock);
|
||||
}
|
||||
#pragma clang diagnostic pop // "-Wdeprecated-declarations"
|
||||
#endif // SANITIZER_APPLE
|
||||
|
||||
#if SANITIZER_APPLE
|
||||
INTERCEPTOR(void, os_unfair_lock_lock, os_unfair_lock_t lock) {
|
||||
__rtsan_notify_intercepted_call("os_unfair_lock_lock");
|
||||
return REAL(os_unfair_lock_lock)(lock);
|
||||
}
|
||||
|
||||
INTERCEPTOR(void, _os_nospin_lock_lock, _os_nospin_lock_t lock) {
|
||||
__rtsan_notify_intercepted_call("_os_nospin_lock_lock");
|
||||
return REAL(_os_nospin_lock_lock)(lock);
|
||||
}
|
||||
#define RTSAN_MAYBE_INTERCEPT_OS_UNFAIR_LOCK_LOCK \
|
||||
INTERCEPT_FUNCTION(os_unfair_lock_lock)
|
||||
#else
|
||||
|
@ -1126,10 +1126,18 @@ TEST(TestRtsanInterceptors, PthreadJoinDiesWhenRealtime) {
|
||||
}
|
||||
|
||||
#if SANITIZER_APPLE
|
||||
|
||||
#pragma clang diagnostic push
|
||||
// OSSpinLockLock is deprecated, but still in use in libc++
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
#undef OSSpinLockLock
|
||||
extern "C" {
|
||||
typedef int32_t OSSpinLock;
|
||||
void OSSpinLockLock(volatile OSSpinLock *__lock);
|
||||
// _os_nospin_lock_lock may replace OSSpinLockLock due to deprecation macro.
|
||||
typedef volatile OSSpinLock *_os_nospin_lock_t;
|
||||
void _os_nospin_lock_lock(_os_nospin_lock_t lock);
|
||||
}
|
||||
|
||||
TEST(TestRtsanInterceptors, OsSpinLockLockDiesWhenRealtime) {
|
||||
auto Func = []() {
|
||||
OSSpinLock spin_lock{};
|
||||
@ -1138,7 +1146,14 @@ TEST(TestRtsanInterceptors, OsSpinLockLockDiesWhenRealtime) {
|
||||
ExpectRealtimeDeath(Func, "OSSpinLockLock");
|
||||
ExpectNonRealtimeSurvival(Func);
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
TEST(TestRtsanInterceptors, OsNoSpinLockLockDiesWhenRealtime) {
|
||||
OSSpinLock lock{};
|
||||
auto Func = [&]() { _os_nospin_lock_lock(&lock); };
|
||||
ExpectRealtimeDeath(Func, "_os_nospin_lock_lock");
|
||||
ExpectNonRealtimeSurvival(Func);
|
||||
}
|
||||
#pragma clang diagnostic pop //"-Wdeprecated-declarations"
|
||||
|
||||
TEST(TestRtsanInterceptors, OsUnfairLockLockDiesWhenRealtime) {
|
||||
auto Func = []() {
|
||||
@ -1148,26 +1163,7 @@ TEST(TestRtsanInterceptors, OsUnfairLockLockDiesWhenRealtime) {
|
||||
ExpectRealtimeDeath(Func, "os_unfair_lock_lock");
|
||||
ExpectNonRealtimeSurvival(Func);
|
||||
}
|
||||
|
||||
// We intercept _os_nospin_lock_lock because it's the internal
|
||||
// locking mechanism for MacOS's atomic implementation for data
|
||||
// types that are larger than the hardware's maximum lock-free size.
|
||||
// However, it's a private implementation detail and not visible in any headers,
|
||||
// so we must duplicate the required type definitions to forward declaration
|
||||
// what we need here.
|
||||
extern "C" {
|
||||
struct _os_nospin_lock_s {
|
||||
unsigned int oul_value;
|
||||
};
|
||||
void _os_nospin_lock_lock(_os_nospin_lock_s *);
|
||||
}
|
||||
TEST(TestRtsanInterceptors, OsNoSpinLockLockDiesWhenRealtime) {
|
||||
_os_nospin_lock_s lock{};
|
||||
auto Func = [&]() { _os_nospin_lock_lock(&lock); };
|
||||
ExpectRealtimeDeath(Func, "_os_nospin_lock_lock");
|
||||
ExpectNonRealtimeSurvival(Func);
|
||||
}
|
||||
#endif
|
||||
#endif // SANITIZER_APPLE
|
||||
|
||||
#if SANITIZER_LINUX
|
||||
TEST(TestRtsanInterceptors, SpinLockLockDiesWhenRealtime) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user