[clang] [compiler-rt] [compiler-rt] Realtime Sanitizer: Introduce RADSan backend (PR #92460)
via cfe-commits
cfe-commits at lists.llvm.org
Fri May 31 14:37:42 PDT 2024
https://github.com/davidtrevelyan updated https://github.com/llvm/llvm-project/pull/92460
>From c46c3243c0455e0f93914fb28f19fbc87ad876a4 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Tue, 7 May 2024 12:24:53 -0700
Subject: [PATCH 01/33] First try
---
clang/include/clang/Basic/Sanitizers.def | 3 +
clang/include/clang/Driver/SanitizerArgs.h | 1 +
clang/lib/Driver/ToolChains/CommonArgs.cpp | 6 +
clang/lib/Driver/ToolChains/Darwin.cpp | 8 +
clang/lib/Driver/ToolChains/Linux.cpp | 1 +
clang/runtime/CMakeLists.txt | 1 +
.../cmake/Modules/AllSupportedArchDefs.cmake | 3 +
compiler-rt/cmake/config-ix.cmake | 12 +-
compiler-rt/lib/radsan/CMakeLists.txt | 92 ++++
compiler-rt/lib/radsan/radsan.cpp | 34 ++
compiler-rt/lib/radsan/radsan.h | 75 +++
compiler-rt/lib/radsan/radsan_context.cpp | 82 ++++
compiler-rt/lib/radsan/radsan_context.h | 38 ++
.../lib/radsan/radsan_interceptors.cpp | 412 ++++++++++++++++
compiler-rt/lib/radsan/radsan_interceptors.h | 15 +
compiler-rt/lib/radsan/radsan_preinit.cpp | 23 +
compiler-rt/lib/radsan/radsan_stack.cpp | 52 ++
compiler-rt/lib/radsan/radsan_stack.h | 15 +
compiler-rt/lib/radsan/tests/CMakeLists.txt | 103 ++++
compiler-rt/lib/radsan/tests/radsan_test.cpp | 203 ++++++++
.../lib/radsan/tests/radsan_test_context.cpp | 69 +++
.../radsan/tests/radsan_test_interceptors.cpp | 454 ++++++++++++++++++
.../lib/radsan/tests/radsan_test_main.cpp | 17 +
.../lib/radsan/tests/radsan_test_utilities.h | 49 ++
compiler-rt/test/radsan/CMakeLists.txt | 47 ++
.../test/radsan/Unit/lit.site.cfg.py.in | 25 +
compiler-rt/test/radsan/lit.cfg.py | 69 +++
compiler-rt/test/radsan/lit.site.cfg.py.in | 17 +
.../test/sanitizer_common/CMakeLists.txt | 2 +-
.../test/sanitizer_common/lit.common.cfg.py | 3 +
30 files changed, 1929 insertions(+), 2 deletions(-)
create mode 100644 compiler-rt/lib/radsan/CMakeLists.txt
create mode 100644 compiler-rt/lib/radsan/radsan.cpp
create mode 100644 compiler-rt/lib/radsan/radsan.h
create mode 100644 compiler-rt/lib/radsan/radsan_context.cpp
create mode 100644 compiler-rt/lib/radsan/radsan_context.h
create mode 100644 compiler-rt/lib/radsan/radsan_interceptors.cpp
create mode 100644 compiler-rt/lib/radsan/radsan_interceptors.h
create mode 100644 compiler-rt/lib/radsan/radsan_preinit.cpp
create mode 100644 compiler-rt/lib/radsan/radsan_stack.cpp
create mode 100644 compiler-rt/lib/radsan/radsan_stack.h
create mode 100644 compiler-rt/lib/radsan/tests/CMakeLists.txt
create mode 100644 compiler-rt/lib/radsan/tests/radsan_test.cpp
create mode 100644 compiler-rt/lib/radsan/tests/radsan_test_context.cpp
create mode 100644 compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
create mode 100644 compiler-rt/lib/radsan/tests/radsan_test_main.cpp
create mode 100644 compiler-rt/lib/radsan/tests/radsan_test_utilities.h
create mode 100644 compiler-rt/test/radsan/CMakeLists.txt
create mode 100644 compiler-rt/test/radsan/Unit/lit.site.cfg.py.in
create mode 100644 compiler-rt/test/radsan/lit.cfg.py
create mode 100644 compiler-rt/test/radsan/lit.site.cfg.py.in
diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def
index b228ffd07ee74..ffb23974fe371 100644
--- a/clang/include/clang/Basic/Sanitizers.def
+++ b/clang/include/clang/Basic/Sanitizers.def
@@ -37,6 +37,9 @@
#endif
+// RealtimeSanitizer
+SANITIZER("realtime", Realtime)
+
// AddressSanitizer
SANITIZER("address", Address)
diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h
index 07070ec4fc065..dd7c128232772 100644
--- a/clang/include/clang/Driver/SanitizerArgs.h
+++ b/clang/include/clang/Driver/SanitizerArgs.h
@@ -79,6 +79,7 @@ class SanitizerArgs {
bool needsStableAbi() const { return StableABI; }
bool needsMemProfRt() const { return NeedsMemProfRt; }
+ bool needsRadsanRt() const { return Sanitizers.has(SanitizerKind::Realtime); }
bool needsAsanRt() const { return Sanitizers.has(SanitizerKind::Address); }
bool needsHwasanRt() const {
return Sanitizers.has(SanitizerKind::HWAddress);
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 71e993119436a..002bf456dc026 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1357,6 +1357,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
if (!Args.hasArg(options::OPT_shared))
HelperStaticRuntimes.push_back("hwasan-preinit");
}
+ if (SanArgs.needsRadsanRt() && SanArgs.linkRuntimes())
+ SharedRuntimes.push_back("radsan");
}
// The stats_client library is also statically linked into DSOs.
@@ -1382,6 +1384,10 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
StaticRuntimes.push_back("asan_cxx");
}
+ if (!SanArgs.needsSharedRt() && SanArgs.needsRadsanRt() && SanArgs.linkRuntimes()) {
+ StaticRuntimes.push_back("radsan");
+ }
+
if (!SanArgs.needsSharedRt() && SanArgs.needsMemProfRt()) {
StaticRuntimes.push_back("memprof");
if (SanArgs.linkCXXRuntimes())
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index 593b403a1e3f0..1e04be42e4085 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -1487,6 +1487,8 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
const char *sanitizer = nullptr;
if (Sanitize.needsUbsanRt()) {
sanitizer = "UndefinedBehaviorSanitizer";
+ } else if (Sanitize.needsRadsanRt()) {
+ sanitizer = "RealtimeSanitizer";
} else if (Sanitize.needsAsanRt()) {
sanitizer = "AddressSanitizer";
} else if (Sanitize.needsTsanRt()) {
@@ -1509,6 +1511,11 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
AddLinkSanitizerLibArgs(Args, CmdArgs, "asan");
}
}
+ if(Sanitize.needsRadsanRt())
+ {
+ assert(Sanitize.needsSharedRt() && "Static sanitizer runtimes not supported");
+ AddLinkSanitizerLibArgs(Args, CmdArgs, "radsan");
+ }
if (Sanitize.needsLsanRt())
AddLinkSanitizerLibArgs(Args, CmdArgs, "lsan");
if (Sanitize.needsUbsanRt()) {
@@ -3445,6 +3452,7 @@ SanitizerMask Darwin::getSupportedSanitizers() const {
const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64;
SanitizerMask Res = ToolChain::getSupportedSanitizers();
Res |= SanitizerKind::Address;
+ Res |= SanitizerKind::Realtime;
Res |= SanitizerKind::PointerCompare;
Res |= SanitizerKind::PointerSubtract;
Res |= SanitizerKind::Leak;
diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
index db2c20d7b461d..416d530a36ff7 100644
--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -799,6 +799,7 @@ SanitizerMask Linux::getSupportedSanitizers() const {
const bool IsHexagon = getTriple().getArch() == llvm::Triple::hexagon;
SanitizerMask Res = ToolChain::getSupportedSanitizers();
Res |= SanitizerKind::Address;
+ Res |= SanitizerKind::Realtime;
Res |= SanitizerKind::PointerCompare;
Res |= SanitizerKind::PointerSubtract;
Res |= SanitizerKind::Fuzzer;
diff --git a/clang/runtime/CMakeLists.txt b/clang/runtime/CMakeLists.txt
index 65fcdc2868f03..c56bff11d476b 100644
--- a/clang/runtime/CMakeLists.txt
+++ b/clang/runtime/CMakeLists.txt
@@ -150,6 +150,7 @@ if(LLVM_BUILD_EXTERNAL_COMPILER_RT AND EXISTS ${COMPILER_RT_SRC_ROOT}/)
check-lsan
check-msan
check-profile
+ check-radsan
check-safestack
check-sanitizer
check-tsan
diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
index 2fe06273a814c..5017d236c1369 100644
--- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
+++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
@@ -32,6 +32,9 @@ set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64}
${LOONGARCH64})
set(ALL_ASAN_ABI_SUPPORTED_ARCH ${X86_64} ${ARM64} ${ARM64_32})
set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${LOONGARCH64})
+set(ALL_RADSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64}
+ ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}
+ ${LOONGARCH64})
if(ANDROID)
set(OS_NAME "Android")
diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake
index 42edbe15edafb..33a9d919a7e2a 100644
--- a/compiler-rt/cmake/config-ix.cmake
+++ b/compiler-rt/cmake/config-ix.cmake
@@ -612,6 +612,9 @@ if(APPLE)
list_intersect(ASAN_SUPPORTED_ARCH
ALL_ASAN_SUPPORTED_ARCH
SANITIZER_COMMON_SUPPORTED_ARCH)
+ list_intersect(RADSAN_SUPPORTED_ARCH
+ ALL_RADSAN_SUPPORTED_ARCH
+ SANITIZER_COMMON_SUPPORTED_ARCH)
list_intersect(DFSAN_SUPPORTED_ARCH
ALL_DFSAN_SUPPORTED_ARCH
SANITIZER_COMMON_SUPPORTED_ARCH)
@@ -675,6 +678,7 @@ else()
filter_available_targets(UBSAN_COMMON_SUPPORTED_ARCH
${SANITIZER_COMMON_SUPPORTED_ARCH})
filter_available_targets(ASAN_SUPPORTED_ARCH ${ALL_ASAN_SUPPORTED_ARCH})
+ filter_available_targets(RADSAN_SUPPORTED_ARCH ${ALL_RADSAN_SUPPORTED_ARCH})
filter_available_targets(FUZZER_SUPPORTED_ARCH ${ALL_FUZZER_SUPPORTED_ARCH})
filter_available_targets(DFSAN_SUPPORTED_ARCH ${ALL_DFSAN_SUPPORTED_ARCH})
filter_available_targets(LSAN_SUPPORTED_ARCH ${ALL_LSAN_SUPPORTED_ARCH})
@@ -727,7 +731,7 @@ if(COMPILER_RT_SUPPORTED_ARCH)
endif()
message(STATUS "Compiler-RT supported architectures: ${COMPILER_RT_SUPPORTED_ARCH}")
-set(ALL_SANITIZERS asan;dfsan;msan;hwasan;tsan;safestack;cfi;scudo_standalone;ubsan_minimal;gwp_asan;asan_abi)
+set(ALL_SANITIZERS asan;radsan;dfsan;msan;hwasan;tsan;safestack;cfi;scudo_standalone;ubsan_minimal;gwp_asan;asan_abi)
set(COMPILER_RT_SANITIZERS_TO_BUILD all CACHE STRING
"sanitizers to build if supported on the target (all;${ALL_SANITIZERS})")
list_replace(COMPILER_RT_SANITIZERS_TO_BUILD all "${ALL_SANITIZERS}")
@@ -758,6 +762,12 @@ else()
set(COMPILER_RT_HAS_ASAN FALSE)
endif()
+if (COMPILER_RT_HAS_SANITIZER_COMMON AND RADSAN_SUPPORTED_ARCH)
+ set(COMPILER_RT_HAS_RADSAN TRUE)
+else()
+ set(COMPILER_RT_HAS_RADSAN FALSE)
+endif()
+
if (OS_NAME MATCHES "Linux|FreeBSD|Windows|NetBSD|SunOS")
set(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME TRUE)
else()
diff --git a/compiler-rt/lib/radsan/CMakeLists.txt b/compiler-rt/lib/radsan/CMakeLists.txt
new file mode 100644
index 0000000000000..c7d1dacf3dbc7
--- /dev/null
+++ b/compiler-rt/lib/radsan/CMakeLists.txt
@@ -0,0 +1,92 @@
+include_directories(..)
+
+set(RADSAN_CXX_SOURCES
+ radsan.cpp
+ radsan_context.cpp
+ radsan_stack.cpp
+ radsan_interceptors.cpp)
+
+set(RADSAN_PREINIT_SOURCES
+ radsan_preinit.cpp)
+
+set(RADSAN_HEADERS
+ radsan.h
+ radsan_context.h
+ radsan_stack.h)
+
+set(RADSAN_DEPS)
+
+set(RADSAN_CFLAGS
+ ${COMPILER_RT_COMMON_CFLAGS}
+ ${COMPILER_RT_CXX_CFLAGS}
+ -DSANITIZER_COMMON_NO_REDEFINE_BUILTINS)
+set(RADSAN_LINK_FLAGS ${COMPILER_RT_COMMON_LINK_FLAGS})
+set(RADSAN_LINK_LIBS
+ ${COMPILER_RT_UNWINDER_LINK_LIBS}
+ ${COMPILER_RT_CXX_LINK_LIBS})
+
+if(APPLE)
+ add_compiler_rt_object_libraries(RTRadsan
+ OS ${SANITIZER_COMMON_SUPPORTED_OS}
+ ARCHS ${RADSAN_SUPPORTED_ARCH}
+ SOURCES ${RADSAN_CXX_SOURCES}
+ ADDITIONAL_HEADERS ${RADSAN_HEADERS}
+ CFLAGS ${RADSAN_CFLAGS}
+ DEPS ${RADSAN_DEPS})
+else()
+ add_compiler_rt_object_libraries(RTRadsan
+ ARCHS ${RADSAN_SUPPORTED_ARCH}
+ SOURCES ${RADSAN_CXX_SOURCES}
+ ADDITIONAL_HEADERS ${RADSAN_HEADERS}
+ CFLAGS ${RADSAN_CFLAGS}
+ DEPS ${RADSAN_DEPS})
+ add_compiler_rt_object_libraries(RTRadsan_preinit
+ ARCHS ${RADSAN_SUPPORTED_ARCH}
+ SOURCES ${RADSAN_PREINIT_SOURCES}
+ ADDITIONAL_HEADERS ${RADSAN_HEADERS}
+ CFLAGS ${RADSAN_CFLAGS})
+endif()
+
+set(RADSAN_COMMON_RUNTIME_OBJECT_LIBS
+ RTInterception
+ RTSanitizerCommon
+ RTSanitizerCommonLibc
+ RTSanitizerCommonCoverage
+ RTSanitizerCommonSymbolizer)
+
+append_list_if(COMPILER_RT_HAS_LIBDL dl RADSAN_LINK_LIBS)
+append_list_if(COMPILER_RT_HAS_LIBRT rt RADSAN_LINK_LIBS)
+append_list_if(COMPILER_RT_HAS_LIBM m RADSAN_LINK_LIBS)
+append_list_if(COMPILER_RT_HAS_LIBPTHREAD pthread RADSAN_LINK_LIBS)
+append_list_if(COMPILER_RT_HAS_LIBLOG log RADSAN_LINK_LIBS)
+
+add_compiler_rt_component(radsan)
+
+if (APPLE)
+ add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)
+ set(RADSAN_LINK_FLAGS ${RADSAN_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS})
+
+ add_compiler_rt_runtime(clang_rt.radsan
+ SHARED
+ OS ${SANITIZER_COMMON_SUPPORTED_OS}
+ ARCHS ${RADSAN_SUPPORTED_ARCH}
+ OBJECT_LIBS RTRadsan
+ ${RADSAN_COMMON_RUNTIME_OBJECT_LIBS}
+ LINK_FLAGS ${RADSAN_LINK_FLAGS}
+ LINK_LIBS ${RADSAN_LINK_LIBS}
+ PARENT_TARGET radsan)
+else()
+ add_compiler_rt_runtime(clang_rt.radsan
+ STATIC
+ ARCHS ${RADSAN_SUPPORTED_ARCH}
+ OBJECT_LIBS RTRadsan_preinit
+ RTRadsan
+ ${RADSAN_COMMON_RUNTIME_OBJECT_LIBS}
+ LINK_FLAGS ${RADSAN_LINK_FLAGS}
+ CFLAGS ${RADSAN_CFLAGS}
+ PARENT_TARGET radsan)
+endif()
+
+if(COMPILER_RT_INCLUDE_TESTS)
+ add_subdirectory(tests)
+endif()
diff --git a/compiler-rt/lib/radsan/radsan.cpp b/compiler-rt/lib/radsan/radsan.cpp
new file mode 100644
index 0000000000000..32a1f8223e55d
--- /dev/null
+++ b/compiler-rt/lib/radsan/radsan.cpp
@@ -0,0 +1,34 @@
+//===--- radsan.cpp - Realtime Sanitizer --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#include <radsan/radsan.h>
+#include <radsan/radsan_context.h>
+#include <radsan/radsan_interceptors.h>
+#include <unistd.h>
+
+extern "C" {
+RADSAN_EXPORT void radsan_init() { radsan::initialiseInterceptors(); }
+
+RADSAN_EXPORT void radsan_realtime_enter() {
+ radsan::getContextForThisThread().realtimePush();
+}
+
+RADSAN_EXPORT void radsan_realtime_exit() {
+ radsan::getContextForThisThread().realtimePop();
+}
+
+RADSAN_EXPORT void radsan_off() {
+ radsan::getContextForThisThread().bypassPush();
+}
+
+RADSAN_EXPORT void radsan_on() {
+ radsan::getContextForThisThread().bypassPop();
+}
+}
diff --git a/compiler-rt/lib/radsan/radsan.h b/compiler-rt/lib/radsan/radsan.h
new file mode 100644
index 0000000000000..684cedd499ae7
--- /dev/null
+++ b/compiler-rt/lib/radsan/radsan.h
@@ -0,0 +1,75 @@
+//===--- radsan.h - Realtime Sanitizer --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#pragma once
+
+#define RADSAN_EXPORT __attribute__((visibility("default")))
+
+extern "C" {
+
+/**
+ Initialise radsan interceptors. A call to this method is added to the
+ preinit array on Linux systems.
+
+ @warning Do not call this method as a user.
+*/
+RADSAN_EXPORT void radsan_init();
+
+/** Enter real-time context.
+
+ When in a real-time context, RADSan interceptors will error if realtime
+ violations are detected. Calls to this method are injected at the code
+ generation stage when RADSan is enabled.
+
+ @warning Do not call this method as a user
+*/
+RADSAN_EXPORT void radsan_realtime_enter();
+
+/** Exit the real-time context.
+
+ When not in a real-time context, RADSan interceptors will simply forward
+ intercepted method calls to the real methods.
+
+ @warning Do not call this method as a user
+*/
+RADSAN_EXPORT void radsan_realtime_exit();
+
+/** Disable all RADSan error reporting.
+
+ This method might be useful to you if RADSan is presenting you with an error
+ for some code you are confident is realtime safe. For example, you might
+ know that a mutex is never contested, and that locking it will never block
+ on your particular system. Be careful!
+
+ A call to `radsan_off()` MUST be paired with a corresponding `radsan_on()`
+ to reactivate interception after the code in question. If you don't, radsan
+ will cease to work.
+
+ Example:
+
+ float process (float x) [[clang::nonblocking]]
+ {
+ auto const y = 2.0f * x;
+
+ radsan_off();
+ i_know_this_method_is_realtime_safe_but_radsan_complains_about_it();
+ radsan_on();
+ }
+
+*/
+RADSAN_EXPORT void radsan_off();
+
+/** Re-enable all RADSan error reporting.
+
+ The counterpart to `radsan_off`. See the description for `radsan_off` for
+ details about how to use this method.
+*/
+RADSAN_EXPORT void radsan_on();
+}
diff --git a/compiler-rt/lib/radsan/radsan_context.cpp b/compiler-rt/lib/radsan/radsan_context.cpp
new file mode 100644
index 0000000000000..5ca70d3fd9dc5
--- /dev/null
+++ b/compiler-rt/lib/radsan/radsan_context.cpp
@@ -0,0 +1,82 @@
+//===--- radsan_context.cpp - Realtime Sanitizer --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#include <radsan/radsan_context.h>
+
+#include <radsan/radsan_stack.h>
+
+#include <sanitizer_common/sanitizer_allocator_internal.h>
+#include <sanitizer_common/sanitizer_stacktrace.h>
+
+#include <new>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+using namespace __sanitizer;
+
+namespace detail {
+
+static pthread_key_t key;
+static pthread_once_t key_once = PTHREAD_ONCE_INIT;
+void internalFree(void *ptr) { InternalFree(ptr); }
+
+} // namespace detail
+
+namespace radsan {
+
+Context::Context() = default;
+
+void Context::realtimePush() { realtime_depth_++; }
+
+void Context::realtimePop() { realtime_depth_--; }
+
+void Context::bypassPush() { bypass_depth_++; }
+
+void Context::bypassPop() { bypass_depth_--; }
+
+void Context::expectNotRealtime(const char *intercepted_function_name) {
+ if (inRealtimeContext() && !isBypassed()) {
+ bypassPush();
+ printDiagnostics(intercepted_function_name);
+ exit(EXIT_FAILURE);
+ bypassPop();
+ }
+}
+
+bool Context::inRealtimeContext() const { return realtime_depth_ > 0; }
+
+bool Context::isBypassed() const { return bypass_depth_ > 0; }
+
+void Context::printDiagnostics(const char *intercepted_function_name) {
+ fprintf(stderr,
+ "Real-time violation: intercepted call to real-time unsafe function "
+ "`%s` in real-time context! Stack trace:\n",
+ intercepted_function_name);
+ radsan::printStackTrace();
+}
+
+Context &getContextForThisThread() {
+ auto make_tls_key = []() {
+ CHECK_EQ(pthread_key_create(&detail::key, detail::internalFree), 0);
+ };
+
+ pthread_once(&detail::key_once, make_tls_key);
+ auto *ptr = static_cast<Context *>(pthread_getspecific(detail::key));
+ if (ptr == nullptr) {
+ ptr = static_cast<Context *>(InternalAlloc(sizeof(Context)));
+ new(ptr) Context();
+ pthread_setspecific(detail::key, ptr);
+ }
+
+ return *ptr;
+}
+
+} // namespace radsan
diff --git a/compiler-rt/lib/radsan/radsan_context.h b/compiler-rt/lib/radsan/radsan_context.h
new file mode 100644
index 0000000000000..efd3677107469
--- /dev/null
+++ b/compiler-rt/lib/radsan/radsan_context.h
@@ -0,0 +1,38 @@
+//===--- radsan_context.h - Realtime Sanitizer --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#pragma once
+
+namespace radsan {
+
+class Context {
+public:
+ Context();
+
+ void realtimePush();
+ void realtimePop();
+
+ void bypassPush();
+ void bypassPop();
+
+ void expectNotRealtime(const char *interpreted_function_name);
+
+private:
+ bool inRealtimeContext() const;
+ bool isBypassed() const;
+ void printDiagnostics(const char *intercepted_function_name);
+
+ int realtime_depth_{0};
+ int bypass_depth_{0};
+};
+
+Context &getContextForThisThread();
+
+} // namespace radsan
diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/radsan/radsan_interceptors.cpp
new file mode 100644
index 0000000000000..d50ece6099b14
--- /dev/null
+++ b/compiler-rt/lib/radsan/radsan_interceptors.cpp
@@ -0,0 +1,412 @@
+//===--- radsan_interceptors.cpp - Realtime Sanitizer --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#include "radsan/radsan_interceptors.h"
+
+#include "sanitizer_common/sanitizer_platform.h"
+#include "sanitizer_common/sanitizer_platform_interceptors.h"
+
+#include "interception/interception.h"
+#include "radsan/radsan_context.h"
+
+#if !SANITIZER_LINUX && !SANITIZER_APPLE
+#error Sorry, radsan does not yet support this platform
+#endif
+
+#if SANITIZER_APPLE
+#include <libkern/OSAtomic.h>
+#include <os/lock.h>
+#endif
+
+#if SANITIZER_INTERCEPT_MEMALIGN || SANITIZER_INTERCEPT_PVALLOC
+#include <malloc.h>
+#endif
+
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <time.h>
+#include <unistd.h>
+
+using namespace __sanitizer;
+
+namespace radsan {
+void expectNotRealtime(const char *intercepted_function_name) {
+ getContextForThisThread().expectNotRealtime(intercepted_function_name);
+}
+} // namespace radsan
+
+/*
+ Filesystem
+*/
+
+INTERCEPTOR(int, open, const char *path, int oflag, ...) {
+ // TODO Establish whether we should intercept here if the flag contains
+ // O_NONBLOCK
+ radsan::expectNotRealtime("open");
+ va_list args;
+ va_start(args, oflag);
+ auto result = REAL(open)(path, oflag, args);
+ va_end(args);
+ return result;
+}
+
+INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) {
+ // TODO Establish whether we should intercept here if the flag contains
+ // O_NONBLOCK
+ radsan::expectNotRealtime("openat");
+ va_list args;
+ va_start(args, oflag);
+ auto result = REAL(openat)(fd, path, oflag, args);
+ va_end(args);
+ return result;
+}
+
+INTERCEPTOR(int, creat, const char *path, mode_t mode) {
+ // TODO Establish whether we should intercept here if the flag contains
+ // O_NONBLOCK
+ radsan::expectNotRealtime("creat");
+ auto result = REAL(creat)(path, mode);
+ return result;
+}
+
+INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) {
+ radsan::expectNotRealtime("fcntl");
+ va_list args;
+ va_start(args, cmd);
+ auto result = REAL(fcntl)(filedes, cmd, args);
+ va_end(args);
+ return result;
+}
+
+INTERCEPTOR(int, close, int filedes) {
+ radsan::expectNotRealtime("close");
+ return REAL(close)(filedes);
+}
+
+INTERCEPTOR(FILE *, fopen, const char *path, const char *mode) {
+ radsan::expectNotRealtime("fopen");
+ return REAL(fopen)(path, mode);
+}
+
+INTERCEPTOR(size_t, fread, void *ptr, size_t size, size_t nitems,
+ FILE *stream) {
+ radsan::expectNotRealtime("fread");
+ return REAL(fread)(ptr, size, nitems, stream);
+}
+
+INTERCEPTOR(size_t, fwrite, const void *ptr, size_t size, size_t nitems,
+ FILE *stream) {
+ radsan::expectNotRealtime("fwrite");
+ return REAL(fwrite)(ptr, size, nitems, stream);
+}
+
+INTERCEPTOR(int, fclose, FILE *stream) {
+ radsan::expectNotRealtime("fclose");
+ return REAL(fclose)(stream);
+}
+
+INTERCEPTOR(int, fputs, const char *s, FILE *stream) {
+ radsan::expectNotRealtime("fputs");
+ return REAL(fputs)(s, stream);
+}
+
+/*
+ Streams
+*/
+
+INTERCEPTOR(int, puts, const char *s) {
+ radsan::expectNotRealtime("puts");
+ return REAL(puts)(s);
+}
+
+/*
+ Concurrency
+*/
+
+#if SANITIZER_APPLE
+#pragma clang diagnostic push
+// OSSpinLockLock is deprecated, but still in use in libc++
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+INTERCEPTOR(void, OSSpinLockLock, volatile OSSpinLock *lock) {
+ radsan::expectNotRealtime("OSSpinLockLock");
+ return REAL(OSSpinLockLock)(lock);
+}
+#pragma clang diagnostic pop
+
+INTERCEPTOR(void, os_unfair_lock_lock, os_unfair_lock_t lock) {
+ radsan::expectNotRealtime("os_unfair_lock_lock");
+ return REAL(os_unfair_lock_lock)(lock);
+}
+#elif SANITIZER_LINUX
+INTERCEPTOR(int, pthread_spin_lock, pthread_spinlock_t *spinlock) {
+ radsan::expectNotRealtime("pthread_spin_lock");
+ return REAL(pthread_spin_lock)(spinlock);
+}
+#endif
+
+INTERCEPTOR(int, pthread_create, pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine)(void *), void *arg) {
+ radsan::expectNotRealtime("pthread_create");
+ return REAL(pthread_create)(thread, attr, start_routine, arg);
+}
+
+INTERCEPTOR(int, pthread_mutex_lock, pthread_mutex_t *mutex) {
+ radsan::expectNotRealtime("pthread_mutex_lock");
+ return REAL(pthread_mutex_lock)(mutex);
+}
+
+INTERCEPTOR(int, pthread_mutex_unlock, pthread_mutex_t *mutex) {
+ radsan::expectNotRealtime("pthread_mutex_unlock");
+ return REAL(pthread_mutex_unlock)(mutex);
+}
+
+INTERCEPTOR(int, pthread_join, pthread_t thread, void **value_ptr) {
+ radsan::expectNotRealtime("pthread_join");
+ return REAL(pthread_join)(thread, value_ptr);
+}
+
+INTERCEPTOR(int, pthread_cond_signal, pthread_cond_t *cond) {
+ radsan::expectNotRealtime("pthread_cond_signal");
+ return REAL(pthread_cond_signal)(cond);
+}
+
+INTERCEPTOR(int, pthread_cond_broadcast, pthread_cond_t *cond) {
+ radsan::expectNotRealtime("pthread_cond_broadcast");
+ return REAL(pthread_cond_broadcast)(cond);
+}
+
+INTERCEPTOR(int, pthread_cond_wait, pthread_cond_t *cond,
+ pthread_mutex_t *mutex) {
+ radsan::expectNotRealtime("pthread_cond_wait");
+ return REAL(pthread_cond_wait)(cond, mutex);
+}
+
+INTERCEPTOR(int, pthread_cond_timedwait, pthread_cond_t *cond,
+ pthread_mutex_t *mutex, const timespec *ts) {
+ radsan::expectNotRealtime("pthread_cond_timedwait");
+ return REAL(pthread_cond_timedwait)(cond, mutex, ts);
+}
+
+INTERCEPTOR(int, pthread_rwlock_rdlock, pthread_rwlock_t *lock) {
+ radsan::expectNotRealtime("pthread_rwlock_rdlock");
+ return REAL(pthread_rwlock_rdlock)(lock);
+}
+
+INTERCEPTOR(int, pthread_rwlock_unlock, pthread_rwlock_t *lock) {
+ radsan::expectNotRealtime("pthread_rwlock_unlock");
+ return REAL(pthread_rwlock_unlock)(lock);
+}
+
+INTERCEPTOR(int, pthread_rwlock_wrlock, pthread_rwlock_t *lock) {
+ radsan::expectNotRealtime("pthread_rwlock_wrlock");
+ return REAL(pthread_rwlock_wrlock)(lock);
+}
+
+/*
+ Sleeping
+*/
+
+INTERCEPTOR(unsigned int, sleep, unsigned int s) {
+ radsan::expectNotRealtime("sleep");
+ return REAL(sleep)(s);
+}
+
+INTERCEPTOR(int, usleep, useconds_t u) {
+ radsan::expectNotRealtime("usleep");
+ return REAL(usleep)(u);
+}
+
+INTERCEPTOR(int, nanosleep, const struct timespec *rqtp,
+ struct timespec *rmtp) {
+ radsan::expectNotRealtime("nanosleep");
+ return REAL(nanosleep)(rqtp, rmtp);
+}
+
+/*
+ Memory
+*/
+
+INTERCEPTOR(void *, calloc, SIZE_T num, SIZE_T size) {
+ radsan::expectNotRealtime("calloc");
+ return REAL(calloc)(num, size);
+}
+
+INTERCEPTOR(void, free, void *ptr) {
+ if (ptr != NULL) {
+ radsan::expectNotRealtime("free");
+ }
+ return REAL(free)(ptr);
+}
+
+INTERCEPTOR(void *, malloc, SIZE_T size) {
+ radsan::expectNotRealtime("malloc");
+ return REAL(malloc)(size);
+}
+
+INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) {
+ radsan::expectNotRealtime("realloc");
+ return REAL(realloc)(ptr, size);
+}
+
+INTERCEPTOR(void *, reallocf, void *ptr, SIZE_T size) {
+ radsan::expectNotRealtime("reallocf");
+ return REAL(reallocf)(ptr, size);
+}
+
+INTERCEPTOR(void *, valloc, SIZE_T size) {
+ radsan::expectNotRealtime("valloc");
+ return REAL(valloc)(size);
+}
+
+#if SANITIZER_INTERCEPT_ALIGNED_ALLOC
+INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) {
+ radsan::expectNotRealtime("aligned_alloc");
+ return REAL(aligned_alloc)(alignment, size);
+}
+#define RADSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(aligned_alloc)
+#else
+#define RADSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC
+#endif
+
+INTERCEPTOR(int, posix_memalign, void **memptr, size_t alignment, size_t size) {
+ radsan::expectNotRealtime("posix_memalign");
+ return REAL(posix_memalign)(memptr, alignment, size);
+}
+
+#if SANITIZER_INTERCEPT_MEMALIGN
+INTERCEPTOR(void *, memalign, size_t alignment, size_t size) {
+ radsan::expectNotRealtime("memalign");
+ return REAL(memalign)(alignment, size);
+}
+#endif
+
+#if SANITIZER_INTERCEPT_PVALLOC
+INTERCEPTOR(void *, pvalloc, size_t size) {
+ radsan::expectNotRealtime("pvalloc");
+ return REAL(pvalloc)(size);
+}
+#endif
+
+/*
+ Sockets
+*/
+
+INTERCEPTOR(int, socket, int domain, int type, int protocol) {
+ radsan::expectNotRealtime("socket");
+ return REAL(socket)(domain, type, protocol);
+}
+
+INTERCEPTOR(ssize_t, send, int sockfd, const void *buf, size_t len, int flags) {
+ radsan::expectNotRealtime("send");
+ return REAL(send)(sockfd, buf, len, flags);
+}
+
+INTERCEPTOR(ssize_t, sendmsg, int socket, const struct msghdr *message,
+ int flags) {
+ radsan::expectNotRealtime("sendmsg");
+ return REAL(sendmsg)(socket, message, flags);
+}
+
+INTERCEPTOR(ssize_t, sendto, int socket, const void *buffer, size_t length,
+ int flags, const struct sockaddr *dest_addr, socklen_t dest_len) {
+ radsan::expectNotRealtime("sendto");
+ return REAL(sendto)(socket, buffer, length, flags, dest_addr, dest_len);
+}
+
+INTERCEPTOR(ssize_t, recv, int socket, void *buffer, size_t length, int flags) {
+ radsan::expectNotRealtime("recv");
+ return REAL(recv)(socket, buffer, length, flags);
+}
+
+INTERCEPTOR(ssize_t, recvfrom, int socket, void *buffer, size_t length,
+ int flags, struct sockaddr *address, socklen_t *address_len) {
+ radsan::expectNotRealtime("recvfrom");
+ return REAL(recvfrom)(socket, buffer, length, flags, address, address_len);
+}
+
+INTERCEPTOR(ssize_t, recvmsg, int socket, struct msghdr *message, int flags) {
+ radsan::expectNotRealtime("recvmsg");
+ return REAL(recvmsg)(socket, message, flags);
+}
+
+INTERCEPTOR(int, shutdown, int socket, int how) {
+ radsan::expectNotRealtime("shutdown");
+ return REAL(shutdown)(socket, how);
+}
+
+/*
+ Preinit
+*/
+
+namespace radsan {
+void initialiseInterceptors() {
+ INTERCEPT_FUNCTION(calloc);
+ INTERCEPT_FUNCTION(free);
+ INTERCEPT_FUNCTION(malloc);
+ INTERCEPT_FUNCTION(realloc);
+ INTERCEPT_FUNCTION(reallocf);
+ INTERCEPT_FUNCTION(valloc);
+ RADSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC;
+ INTERCEPT_FUNCTION(posix_memalign);
+#if SANITIZER_INTERCEPT_MEMALIGN
+ INTERCEPT_FUNCTION(memalign);
+#endif
+#if SANITIZER_INTERCEPT_PVALLOC
+ INTERCEPT_FUNCTION(pvalloc);
+#endif
+
+ INTERCEPT_FUNCTION(open);
+ INTERCEPT_FUNCTION(openat);
+ INTERCEPT_FUNCTION(close);
+ INTERCEPT_FUNCTION(fopen);
+ INTERCEPT_FUNCTION(fread);
+ INTERCEPT_FUNCTION(fwrite);
+ INTERCEPT_FUNCTION(fclose);
+ INTERCEPT_FUNCTION(fcntl);
+ INTERCEPT_FUNCTION(creat);
+ INTERCEPT_FUNCTION(puts);
+ INTERCEPT_FUNCTION(fputs);
+
+#if SANITIZER_APPLE
+ INTERCEPT_FUNCTION(OSSpinLockLock);
+ INTERCEPT_FUNCTION(os_unfair_lock_lock);
+#elif SANITIZER_LINUX
+ INTERCEPT_FUNCTION(pthread_spin_lock);
+#endif
+
+ INTERCEPT_FUNCTION(pthread_create);
+ INTERCEPT_FUNCTION(pthread_mutex_lock);
+ INTERCEPT_FUNCTION(pthread_mutex_unlock);
+ INTERCEPT_FUNCTION(pthread_join);
+ INTERCEPT_FUNCTION(pthread_cond_signal);
+ INTERCEPT_FUNCTION(pthread_cond_broadcast);
+ INTERCEPT_FUNCTION(pthread_cond_wait);
+ INTERCEPT_FUNCTION(pthread_cond_timedwait);
+ INTERCEPT_FUNCTION(pthread_rwlock_rdlock);
+ INTERCEPT_FUNCTION(pthread_rwlock_unlock);
+ INTERCEPT_FUNCTION(pthread_rwlock_wrlock);
+
+ INTERCEPT_FUNCTION(sleep);
+ INTERCEPT_FUNCTION(usleep);
+ INTERCEPT_FUNCTION(nanosleep);
+
+ INTERCEPT_FUNCTION(socket);
+ INTERCEPT_FUNCTION(send);
+ INTERCEPT_FUNCTION(sendmsg);
+ INTERCEPT_FUNCTION(sendto);
+ INTERCEPT_FUNCTION(recv);
+ INTERCEPT_FUNCTION(recvmsg);
+ INTERCEPT_FUNCTION(recvfrom);
+ INTERCEPT_FUNCTION(shutdown);
+}
+} // namespace radsan
diff --git a/compiler-rt/lib/radsan/radsan_interceptors.h b/compiler-rt/lib/radsan/radsan_interceptors.h
new file mode 100644
index 0000000000000..d10f4a01d8c80
--- /dev/null
+++ b/compiler-rt/lib/radsan/radsan_interceptors.h
@@ -0,0 +1,15 @@
+//===--- radsan_interceptors.h - Realtime Sanitizer --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#pragma once
+
+namespace radsan {
+void initialiseInterceptors();
+}
diff --git a/compiler-rt/lib/radsan/radsan_preinit.cpp b/compiler-rt/lib/radsan/radsan_preinit.cpp
new file mode 100644
index 0000000000000..e5e92becb1eac
--- /dev/null
+++ b/compiler-rt/lib/radsan/radsan_preinit.cpp
@@ -0,0 +1,23 @@
+//===--- radsan_preinit.cpp - Realtime Sanitizer --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_common/sanitizer_internal_defs.h"
+#include <radsan/radsan.h>
+
+#if SANITIZER_CAN_USE_PREINIT_ARRAY
+
+// The symbol is called __local_radsan_preinit, because it's not intended to be
+// exported.
+// This code is linked into the main executable when -fsanitize=realtime is in
+// the link flags. It can only use exported interface functions.
+__attribute__((section(".preinit_array"), used))
+void (*__local_radsan_preinit)(void) = radsan_init;
+
+#endif
diff --git a/compiler-rt/lib/radsan/radsan_stack.cpp b/compiler-rt/lib/radsan/radsan_stack.cpp
new file mode 100644
index 0000000000000..b3cffa98b3ab9
--- /dev/null
+++ b/compiler-rt/lib/radsan/radsan_stack.cpp
@@ -0,0 +1,52 @@
+//===--- radsan_stack.cpp - Realtime Sanitizer --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#include <sanitizer_common/sanitizer_flags.h>
+#include <sanitizer_common/sanitizer_stacktrace.h>
+
+using namespace __sanitizer;
+
+// We must define our own implementation of this method for our runtime.
+// This one is just copied from UBSan.
+
+namespace __sanitizer {
+void BufferedStackTrace::UnwindImpl(uptr pc, uptr bp, void *context,
+ bool request_fast, u32 max_depth) {
+ uptr top = 0;
+ uptr bottom = 0;
+ GetThreadStackTopAndBottom(false, &top, &bottom);
+ bool fast = StackTrace::WillUseFastUnwind(request_fast);
+ Unwind(max_depth, pc, bp, context, top, bottom, fast);
+}
+} // namespace __sanitizer
+
+namespace {
+void setGlobalStackTraceFormat() {
+ SetCommonFlagsDefaults();
+ CommonFlags cf;
+ cf.CopyFrom(*common_flags());
+ cf.stack_trace_format = "DEFAULT";
+ cf.external_symbolizer_path = GetEnv("RADSAN_SYMBOLIZER_PATH");
+ OverrideCommonFlags(cf);
+}
+} // namespace
+
+namespace radsan {
+void printStackTrace() {
+
+ auto stack = BufferedStackTrace{};
+
+ GET_CURRENT_PC_BP;
+ stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_fatal);
+
+ setGlobalStackTraceFormat();
+ stack.Print();
+}
+} // namespace radsan
diff --git a/compiler-rt/lib/radsan/radsan_stack.h b/compiler-rt/lib/radsan/radsan_stack.h
new file mode 100644
index 0000000000000..ee65a959431aa
--- /dev/null
+++ b/compiler-rt/lib/radsan/radsan_stack.h
@@ -0,0 +1,15 @@
+//===--- radsan_stack.h - Realtime Sanitizer --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#pragma once
+
+namespace radsan {
+void printStackTrace();
+}
diff --git a/compiler-rt/lib/radsan/tests/CMakeLists.txt b/compiler-rt/lib/radsan/tests/CMakeLists.txt
new file mode 100644
index 0000000000000..73cedac2765d6
--- /dev/null
+++ b/compiler-rt/lib/radsan/tests/CMakeLists.txt
@@ -0,0 +1,103 @@
+include(CompilerRTCompile)
+
+include_directories(..)
+
+set(RADSAN_UNITTEST_CFLAGS
+ ${COMPILER_RT_UNITTEST_CFLAGS}
+ ${COMPILER_RT_GTEST_CFLAGS}
+ ${COMPILER_RT_GMOCK_CFLAGS}
+ ${SANITIZER_TEST_CXX_CFLAGS}
+ -I${COMPILER_RT_SOURCE_DIR}/lib/
+ -I${COMPILER_RT_SOURCE_DIR}/include/
+ -I${COMPILER_RT_SOURCE_DIR}/lib/radsan
+ -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/tests
+ -DSANITIZER_COMMON_NO_REDEFINE_BUILTINS
+ -O2)
+
+set(RADSAN_INST_TEST_SOURCES
+ radsan_test.cpp
+ radsan_test_interceptors.cpp
+ radsan_test_main.cpp)
+
+set(RADSAN_NOINST_TEST_SOURCES
+ ../radsan_preinit.cpp
+ radsan_test_context.cpp
+ radsan_test_main.cpp)
+
+set(RADSAN_UNITTEST_HEADERS
+ radsan_test_utilities.h)
+
+add_custom_target(RadsanUnitTests)
+set_target_properties(RadsanUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
+
+set(RADSAN_UNITTEST_LINK_FLAGS
+ ${COMPILER_RT_UNITTEST_LINK_FLAGS}
+ ${COMPILER_RT_UNWINDER_LINK_LIBS}
+ ${SANITIZER_TEST_CXX_LIBRARIES}
+ -no-pie)
+
+if (APPLE)
+ add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)
+ list(APPEND RADSAN_UNITTEST_LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS})
+ list(APPEND RADSAN_UNITTEST_LINK_FLAGS ${DARWIN_osx_LINK_FLAGS})
+ list(APPEND RADSAN_UNITTEST_CFLAGS ${DARWIN_osx_CFLAGS})
+else()
+ list(APPEND RADSAN_UNITTEST_LINK_FLAGS -latomic)
+endif()
+
+set(COMPILER_RT_GOOGLETEST_SOURCES ${COMPILER_RT_GTEST_SOURCE} ${COMPILER_RT_GMOCK_SOURCE})
+
+set(RADSAN_TEST_ARCH ${RADSAN_SUPPORTED_ARCH})
+if(APPLE)
+ darwin_filter_host_archs(RADSAN_SUPPORTED_ARCH RADSAN_TEST_ARCH)
+endif()
+
+foreach(arch ${RADSAN_TEST_ARCH})
+ set(RadsanTestObjects)
+ generate_compiler_rt_tests(RadsanTestObjects
+ RadsanUnitTests "Radsan-${arch}-Test" ${arch}
+ COMPILE_DEPS ${RADSAN_UNITTEST_HEADERS}
+ SOURCES ${RADSAN_INST_TEST_SOURCES} ${COMPILER_RT_GOOGLETEST_SOURCES}
+ DEPS llvm_gtest radsan
+ CFLAGS ${RADSAN_UNITTEST_CFLAGS} -fsanitize=realtime
+ LINK_FLAGS ${RADSAN_UNITTEST_LINK_FLAGS} -fsanitize=realtime)
+ set_target_properties(RadsanUnitTests PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+
+ set(RADSAN_TEST_RUNTIME RTRadsanTest.${arch})
+ if(APPLE)
+ set(RADSAN_TEST_RUNTIME_OBJECTS
+ $<TARGET_OBJECTS:RTRadsan.osx>
+ $<TARGET_OBJECTS:RTInterception.osx>
+ $<TARGET_OBJECTS:RTSanitizerCommon.osx>
+ $<TARGET_OBJECTS:RTSanitizerCommonLibc.osx>
+ $<TARGET_OBJECTS:RTSanitizerCommonCoverage.osx>
+ $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.osx>)
+ else()
+ set(RADSAN_TEST_RUNTIME_OBJECTS
+ $<TARGET_OBJECTS:RTRadsan.${arch}>
+ $<TARGET_OBJECTS:RTInterception.${arch}>
+ $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
+ $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
+ $<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
+ $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
+ $<TARGET_OBJECTS:RTSanitizerCommonSymbolizerInternal.${arch}>)
+ endif()
+ add_library(${RADSAN_TEST_RUNTIME} STATIC ${RADSAN_TEST_RUNTIME_OBJECTS})
+ set_target_properties(${RADSAN_TEST_RUNTIME} PROPERTIES
+ ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ FOLDER "Compiler-RT Runtime tests")
+
+ set(RadsanNoInstTestObjects)
+ generate_compiler_rt_tests(RadsanNoInstTestObjects
+ RadsanUnitTests "Radsan-${arch}-NoInstTest" ${arch}
+ COMPILE_DEPS ${RADSAN_UNITTEST_HEADERS}
+ SOURCES ${RADSAN_NOINST_TEST_SOURCES}
+ ${COMPILER_RT_GOOGLETEST_SOURCES}
+ DEPS llvm_gtest
+ CFLAGS ${RADSAN_UNITTEST_CFLAGS}
+ LINK_FLAGS ${RADSAN_UNITTEST_LINK_FLAGS}
+ RUNTIME ${RADSAN_TEST_RUNTIME})
+ set_target_properties(RadsanUnitTests PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+endforeach()
diff --git a/compiler-rt/lib/radsan/tests/radsan_test.cpp b/compiler-rt/lib/radsan/tests/radsan_test.cpp
new file mode 100644
index 0000000000000..65c4380dfc602
--- /dev/null
+++ b/compiler-rt/lib/radsan/tests/radsan_test.cpp
@@ -0,0 +1,203 @@
+//===--- radsan_test.cpp - Realtime Sanitizer --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+#include "radsan_test_utilities.h"
+#include <radsan.h>
+#include <sanitizer_common/sanitizer_platform.h>
+#include <sanitizer_common/sanitizer_platform_interceptors.h>
+
+#include <array>
+#include <atomic>
+#include <chrono>
+#include <fstream>
+#include <mutex>
+#include <shared_mutex>
+#include <thread>
+
+#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
+ __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101200
+#define SI_MAC_DEPLOYMENT_AT_LEAST_10_12 1
+#else
+#define SI_MAC_DEPLOYMENT_AT_LEAST_10_12 0
+#endif
+
+#define RADSAN_TEST_SHARED_MUTEX (!(SI_MAC) || SI_MAC_DEPLOYMENT_AT_LEAST_10_12)
+
+using namespace testing;
+using namespace radsan_testing;
+using namespace std::chrono_literals;
+
+namespace {
+void invokeStdFunction(std::function<void()> &&function) { function(); }
+} // namespace
+
+TEST(TestRadsan, vectorPushBackAllocationDiesWhenRealtime) {
+ auto vec = std::vector<float>{};
+ auto func = [&vec]() { vec.push_back(0.4f); };
+ expectRealtimeDeath(func);
+ ASSERT_EQ(0u, vec.size());
+ expectNonrealtimeSurvival(func);
+ ASSERT_EQ(1u, vec.size());
+}
+
+TEST(TestRadsan, destructionOfObjectOnHeapDiesWhenRealtime) {
+ auto obj = std::make_unique<std::array<float, 256>>();
+ auto func = [&obj]() { obj.reset(); };
+ expectRealtimeDeath(func);
+ ASSERT_NE(nullptr, obj.get());
+ expectNonrealtimeSurvival(func);
+ ASSERT_EQ(nullptr, obj.get());
+}
+
+TEST(TestRadsan, sleepingAThreadDiesWhenRealtime) {
+ auto func = []() { std::this_thread::sleep_for(1us); };
+ expectRealtimeDeath(func);
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsan, ifstreamCreationDiesWhenRealtime) {
+ auto func = []() { auto ifs = std::ifstream("./file.txt"); };
+ expectRealtimeDeath(func);
+ expectNonrealtimeSurvival(func);
+ std::remove("./file.txt");
+}
+
+TEST(TestRadsan, ofstreamCreationDiesWhenRealtime) {
+ auto func = []() { auto ofs = std::ofstream("./file.txt"); };
+ expectRealtimeDeath(func);
+ expectNonrealtimeSurvival(func);
+ std::remove("./file.txt");
+}
+
+TEST(TestRadsan, lockingAMutexDiesWhenRealtime) {
+ auto mutex = std::mutex{};
+ auto func = [&]() { mutex.lock(); };
+ expectRealtimeDeath(func);
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsan, unlockingAMutexDiesWhenRealtime) {
+ auto mutex = std::mutex{};
+ mutex.lock();
+ auto func = [&]() { mutex.unlock(); };
+ expectRealtimeDeath(func);
+ expectNonrealtimeSurvival(func);
+}
+
+#if RADSAN_TEST_SHARED_MUTEX
+
+TEST(TestRadsan, lockingASharedMutexDiesWhenRealtime) {
+ auto mutex = std::shared_mutex();
+ auto func = [&]() { mutex.lock(); };
+ expectRealtimeDeath(func);
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsan, unlockingASharedMutexDiesWhenRealtime) {
+ auto mutex = std::shared_mutex();
+ mutex.lock();
+ auto func = [&]() { mutex.unlock(); };
+ expectRealtimeDeath(func);
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsan, sharedLockingASharedMutexDiesWhenRealtime) {
+ auto mutex = std::shared_mutex();
+ auto func = [&]() { mutex.lock_shared(); };
+ expectRealtimeDeath(func);
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsan, sharedUnlockingASharedMutexDiesWhenRealtime) {
+ auto mutex = std::shared_mutex();
+ mutex.lock_shared();
+ auto func = [&]() { mutex.unlock_shared(); };
+ expectRealtimeDeath(func);
+ expectNonrealtimeSurvival(func);
+}
+
+#endif // RADSAN_TEST_SHARED_MUTEX
+
+TEST(TestRadsan, launchingAThreadDiesWhenRealtime) {
+ auto func = [&]() {
+ auto t = std::thread([]() {});
+ t.join();
+ };
+ expectRealtimeDeath(func);
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsan, copyingALambdaWithLargeCaptureDiesWhenRealtime) {
+ auto lots_of_data = std::array<float, 16>{};
+ auto lambda = [lots_of_data]() mutable {
+ // Stop everything getting optimised out
+ lots_of_data[3] = 0.25f;
+ EXPECT_EQ(16, lots_of_data.size());
+ EXPECT_EQ(0.25f, lots_of_data[3]);
+ };
+ auto func = [&]() { invokeStdFunction(lambda); };
+ expectRealtimeDeath(func);
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsan, accessingALargeAtomicVariableDiesWhenRealtime) {
+ auto small_atomic = std::atomic<float>{0.0f};
+ ASSERT_TRUE(small_atomic.is_lock_free());
+ realtimeInvoke([&small_atomic]() { auto x = small_atomic.load(); });
+
+ auto large_atomic = std::atomic<std::array<float, 2048>>{{}};
+ ASSERT_FALSE(large_atomic.is_lock_free());
+ auto func = [&]() { auto x = large_atomic.load(); };
+ expectRealtimeDeath(func);
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsan, firstCoutDiesWhenRealtime) {
+ auto func = []() { std::cout << "Hello, world!" << std::endl; };
+ expectRealtimeDeath(func);
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsan, secondCoutDiesWhenRealtime) {
+ std::cout << "Hello, world";
+ auto func = []() { std::cout << "Hello, again!" << std::endl; };
+ expectRealtimeDeath(func);
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsan, printfDiesWhenRealtime) {
+ auto func = []() { printf("Hello, world!\n"); };
+ expectRealtimeDeath(func);
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsan, throwingAnExceptionDiesWhenRealtime) {
+ auto func = [&]() {
+ try {
+ throw std::exception();
+ } catch (std::exception &) {
+ }
+ };
+ expectRealtimeDeath(func);
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsan, doesNotDieIfTurnedOff) {
+ auto mutex = std::mutex{};
+ auto realtime_unsafe_func = [&]() {
+ radsan_off();
+ mutex.lock();
+ mutex.unlock();
+ radsan_on();
+ };
+ realtimeInvoke(realtime_unsafe_func);
+}
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp
new file mode 100644
index 0000000000000..c52a0fff3b7ef
--- /dev/null
+++ b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp
@@ -0,0 +1,69 @@
+//===--- radsan_test_context.cpp - Realtime Sanitizer --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#include "radsan_test_utilities.h"
+
+#include "radsan_context.h"
+
+TEST(TestRadsanContext, canCreateContext) { auto context = radsan::Context{}; }
+
+TEST(TestRadsanContext, expectNotRealtimeDoesNotDieBeforeRealtimePush) {
+ auto context = radsan::Context{};
+ context.expectNotRealtime("do_some_stuff");
+}
+
+TEST(TestRadsanContext, expectNotRealtimeDoesNotDieAfterPushAndPop) {
+ auto context = radsan::Context{};
+ context.realtimePush();
+ context.realtimePop();
+ context.expectNotRealtime("do_some_stuff");
+}
+
+TEST(TestRadsanContext, expectNotRealtimeDiesAfterRealtimePush) {
+ auto context = radsan::Context{};
+
+ context.realtimePush();
+ EXPECT_DEATH(context.expectNotRealtime("do_some_stuff"), "");
+}
+
+TEST(TestRadsanContext,
+ expectNotRealtimeDiesAfterRealtimeAfterMorePushesThanPops) {
+ auto context = radsan::Context{};
+
+ context.realtimePush();
+ context.realtimePush();
+ context.realtimePush();
+ context.realtimePop();
+ context.realtimePop();
+ EXPECT_DEATH(context.expectNotRealtime("do_some_stuff"), "");
+}
+
+TEST(TestRadsanContext, expectNotRealtimeDoesNotDieAfterBypassPush) {
+ auto context = radsan::Context{};
+
+ context.realtimePush();
+ context.bypassPush();
+ context.expectNotRealtime("do_some_stuff");
+}
+
+TEST(TestRadsanContext,
+ expectNotRealtimeDoesNotDieIfBypassDepthIsGreaterThanZero) {
+ auto context = radsan::Context{};
+
+ context.realtimePush();
+ context.bypassPush();
+ context.bypassPush();
+ context.bypassPush();
+ context.bypassPop();
+ context.bypassPop();
+ context.expectNotRealtime("do_some_stuff");
+ context.bypassPop();
+ EXPECT_DEATH(context.expectNotRealtime("do_some_stuff"), "");
+}
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
new file mode 100644
index 0000000000000..6b6bb6b76d7ff
--- /dev/null
+++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
@@ -0,0 +1,454 @@
+//===--- radsan_test_interceptors.cpp - Realtime Sanitizer --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+#include <sanitizer_common/sanitizer_platform.h>
+#include <sanitizer_common/sanitizer_platform_interceptors.h>
+
+#include "radsan_test_utilities.h"
+
+#if SANITIZER_APPLE
+#include <libkern/OSAtomic.h>
+#include <os/lock.h>
+#endif
+
+#if SANITIZER_INTERCEPT_MEMALIGN || SANITIZER_INTERCEPT_PVALLOC
+#include <malloc.h>
+#endif
+
+#include <atomic>
+#include <chrono>
+#include <thread>
+
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <sys/socket.h>
+
+using namespace testing;
+using namespace radsan_testing;
+using namespace std::chrono_literals;
+
+namespace {
+void *fake_thread_entry_point(void *) { return nullptr; }
+
+/*
+ The creat function doesn't seem to work on an ubuntu Docker image when the
+ path is in a shared volume of the host. For now, to keep testing convenient
+ with a local Docker container, we just put it somewhere that's not in the
+ shared volume (/tmp). This is volatile and will be cleaned up as soon as the
+ container is stopped.
+*/
+constexpr const char *temporary_file_path() {
+#if SANITIZER_LINUX
+ return "/tmp/radsan_temporary_test_file.txt";
+#elif SANITIZER_APPLE
+ return "./radsan_temporary_test_file.txt";
+#endif
+}
+} // namespace
+
+/*
+ Allocation and deallocation
+*/
+
+TEST(TestRadsanInterceptors, mallocDiesWhenRealtime) {
+ auto func = []() { EXPECT_NE(nullptr, malloc(1)); };
+ expectRealtimeDeath(func, "malloc");
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsanInterceptors, reallocDiesWhenRealtime) {
+ auto *ptr_1 = malloc(1);
+ auto func = [ptr_1]() { EXPECT_NE(nullptr, realloc(ptr_1, 8)); };
+ expectRealtimeDeath(func, "realloc");
+ expectNonrealtimeSurvival(func);
+}
+
+#if SANITIZER_APPLE
+TEST(TestRadsanInterceptors, reallocfDiesWhenRealtime) {
+ auto *ptr_1 = malloc(1);
+ auto func = [ptr_1]() { EXPECT_NE(nullptr, reallocf(ptr_1, 8)); };
+ expectRealtimeDeath(func, "reallocf");
+ expectNonrealtimeSurvival(func);
+}
+#endif
+
+TEST(TestRadsanInterceptors, vallocDiesWhenRealtime) {
+ auto func = []() { EXPECT_NE(nullptr, valloc(4)); };
+ expectRealtimeDeath(func, "valloc");
+ expectNonrealtimeSurvival(func);
+}
+
+#if SANITIZER_INTERCEPT_ALIGNED_ALLOC
+TEST(TestRadsanInterceptors, alignedAllocDiesWhenRealtime) {
+ auto func = []() { EXPECT_NE(nullptr, aligned_alloc(16, 32)); };
+ expectRealtimeDeath(func, "aligned_alloc");
+ expectNonrealtimeSurvival(func);
+}
+#endif
+
+// free_sized and free_aligned_sized (both C23) are not yet supported
+TEST(TestRadsanInterceptors, freeDiesWhenRealtime) {
+ auto *ptr_1 = malloc(1);
+ auto *ptr_2 = malloc(1);
+ expectRealtimeDeath([ptr_1]() { free(ptr_1); }, "free");
+ expectNonrealtimeSurvival([ptr_2]() { free(ptr_2); });
+
+ // Prevent malloc/free pair being optimised out
+ ASSERT_NE(nullptr, ptr_1);
+ ASSERT_NE(nullptr, ptr_2);
+}
+
+TEST(TestRadsanInterceptors, freeSurvivesWhenRealtimeIfArgumentIsNull) {
+ realtimeInvoke([]() { free(NULL); });
+ expectNonrealtimeSurvival([]() { free(NULL); });
+}
+
+TEST(TestRadsanInterceptors, posixMemalignDiesWhenRealtime) {
+ auto func = []() {
+ void *mem;
+ posix_memalign(&mem, 4, 4);
+ };
+ expectRealtimeDeath(func, "posix_memalign");
+ expectNonrealtimeSurvival(func);
+}
+
+#if SANITIZER_INTERCEPT_MEMALIGN
+TEST(TestRadsanInterceptors, memalignDiesWhenRealtime) {
+ auto func = []() { EXPECT_NE(memalign(2, 2048), nullptr); };
+ expectRealtimeDeath(func, "memalign");
+ expectNonrealtimeSurvival(func);
+}
+#endif
+
+#if SANITIZER_INTERCEPT_PVALLOC
+TEST(TestRadsanInterceptors, pvallocDiesWhenRealtime) {
+ auto func = []() { EXPECT_NE(pvalloc(2048), nullptr); };
+ expectRealtimeDeath(func, "pvalloc");
+ expectNonrealtimeSurvival(func);
+}
+#endif
+
+/*
+ Sleeping
+*/
+
+TEST(TestRadsanInterceptors, sleepDiesWhenRealtime) {
+ auto func = []() { sleep(0u); };
+ expectRealtimeDeath(func, "sleep");
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsanInterceptors, usleepDiesWhenRealtime) {
+ auto func = []() { usleep(1u); };
+ expectRealtimeDeath(func, "usleep");
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsanInterceptors, nanosleepDiesWhenRealtime) {
+ auto func = []() {
+ auto t = timespec{};
+ nanosleep(&t, &t);
+ };
+ expectRealtimeDeath(func, "nanosleep");
+ expectNonrealtimeSurvival(func);
+}
+
+/*
+ Filesystem
+*/
+
+TEST(TestRadsanInterceptors, openDiesWhenRealtime) {
+ auto func = []() { open(temporary_file_path(), O_RDONLY); };
+ expectRealtimeDeath(func, "open");
+ expectNonrealtimeSurvival(func);
+ std::remove(temporary_file_path());
+}
+
+TEST(TestRadsanInterceptors, openatDiesWhenRealtime) {
+ auto func = []() { openat(0, temporary_file_path(), O_RDONLY); };
+ expectRealtimeDeath(func, "openat");
+ expectNonrealtimeSurvival(func);
+ std::remove(temporary_file_path());
+}
+
+TEST(TestRadsanInterceptors, creatDiesWhenRealtime) {
+ auto func = []() { creat(temporary_file_path(), S_IWOTH | S_IROTH); };
+ expectRealtimeDeath(func, "creat");
+ expectNonrealtimeSurvival(func);
+ std::remove(temporary_file_path());
+}
+
+TEST(TestRadsanInterceptors, fcntlDiesWhenRealtime) {
+ auto func = []() { fcntl(0, F_GETFL); };
+ expectRealtimeDeath(func, "fcntl");
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsanInterceptors, closeDiesWhenRealtime) {
+ auto func = []() { close(0); };
+ expectRealtimeDeath(func, "close");
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsanInterceptors, fopenDiesWhenRealtime) {
+ auto func = []() {
+ auto fd = fopen(temporary_file_path(), "w");
+ EXPECT_THAT(fd, Ne(nullptr));
+ };
+ expectRealtimeDeath(func, "fopen");
+ expectNonrealtimeSurvival(func);
+ std::remove(temporary_file_path());
+}
+
+TEST(TestRadsanInterceptors, freadDiesWhenRealtime) {
+ auto fd = fopen(temporary_file_path(), "w");
+ auto func = [fd]() {
+ char c{};
+ fread(&c, 1, 1, fd);
+ };
+ expectRealtimeDeath(func, "fread");
+ expectNonrealtimeSurvival(func);
+ if (fd != nullptr)
+ fclose(fd);
+ std::remove(temporary_file_path());
+}
+
+TEST(TestRadsanInterceptors, fwriteDiesWhenRealtime) {
+ auto fd = fopen(temporary_file_path(), "w");
+ ASSERT_NE(nullptr, fd);
+ auto message = "Hello, world!";
+ auto func = [&]() { fwrite(&message, 1, 4, fd); };
+ expectRealtimeDeath(func, "fwrite");
+ expectNonrealtimeSurvival(func);
+ std::remove(temporary_file_path());
+}
+
+TEST(TestRadsanInterceptors, fcloseDiesWhenRealtime) {
+ auto fd = fopen(temporary_file_path(), "w");
+ EXPECT_THAT(fd, Ne(nullptr));
+ auto func = [fd]() { fclose(fd); };
+ expectRealtimeDeath(func, "fclose");
+ expectNonrealtimeSurvival(func);
+ std::remove(temporary_file_path());
+}
+
+TEST(TestRadsanInterceptors, putsDiesWhenRealtime) {
+ auto func = []() { puts("Hello, world!\n"); };
+ expectRealtimeDeath(func);
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsanInterceptors, fputsDiesWhenRealtime) {
+ auto fd = fopen(temporary_file_path(), "w");
+ ASSERT_THAT(fd, Ne(nullptr)) << errno;
+ auto func = [fd]() { fputs("Hello, world!\n", fd); };
+ expectRealtimeDeath(func);
+ expectNonrealtimeSurvival(func);
+ if (fd != nullptr)
+ fclose(fd);
+ std::remove(temporary_file_path());
+}
+
+/*
+ Concurrency
+*/
+
+TEST(TestRadsanInterceptors, pthreadCreateDiesWhenRealtime) {
+ auto func = []() {
+ auto thread = pthread_t{};
+ auto const attr = pthread_attr_t{};
+ struct thread_info *tinfo;
+ pthread_create(&thread, &attr, &fake_thread_entry_point, tinfo);
+ };
+ expectRealtimeDeath(func, "pthread_create");
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsanInterceptors, pthreadMutexLockDiesWhenRealtime) {
+ auto func = []() {
+ auto mutex = pthread_mutex_t{};
+ pthread_mutex_lock(&mutex);
+ };
+
+ expectRealtimeDeath(func, "pthread_mutex_lock");
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsanInterceptors, pthreadMutexUnlockDiesWhenRealtime) {
+ auto func = []() {
+ auto mutex = pthread_mutex_t{};
+ pthread_mutex_unlock(&mutex);
+ };
+
+ expectRealtimeDeath(func, "pthread_mutex_unlock");
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsanInterceptors, pthreadMutexJoinDiesWhenRealtime) {
+ auto func = []() {
+ auto thread = pthread_t{};
+ pthread_join(thread, nullptr);
+ };
+
+ expectRealtimeDeath(func, "pthread_join");
+ expectNonrealtimeSurvival(func);
+}
+
+#if SANITIZER_APPLE
+
+#pragma clang diagnostic push
+// OSSpinLockLock is deprecated, but still in use in libc++
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+TEST(TestRadsanInterceptors, osSpinLockLockDiesWhenRealtime) {
+ auto func = []() {
+ auto spin_lock = OSSpinLock{};
+ OSSpinLockLock(&spin_lock);
+ };
+ expectRealtimeDeath(func, "OSSpinLockLock");
+ expectNonrealtimeSurvival(func);
+}
+#pragma clang diagnostic pop
+
+TEST(TestRadsanInterceptors, osUnfairLockLockDiesWhenRealtime) {
+ auto func = []() {
+ auto unfair_lock = os_unfair_lock_s{};
+ os_unfair_lock_lock(&unfair_lock);
+ };
+ expectRealtimeDeath(func, "os_unfair_lock_lock");
+ expectNonrealtimeSurvival(func);
+}
+#endif
+
+#if SANITIZER_LINUX
+TEST(TestRadsanInterceptors, spinLockLockDiesWhenRealtime) {
+ auto spinlock = pthread_spinlock_t{};
+ pthread_spin_init(&spinlock, PTHREAD_PROCESS_SHARED);
+ auto func = [&]() { pthread_spin_lock(&spinlock); };
+ expectRealtimeDeath(func, "pthread_spin_lock");
+ expectNonrealtimeSurvival(func);
+}
+#endif
+
+TEST(TestRadsanInterceptors, pthreadCondSignalDiesWhenRealtime) {
+ auto func = []() {
+ auto cond = pthread_cond_t{};
+ pthread_cond_signal(&cond);
+ };
+ expectRealtimeDeath(func, "pthread_cond_signal");
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsanInterceptors, pthreadCondBroadcastDiesWhenRealtime) {
+ auto func = []() {
+ auto cond = pthread_cond_t{};
+ pthread_cond_broadcast(&cond);
+ };
+ expectRealtimeDeath(func, "pthread_cond_broadcast");
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsanInterceptors, pthreadCondWaitDiesWhenRealtime) {
+ auto cond = pthread_cond_t{};
+ auto mutex = pthread_mutex_t{};
+ ASSERT_EQ(0, pthread_cond_init(&cond, nullptr));
+ ASSERT_EQ(0, pthread_mutex_init(&mutex, nullptr));
+ auto func = [&]() { pthread_cond_wait(&cond, &mutex); };
+ expectRealtimeDeath(func, "pthread_cond_wait");
+ // It's very difficult to test the success case here without doing some
+ // sleeping, which is at the mercy of the scheduler. What's really important
+ // here is the interception - so we're only testing that for now.
+}
+
+TEST(TestRadsanInterceptors, pthreadRwlockRdlockDiesWhenRealtime) {
+ auto func = []() {
+ auto rwlock = pthread_rwlock_t{};
+ pthread_rwlock_rdlock(&rwlock);
+ };
+ expectRealtimeDeath(func, "pthread_rwlock_rdlock");
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsanInterceptors, pthreadRwlockUnlockDiesWhenRealtime) {
+ auto func = []() {
+ auto rwlock = pthread_rwlock_t{};
+ pthread_rwlock_unlock(&rwlock);
+ };
+ expectRealtimeDeath(func, "pthread_rwlock_unlock");
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsanInterceptors, pthreadRwlockWrlockDiesWhenRealtime) {
+ auto func = []() {
+ auto rwlock = pthread_rwlock_t{};
+ pthread_rwlock_wrlock(&rwlock);
+ };
+ expectRealtimeDeath(func, "pthread_rwlock_wrlock");
+ expectNonrealtimeSurvival(func);
+}
+
+/*
+ Sockets
+*/
+TEST(TestRadsanInterceptors, openingASocketDiesWhenRealtime) {
+ auto func = []() { socket(PF_INET, SOCK_STREAM, 0); };
+ expectRealtimeDeath(func, "socket");
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsanInterceptors, sendToASocketDiesWhenRealtime) {
+ auto func = []() { send(0, nullptr, 0, 0); };
+ expectRealtimeDeath(func, "send");
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsanInterceptors, sendmsgToASocketDiesWhenRealtime) {
+ auto const msg = msghdr{};
+ auto func = [&]() { sendmsg(0, &msg, 0); };
+ expectRealtimeDeath(func, "sendmsg");
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsanInterceptors, sendtoToASocketDiesWhenRealtime) {
+ auto const addr = sockaddr{};
+ auto const len = socklen_t{};
+ auto func = [&]() { sendto(0, nullptr, 0, 0, &addr, len); };
+ expectRealtimeDeath(func, "sendto");
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsanInterceptors, recvFromASocketDiesWhenRealtime) {
+ auto func = []() { recv(0, nullptr, 0, 0); };
+ expectRealtimeDeath(func, "recv");
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsanInterceptors, recvfromOnASocketDiesWhenRealtime) {
+ auto addr = sockaddr{};
+ auto len = socklen_t{};
+ auto func = [&]() { recvfrom(0, nullptr, 0, 0, &addr, &len); };
+ expectRealtimeDeath(func, "recvfrom");
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsanInterceptors, recvmsgOnASocketDiesWhenRealtime) {
+ auto msg = msghdr{};
+ auto func = [&]() { recvmsg(0, &msg, 0); };
+ expectRealtimeDeath(func, "recvmsg");
+ expectNonrealtimeSurvival(func);
+}
+
+TEST(TestRadsanInterceptors, shutdownOnASocketDiesWhenRealtime) {
+ auto func = [&]() { shutdown(0, 0); };
+ expectRealtimeDeath(func, "shutdown");
+ expectNonrealtimeSurvival(func);
+}
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_main.cpp b/compiler-rt/lib/radsan/tests/radsan_test_main.cpp
new file mode 100644
index 0000000000000..5777a0b69a93f
--- /dev/null
+++ b/compiler-rt/lib/radsan/tests/radsan_test_main.cpp
@@ -0,0 +1,17 @@
+//===--- radsan_test_main.cpp - Realtime Sanitizer --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_test_utils.h"
+
+int main(int argc, char **argv) {
+ testing::GTEST_FLAG(death_test_style) = "threadsafe";
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h b/compiler-rt/lib/radsan/tests/radsan_test_utilities.h
new file mode 100644
index 0000000000000..fb3681aa97b06
--- /dev/null
+++ b/compiler-rt/lib/radsan/tests/radsan_test_utilities.h
@@ -0,0 +1,49 @@
+//===--- radsan_test_utilities.h - Realtime Sanitizer --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#pragma once
+
+#include "gmock/gmock.h"
+#include "radsan.h"
+#include <string>
+
+namespace radsan_testing {
+
+template <typename Function>
+void realtimeInvoke(Function &&func)
+{
+ radsan_realtime_enter();
+ std::forward<Function>(func)();
+ radsan_realtime_exit();
+}
+
+template <typename Function>
+void expectRealtimeDeath(Function &&func,
+ const char *intercepted_method_name = nullptr) {
+
+ using namespace testing;
+
+ auto expected_error_substr = [&]() -> std::string {
+ return intercepted_method_name != nullptr
+ ? "Real-time violation: intercepted call to real-time unsafe "
+ "function `" +
+ std::string(intercepted_method_name) + "`"
+ : "";
+ };
+
+ EXPECT_EXIT(realtimeInvoke(std::forward<Function>(func)),
+ ExitedWithCode(EXIT_FAILURE), expected_error_substr());
+}
+
+template <typename Function> void expectNonrealtimeSurvival(Function &&func) {
+ std::forward<Function>(func)();
+}
+
+} // namespace radsan_testing
diff --git a/compiler-rt/test/radsan/CMakeLists.txt b/compiler-rt/test/radsan/CMakeLists.txt
new file mode 100644
index 0000000000000..51a3ff72859b6
--- /dev/null
+++ b/compiler-rt/test/radsan/CMakeLists.txt
@@ -0,0 +1,47 @@
+set(RADSAN_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+
+set(RADSAN_TESTSUITES)
+set(RADSAN_FDR_TESTSUITES)
+
+set(RADSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
+set(RADSAN_FDR_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
+set(RADSAN_TEST_ARCH ${RADSAN_SUPPORTED_ARCH})
+if(APPLE)
+ darwin_filter_host_archs(RADSAN_SUPPORTED_ARCH RADSAN_TEST_ARCH)
+endif()
+
+if (COMPILER_RT_HAS_RADSAN)
+ foreach(arch ${RADSAN_TEST_ARCH})
+ set(RADSAN_TEST_TARGET_ARCH ${arch})
+ string(TOLOWER "-${arch}-${OS_NAME}" RADSAN_TEST_CONFIG_SUFFIX)
+ get_test_cc_for_arch(${arch} RADSAN_TEST_TARGET_CC RADSAN_TEST_TARGET_CFLAGS)
+ string(TOUPPER ${arch} ARCH_UPPER_CASE)
+ set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config)
+
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg.py)
+ list(APPEND RADSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
+ endforeach()
+endif()
+
+if(COMPILER_RT_INCLUDE_TESTS)
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in
+ ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg.py)
+ if(COMPILER_RT_RADSAN_HAS_STATIC_RUNTIME)
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in
+ ${CMAKE_CURRENT_BINARY_DIR}/Unit/dynamic/lit.site.cfg.py)
+ endif()
+ list(APPEND RADSAN_TEST_DEPS RadsanUnitTests)
+ list(APPEND RADSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit)
+ if(COMPILER_RT_RADSAN_HAS_STATIC_RUNTIME)
+ list(APPEND RADSAN_DYNAMIC_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit/dynamic)
+ endif()
+endif()
+
+add_lit_testsuite(check-radsan "Running the Radsan tests"
+ ${RADSAN_TESTSUITES}
+ DEPENDS ${RADSAN_TEST_DEPS})
+set_target_properties(check-radsan PROPERTIES FOLDER "Compiler-RT Misc")
diff --git a/compiler-rt/test/radsan/Unit/lit.site.cfg.py.in b/compiler-rt/test/radsan/Unit/lit.site.cfg.py.in
new file mode 100644
index 0000000000000..432e0ed5e1907
--- /dev/null
+++ b/compiler-rt/test/radsan/Unit/lit.site.cfg.py.in
@@ -0,0 +1,25 @@
+ at LIT_SITE_CFG_IN_HEADER@
+
+# Load common config for all compiler-rt unit tests.
+lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/unittests/lit.common.unit.configured")
+
+# Setup config name.
+config.name = 'RealtimeSanitizer-Unit'
+
+# Setup test source and exec root. For unit tests, we define
+# it as build directory with ASan unit tests.
+# FIXME: De-hardcode this path.
+config.test_exec_root = "@COMPILER_RT_BINARY_DIR@/lib/radsan/tests"
+config.test_source_root = config.test_exec_root
+
+if not config.parallelism_group:
+ config.parallelism_group = 'shadow-memory'
+
+if config.host_os == 'Darwin':
+ # On Darwin, we default to ignore_noninstrumented_modules=1, which also
+ # suppresses some races the tests are supposed to find. See radsan/lit.cfg.py.
+ if 'RADSAN_OPTIONS' in config.environment:
+ config.environment['RADSAN_OPTIONS'] += ':ignore_noninstrumented_modules=0'
+ else:
+ config.environment['RADSAN_OPTIONS'] = 'ignore_noninstrumented_modules=0'
+ config.environment['RADSAN_OPTIONS'] += ':ignore_interceptors_accesses=0'
diff --git a/compiler-rt/test/radsan/lit.cfg.py b/compiler-rt/test/radsan/lit.cfg.py
new file mode 100644
index 0000000000000..773b624900fa6
--- /dev/null
+++ b/compiler-rt/test/radsan/lit.cfg.py
@@ -0,0 +1,69 @@
+# -*- Python -*-
+
+import os
+
+# Setup config name.
+config.name = "RADSAN" + config.name_suffix
+
+# Setup source root.
+config.test_source_root = os.path.dirname(__file__)
+
+# Setup default compiler flags use with -fradsan-instrument option.
+clang_radsan_cflags = ["-fradsan-instrument", config.target_cflags]
+
+# If libc++ was used to build radsan libraries, libc++ is needed. Fix applied
+# to Linux only since -rpath may not be portable. This can be extended to
+# other platforms.
+if config.libcxx_used == "1" and config.host_os == "Linux":
+ clang_radsan_cflags = clang_radsan_cflags + (
+ ["-L%s -lc++ -Wl,-rpath=%s" % (config.llvm_shlib_dir, config.llvm_shlib_dir)]
+ )
+
+clang_radsan_cxxflags = config.cxx_mode_flags + clang_radsan_cflags
+
+
+def build_invocation(compile_flags):
+ return " " + " ".join([config.clang] + compile_flags) + " "
+
+
+# Assume that llvm-radsan is in the config.llvm_tools_dir.
+llvm_radsan = os.path.join(config.llvm_tools_dir, "llvm-radsan")
+
+# Setup substitutions.
+if config.host_os == "Linux":
+ libdl_flag = "-ldl"
+else:
+ libdl_flag = ""
+
+config.substitutions.append(("%clang ", build_invocation([config.target_cflags])))
+config.substitutions.append(
+ ("%clangxx ", build_invocation(config.cxx_mode_flags + [config.target_cflags]))
+)
+config.substitutions.append(("%clang_radsan ", build_invocation(clang_radsan_cflags)))
+config.substitutions.append(("%clangxx_radsan", build_invocation(clang_radsan_cxxflags)))
+config.substitutions.append(("%llvm_radsan", llvm_radsan))
+config.substitutions.append(
+ (
+ "%radsanlib",
+ (
+ "-lm -lpthread %s -lrt -L%s "
+ "-Wl,-whole-archive -lclang_rt.radsan%s -Wl,-no-whole-archive"
+ )
+ % (libdl_flag, config.compiler_rt_libdir, config.target_suffix),
+ )
+)
+
+# Default test suffixes.
+config.suffixes = [".c", ".cpp"]
+
+if config.host_os not in ["Darwin", "FreeBSD", "Linux", "NetBSD", "OpenBSD"]:
+ config.unsupported = True
+elif "64" not in config.host_arch:
+ if "arm" in config.host_arch:
+ if "-mthumb" in config.target_cflags:
+ config.unsupported = True
+ else:
+ config.unsupported = True
+
+if config.host_os == "NetBSD":
+ config.substitutions.insert(0, ("%run", config.netbsd_nomprotect_prefix))
diff --git a/compiler-rt/test/radsan/lit.site.cfg.py.in b/compiler-rt/test/radsan/lit.site.cfg.py.in
new file mode 100644
index 0000000000000..7d509c9f2eb91
--- /dev/null
+++ b/compiler-rt/test/radsan/lit.site.cfg.py.in
@@ -0,0 +1,17 @@
+ at LIT_SITE_CFG_IN_HEADER@
+
+# Tool-specific config options.
+config.name_suffix = "@RADSAN_TEST_CONFIG_SUFFIX@"
+config.radsan_lit_source_dir = "@RADSAN_LIT_SOURCE_DIR@"
+config.target_cflags = "@RADSAN_TEST_TARGET_CFLAGS@"
+config.target_arch = "@RADSAN_TEST_TARGET_ARCH@"
+config.built_with_llvm = ("@COMPILER_RT_STANDALONE_BUILD@" != "TRUE")
+
+if config.built_with_llvm:
+ config.available_features.add('built-in-llvm-tree')
+
+# Load common config for all compiler-rt lit tests
+lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured")
+
+# Load tool-specific config that would do the real work.
+lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg.py")
diff --git a/compiler-rt/test/sanitizer_common/CMakeLists.txt b/compiler-rt/test/sanitizer_common/CMakeLists.txt
index f2df8cec3549b..bdf839b348e25 100644
--- a/compiler-rt/test/sanitizer_common/CMakeLists.txt
+++ b/compiler-rt/test/sanitizer_common/CMakeLists.txt
@@ -7,7 +7,7 @@ set(SANITIZER_COMMON_TESTSUITES)
# FIXME(dliew): We should switch to COMPILER_RT_SANITIZERS_TO_BUILD instead of
# the hard coded `SUPPORTED_TOOLS_INIT` list once we know that the other
# sanitizers work.
-set(SUPPORTED_TOOLS_INIT asan lsan hwasan msan tsan ubsan)
+set(SUPPORTED_TOOLS_INIT asan lsan hwasan msan radsan tsan ubsan)
set(SUPPORTED_TOOLS)
foreach(SANITIZER_TOOL ${SUPPORTED_TOOLS_INIT})
string(TOUPPER ${SANITIZER_TOOL} SANITIZER_TOOL_UPPER)
diff --git a/compiler-rt/test/sanitizer_common/lit.common.cfg.py b/compiler-rt/test/sanitizer_common/lit.common.cfg.py
index 04af4816eb6e7..80c7372372f44 100644
--- a/compiler-rt/test/sanitizer_common/lit.common.cfg.py
+++ b/compiler-rt/test/sanitizer_common/lit.common.cfg.py
@@ -18,6 +18,9 @@
tool_options = "HWASAN_OPTIONS"
if not config.has_lld:
config.unsupported = True
+elif config.tool_name == "radsan":
+ tool_cflags = ["-fsanitize=realtime"]
+ tool_options = "RADSAN_OPTIONS"
elif config.tool_name == "tsan":
tool_cflags = ["-fsanitize=thread"]
tool_options = "TSAN_OPTIONS"
>From e78164140cd34dd3d2c369d258b5d0d8bcd26aa3 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Tue, 7 May 2024 15:28:48 -0700
Subject: [PATCH 02/33] Fixing some clang tidy foo
---
.../lib/radsan/radsan_interceptors.cpp | 8 +-
compiler-rt/lib/radsan/tests/radsan_test.cpp | 226 +++++++++---------
.../radsan/tests/radsan_test_interceptors.cpp | 176 +++++++-------
.../lib/radsan/tests/radsan_test_utilities.h | 4 +-
4 files changed, 207 insertions(+), 207 deletions(-)
diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/radsan/radsan_interceptors.cpp
index d50ece6099b14..6d0bc52893b35 100644
--- a/compiler-rt/lib/radsan/radsan_interceptors.cpp
+++ b/compiler-rt/lib/radsan/radsan_interceptors.cpp
@@ -55,7 +55,7 @@ INTERCEPTOR(int, open, const char *path, int oflag, ...) {
radsan::expectNotRealtime("open");
va_list args;
va_start(args, oflag);
- auto result = REAL(open)(path, oflag, args);
+ const int result = REAL(open)(path, oflag, args);
va_end(args);
return result;
}
@@ -66,7 +66,7 @@ INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) {
radsan::expectNotRealtime("openat");
va_list args;
va_start(args, oflag);
- auto result = REAL(openat)(fd, path, oflag, args);
+ const int result = REAL(openat)(fd, path, oflag, args);
va_end(args);
return result;
}
@@ -75,7 +75,7 @@ INTERCEPTOR(int, creat, const char *path, mode_t mode) {
// TODO Establish whether we should intercept here if the flag contains
// O_NONBLOCK
radsan::expectNotRealtime("creat");
- auto result = REAL(creat)(path, mode);
+ const int result = REAL(creat)(path, mode);
return result;
}
@@ -83,7 +83,7 @@ INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) {
radsan::expectNotRealtime("fcntl");
va_list args;
va_start(args, cmd);
- auto result = REAL(fcntl)(filedes, cmd, args);
+ const int result = REAL(fcntl)(filedes, cmd, args);
va_end(args);
return result;
}
diff --git a/compiler-rt/lib/radsan/tests/radsan_test.cpp b/compiler-rt/lib/radsan/tests/radsan_test.cpp
index 65c4380dfc602..9769e7a72779e 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test.cpp
@@ -36,168 +36,168 @@ using namespace testing;
using namespace radsan_testing;
using namespace std::chrono_literals;
-namespace {
-void invokeStdFunction(std::function<void()> &&function) { function(); }
-} // namespace
-
-TEST(TestRadsan, vectorPushBackAllocationDiesWhenRealtime) {
- auto vec = std::vector<float>{};
- auto func = [&vec]() { vec.push_back(0.4f); };
- expectRealtimeDeath(func);
- ASSERT_EQ(0u, vec.size());
- expectNonrealtimeSurvival(func);
- ASSERT_EQ(1u, vec.size());
-}
-
-TEST(TestRadsan, destructionOfObjectOnHeapDiesWhenRealtime) {
- auto obj = std::make_unique<std::array<float, 256>>();
- auto func = [&obj]() { obj.reset(); };
- expectRealtimeDeath(func);
- ASSERT_NE(nullptr, obj.get());
- expectNonrealtimeSurvival(func);
- ASSERT_EQ(nullptr, obj.get());
-}
-
-TEST(TestRadsan, sleepingAThreadDiesWhenRealtime) {
- auto func = []() { std::this_thread::sleep_for(1us); };
- expectRealtimeDeath(func);
- expectNonrealtimeSurvival(func);
-}
-
-TEST(TestRadsan, ifstreamCreationDiesWhenRealtime) {
- auto func = []() { auto ifs = std::ifstream("./file.txt"); };
- expectRealtimeDeath(func);
- expectNonrealtimeSurvival(func);
+TEST(TestRadsan, VectorPushBackAllocationDiesWhenRealtime) {
+ std::vector<float> Vec{};
+ auto Func = [&Vec]() { Vec.push_back(0.4f); };
+ ExpectRealtimeDeath(Func);
+ ASSERT_EQ(0u, Vec.size());
+ ExpectNonRealtimeSurvival(Func);
+ ASSERT_EQ(1u, Vec.size());
+}
+
+TEST(TestRadsan, DestructionOfObjectOnHeapDiesWhenRealtime) {
+ auto AllocatedPtr = std::make_unique<std::array<float, 256>>();
+ auto Func = [&AllocatedPtr]() { AllocatedPtr.reset(); };
+ ExpectRealtimeDeath(Func);
+ ASSERT_NE(nullptr, AllocatedPtr.get());
+ ExpectNonRealtimeSurvival(Func);
+ ASSERT_EQ(nullptr, AllocatedPtr.get());
+}
+
+TEST(TestRadsan, SleepingAThreadDiesWhenRealtime) {
+ auto Func = []() { std::this_thread::sleep_for(1us); };
+ ExpectRealtimeDeath(Func);
+ ExpectNonRealtimeSurvival(Func);
+}
+
+TEST(TestRadsan, IfstreamCreationDiesWhenRealtime) {
+ auto Func = []() { auto ifs = std::ifstream("./file.txt"); };
+ ExpectRealtimeDeath(Func);
+ ExpectNonRealtimeSurvival(Func);
std::remove("./file.txt");
}
-TEST(TestRadsan, ofstreamCreationDiesWhenRealtime) {
- auto func = []() { auto ofs = std::ofstream("./file.txt"); };
- expectRealtimeDeath(func);
- expectNonrealtimeSurvival(func);
+TEST(TestRadsan, OfstreamCreationDiesWhenRealtime) {
+ auto Func = []() { auto ofs = std::ofstream("./file.txt"); };
+ ExpectRealtimeDeath(Func);
+ ExpectNonRealtimeSurvival(Func);
std::remove("./file.txt");
}
-TEST(TestRadsan, lockingAMutexDiesWhenRealtime) {
- auto mutex = std::mutex{};
- auto func = [&]() { mutex.lock(); };
- expectRealtimeDeath(func);
- expectNonrealtimeSurvival(func);
+TEST(TestRadsan, LockingAMutexDiesWhenRealtime) {
+ std::mutex Mutex{};
+ auto Func = [&]() { Mutex.lock(); };
+ ExpectRealtimeDeath(Func);
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsan, unlockingAMutexDiesWhenRealtime) {
- auto mutex = std::mutex{};
- mutex.lock();
- auto func = [&]() { mutex.unlock(); };
- expectRealtimeDeath(func);
- expectNonrealtimeSurvival(func);
+TEST(TestRadsan, UnlockingAMutexDiesWhenRealtime) {
+ std::mutex Mutex{};
+ Mutex.lock();
+ auto Func = [&]() { Mutex.unlock(); };
+ ExpectRealtimeDeath(Func);
+ ExpectNonRealtimeSurvival(Func);
}
#if RADSAN_TEST_SHARED_MUTEX
-TEST(TestRadsan, lockingASharedMutexDiesWhenRealtime) {
- auto mutex = std::shared_mutex();
- auto func = [&]() { mutex.lock(); };
- expectRealtimeDeath(func);
- expectNonrealtimeSurvival(func);
+TEST(TestRadsan, LockingASharedMutexDiesWhenRealtime) {
+ std::shared_mutex Mutex{};
+ auto Func = [&]() { Mutex.lock(); };
+ ExpectRealtimeDeath(Func);
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsan, unlockingASharedMutexDiesWhenRealtime) {
- auto mutex = std::shared_mutex();
- mutex.lock();
- auto func = [&]() { mutex.unlock(); };
- expectRealtimeDeath(func);
- expectNonrealtimeSurvival(func);
+TEST(TestRadsan, UnlockingASharedMutexDiesWhenRealtime) {
+ std::shared_mutex Mutex{};
+ Mutex.lock();
+ auto Func = [&]() { Mutex.unlock(); };
+ ExpectRealtimeDeath(Func);
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsan, sharedLockingASharedMutexDiesWhenRealtime) {
- auto mutex = std::shared_mutex();
- auto func = [&]() { mutex.lock_shared(); };
- expectRealtimeDeath(func);
- expectNonrealtimeSurvival(func);
+TEST(TestRadsan, SharedLockingASharedMutexDiesWhenRealtime) {
+ std::shared_mutex Mutex{};
+ auto Func = [&]() { Mutex.lock_shared(); };
+ ExpectRealtimeDeath(Func);
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsan, sharedUnlockingASharedMutexDiesWhenRealtime) {
- auto mutex = std::shared_mutex();
- mutex.lock_shared();
- auto func = [&]() { mutex.unlock_shared(); };
- expectRealtimeDeath(func);
- expectNonrealtimeSurvival(func);
+TEST(TestRadsan, SharedUnlockingASharedMutexDiesWhenRealtime) {
+ std::shared_mutex Mutex{};
+ Mutex.lock_shared();
+ auto Func = [&]() { Mutex.unlock_shared(); };
+ ExpectRealtimeDeath(Func);
+ ExpectNonRealtimeSurvival(Func);
}
#endif // RADSAN_TEST_SHARED_MUTEX
-TEST(TestRadsan, launchingAThreadDiesWhenRealtime) {
- auto func = [&]() {
+TEST(TestRadsan, LaunchingAThreadDiesWhenRealtime) {
+ auto Func = [&]() {
auto t = std::thread([]() {});
t.join();
};
- expectRealtimeDeath(func);
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(Func);
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsan, copyingALambdaWithLargeCaptureDiesWhenRealtime) {
- auto lots_of_data = std::array<float, 16>{};
- auto lambda = [lots_of_data]() mutable {
+namespace {
+void InvokeStdFunction(std::function<void()> &&function) { function(); }
+} // namespace
+
+TEST(TestRadsan, CopyingALambdaWithLargeCaptureDiesWhenRealtime) {
+ std::array<float, 16> LotsOfData{};
+ auto lambda = [LotsOfData]() mutable {
// Stop everything getting optimised out
- lots_of_data[3] = 0.25f;
- EXPECT_EQ(16, lots_of_data.size());
- EXPECT_EQ(0.25f, lots_of_data[3]);
+ LotsOfData[3] = 0.25f;
+ EXPECT_EQ(16, LotsOfData.size());
+ EXPECT_EQ(0.25f, LotsOfData[3]);
};
- auto func = [&]() { invokeStdFunction(lambda); };
- expectRealtimeDeath(func);
- expectNonrealtimeSurvival(func);
+ auto Func = [&]() { InvokeStdFunction(lambda); };
+ ExpectRealtimeDeath(Func);
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsan, accessingALargeAtomicVariableDiesWhenRealtime) {
- auto small_atomic = std::atomic<float>{0.0f};
- ASSERT_TRUE(small_atomic.is_lock_free());
- realtimeInvoke([&small_atomic]() { auto x = small_atomic.load(); });
+TEST(TestRadsan, AccessingALargeAtomicVariableDiesWhenRealtime) {
+ std::atomic<float> SmallAtomic{0.0f};
+ ASSERT_TRUE(SmallAtomic.is_lock_free());
+ realtimeInvoke([&SmallAtomic]() { float x = SmallAtomic.load(); });
- auto large_atomic = std::atomic<std::array<float, 2048>>{{}};
- ASSERT_FALSE(large_atomic.is_lock_free());
- auto func = [&]() { auto x = large_atomic.load(); };
- expectRealtimeDeath(func);
- expectNonrealtimeSurvival(func);
+ std::atomic<std::array<float, 2048>> LargeAtomic{};
+ ASSERT_FALSE(LargeAtomic.is_lock_free());
+ auto Func = [&]() { auto x = LargeAtomic.load(); };
+ ExpectRealtimeDeath(Func);
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsan, firstCoutDiesWhenRealtime) {
- auto func = []() { std::cout << "Hello, world!" << std::endl; };
- expectRealtimeDeath(func);
- expectNonrealtimeSurvival(func);
+TEST(TestRadsan, FirstCoutDiesWhenRealtime) {
+ auto Func = []() { std::cout << "Hello, world!" << std::endl; };
+ ExpectRealtimeDeath(Func);
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsan, secondCoutDiesWhenRealtime) {
+TEST(TestRadsan, SecondCoutDiesWhenRealtime) {
std::cout << "Hello, world";
- auto func = []() { std::cout << "Hello, again!" << std::endl; };
- expectRealtimeDeath(func);
- expectNonrealtimeSurvival(func);
+ auto Func = []() { std::cout << "Hello, again!" << std::endl; };
+ ExpectRealtimeDeath(Func);
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsan, printfDiesWhenRealtime) {
- auto func = []() { printf("Hello, world!\n"); };
- expectRealtimeDeath(func);
- expectNonrealtimeSurvival(func);
+TEST(TestRadsan, PrintfDiesWhenRealtime) {
+ auto Func = []() { printf("Hello, world!\n"); };
+ ExpectRealtimeDeath(Func);
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsan, throwingAnExceptionDiesWhenRealtime) {
- auto func = [&]() {
+TEST(TestRadsan, ThrowingAnExceptionDiesWhenRealtime) {
+ auto Func = [&]() {
try {
throw std::exception();
} catch (std::exception &) {
}
};
- expectRealtimeDeath(func);
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(Func);
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsan, doesNotDieIfTurnedOff) {
- auto mutex = std::mutex{};
- auto realtime_unsafe_func = [&]() {
+TEST(TestRadsan, DoesNotDieIfTurnedOff) {
+ std::mutex Mutex{};
+ auto RealtimeUnsafeFunc = [&]() {
radsan_off();
- mutex.lock();
- mutex.unlock();
+ Mutex.lock();
+ Mutex.unlock();
radsan_on();
};
- realtimeInvoke(realtime_unsafe_func);
+ realtimeInvoke(RealtimeUnsafeFunc);
}
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
index 6b6bb6b76d7ff..95735d2059de3 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
@@ -62,37 +62,37 @@ constexpr const char *temporary_file_path() {
TEST(TestRadsanInterceptors, mallocDiesWhenRealtime) {
auto func = []() { EXPECT_NE(nullptr, malloc(1)); };
- expectRealtimeDeath(func, "malloc");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "malloc");
+ ExpectNonRealtimeSurvival(func);
}
TEST(TestRadsanInterceptors, reallocDiesWhenRealtime) {
auto *ptr_1 = malloc(1);
auto func = [ptr_1]() { EXPECT_NE(nullptr, realloc(ptr_1, 8)); };
- expectRealtimeDeath(func, "realloc");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "realloc");
+ ExpectNonRealtimeSurvival(func);
}
#if SANITIZER_APPLE
TEST(TestRadsanInterceptors, reallocfDiesWhenRealtime) {
auto *ptr_1 = malloc(1);
auto func = [ptr_1]() { EXPECT_NE(nullptr, reallocf(ptr_1, 8)); };
- expectRealtimeDeath(func, "reallocf");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "reallocf");
+ ExpectNonRealtimeSurvival(func);
}
#endif
TEST(TestRadsanInterceptors, vallocDiesWhenRealtime) {
auto func = []() { EXPECT_NE(nullptr, valloc(4)); };
- expectRealtimeDeath(func, "valloc");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "valloc");
+ ExpectNonRealtimeSurvival(func);
}
#if SANITIZER_INTERCEPT_ALIGNED_ALLOC
TEST(TestRadsanInterceptors, alignedAllocDiesWhenRealtime) {
auto func = []() { EXPECT_NE(nullptr, aligned_alloc(16, 32)); };
- expectRealtimeDeath(func, "aligned_alloc");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "aligned_alloc");
+ ExpectNonRealtimeSurvival(func);
}
#endif
@@ -100,8 +100,8 @@ TEST(TestRadsanInterceptors, alignedAllocDiesWhenRealtime) {
TEST(TestRadsanInterceptors, freeDiesWhenRealtime) {
auto *ptr_1 = malloc(1);
auto *ptr_2 = malloc(1);
- expectRealtimeDeath([ptr_1]() { free(ptr_1); }, "free");
- expectNonrealtimeSurvival([ptr_2]() { free(ptr_2); });
+ ExpectRealtimeDeath([ptr_1]() { free(ptr_1); }, "free");
+ ExpectNonRealtimeSurvival([ptr_2]() { free(ptr_2); });
// Prevent malloc/free pair being optimised out
ASSERT_NE(nullptr, ptr_1);
@@ -110,7 +110,7 @@ TEST(TestRadsanInterceptors, freeDiesWhenRealtime) {
TEST(TestRadsanInterceptors, freeSurvivesWhenRealtimeIfArgumentIsNull) {
realtimeInvoke([]() { free(NULL); });
- expectNonrealtimeSurvival([]() { free(NULL); });
+ ExpectNonRealtimeSurvival([]() { free(NULL); });
}
TEST(TestRadsanInterceptors, posixMemalignDiesWhenRealtime) {
@@ -118,23 +118,23 @@ TEST(TestRadsanInterceptors, posixMemalignDiesWhenRealtime) {
void *mem;
posix_memalign(&mem, 4, 4);
};
- expectRealtimeDeath(func, "posix_memalign");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "posix_memalign");
+ ExpectNonRealtimeSurvival(func);
}
#if SANITIZER_INTERCEPT_MEMALIGN
TEST(TestRadsanInterceptors, memalignDiesWhenRealtime) {
auto func = []() { EXPECT_NE(memalign(2, 2048), nullptr); };
- expectRealtimeDeath(func, "memalign");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "memalign");
+ ExpectNonRealtimeSurvival(func);
}
#endif
#if SANITIZER_INTERCEPT_PVALLOC
TEST(TestRadsanInterceptors, pvallocDiesWhenRealtime) {
auto func = []() { EXPECT_NE(pvalloc(2048), nullptr); };
- expectRealtimeDeath(func, "pvalloc");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "pvalloc");
+ ExpectNonRealtimeSurvival(func);
}
#endif
@@ -144,14 +144,14 @@ TEST(TestRadsanInterceptors, pvallocDiesWhenRealtime) {
TEST(TestRadsanInterceptors, sleepDiesWhenRealtime) {
auto func = []() { sleep(0u); };
- expectRealtimeDeath(func, "sleep");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "sleep");
+ ExpectNonRealtimeSurvival(func);
}
TEST(TestRadsanInterceptors, usleepDiesWhenRealtime) {
auto func = []() { usleep(1u); };
- expectRealtimeDeath(func, "usleep");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "usleep");
+ ExpectNonRealtimeSurvival(func);
}
TEST(TestRadsanInterceptors, nanosleepDiesWhenRealtime) {
@@ -159,8 +159,8 @@ TEST(TestRadsanInterceptors, nanosleepDiesWhenRealtime) {
auto t = timespec{};
nanosleep(&t, &t);
};
- expectRealtimeDeath(func, "nanosleep");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "nanosleep");
+ ExpectNonRealtimeSurvival(func);
}
/*
@@ -169,35 +169,35 @@ TEST(TestRadsanInterceptors, nanosleepDiesWhenRealtime) {
TEST(TestRadsanInterceptors, openDiesWhenRealtime) {
auto func = []() { open(temporary_file_path(), O_RDONLY); };
- expectRealtimeDeath(func, "open");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "open");
+ ExpectNonRealtimeSurvival(func);
std::remove(temporary_file_path());
}
TEST(TestRadsanInterceptors, openatDiesWhenRealtime) {
auto func = []() { openat(0, temporary_file_path(), O_RDONLY); };
- expectRealtimeDeath(func, "openat");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "openat");
+ ExpectNonRealtimeSurvival(func);
std::remove(temporary_file_path());
}
TEST(TestRadsanInterceptors, creatDiesWhenRealtime) {
auto func = []() { creat(temporary_file_path(), S_IWOTH | S_IROTH); };
- expectRealtimeDeath(func, "creat");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "creat");
+ ExpectNonRealtimeSurvival(func);
std::remove(temporary_file_path());
}
TEST(TestRadsanInterceptors, fcntlDiesWhenRealtime) {
auto func = []() { fcntl(0, F_GETFL); };
- expectRealtimeDeath(func, "fcntl");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "fcntl");
+ ExpectNonRealtimeSurvival(func);
}
TEST(TestRadsanInterceptors, closeDiesWhenRealtime) {
auto func = []() { close(0); };
- expectRealtimeDeath(func, "close");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "close");
+ ExpectNonRealtimeSurvival(func);
}
TEST(TestRadsanInterceptors, fopenDiesWhenRealtime) {
@@ -205,8 +205,8 @@ TEST(TestRadsanInterceptors, fopenDiesWhenRealtime) {
auto fd = fopen(temporary_file_path(), "w");
EXPECT_THAT(fd, Ne(nullptr));
};
- expectRealtimeDeath(func, "fopen");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "fopen");
+ ExpectNonRealtimeSurvival(func);
std::remove(temporary_file_path());
}
@@ -216,8 +216,8 @@ TEST(TestRadsanInterceptors, freadDiesWhenRealtime) {
char c{};
fread(&c, 1, 1, fd);
};
- expectRealtimeDeath(func, "fread");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "fread");
+ ExpectNonRealtimeSurvival(func);
if (fd != nullptr)
fclose(fd);
std::remove(temporary_file_path());
@@ -228,8 +228,8 @@ TEST(TestRadsanInterceptors, fwriteDiesWhenRealtime) {
ASSERT_NE(nullptr, fd);
auto message = "Hello, world!";
auto func = [&]() { fwrite(&message, 1, 4, fd); };
- expectRealtimeDeath(func, "fwrite");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "fwrite");
+ ExpectNonRealtimeSurvival(func);
std::remove(temporary_file_path());
}
@@ -237,23 +237,23 @@ TEST(TestRadsanInterceptors, fcloseDiesWhenRealtime) {
auto fd = fopen(temporary_file_path(), "w");
EXPECT_THAT(fd, Ne(nullptr));
auto func = [fd]() { fclose(fd); };
- expectRealtimeDeath(func, "fclose");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "fclose");
+ ExpectNonRealtimeSurvival(func);
std::remove(temporary_file_path());
}
TEST(TestRadsanInterceptors, putsDiesWhenRealtime) {
auto func = []() { puts("Hello, world!\n"); };
- expectRealtimeDeath(func);
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func);
+ ExpectNonRealtimeSurvival(func);
}
TEST(TestRadsanInterceptors, fputsDiesWhenRealtime) {
auto fd = fopen(temporary_file_path(), "w");
ASSERT_THAT(fd, Ne(nullptr)) << errno;
auto func = [fd]() { fputs("Hello, world!\n", fd); };
- expectRealtimeDeath(func);
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func);
+ ExpectNonRealtimeSurvival(func);
if (fd != nullptr)
fclose(fd);
std::remove(temporary_file_path());
@@ -270,8 +270,8 @@ TEST(TestRadsanInterceptors, pthreadCreateDiesWhenRealtime) {
struct thread_info *tinfo;
pthread_create(&thread, &attr, &fake_thread_entry_point, tinfo);
};
- expectRealtimeDeath(func, "pthread_create");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "pthread_create");
+ ExpectNonRealtimeSurvival(func);
}
TEST(TestRadsanInterceptors, pthreadMutexLockDiesWhenRealtime) {
@@ -280,8 +280,8 @@ TEST(TestRadsanInterceptors, pthreadMutexLockDiesWhenRealtime) {
pthread_mutex_lock(&mutex);
};
- expectRealtimeDeath(func, "pthread_mutex_lock");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "pthread_mutex_lock");
+ ExpectNonRealtimeSurvival(func);
}
TEST(TestRadsanInterceptors, pthreadMutexUnlockDiesWhenRealtime) {
@@ -290,8 +290,8 @@ TEST(TestRadsanInterceptors, pthreadMutexUnlockDiesWhenRealtime) {
pthread_mutex_unlock(&mutex);
};
- expectRealtimeDeath(func, "pthread_mutex_unlock");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "pthread_mutex_unlock");
+ ExpectNonRealtimeSurvival(func);
}
TEST(TestRadsanInterceptors, pthreadMutexJoinDiesWhenRealtime) {
@@ -300,8 +300,8 @@ TEST(TestRadsanInterceptors, pthreadMutexJoinDiesWhenRealtime) {
pthread_join(thread, nullptr);
};
- expectRealtimeDeath(func, "pthread_join");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "pthread_join");
+ ExpectNonRealtimeSurvival(func);
}
#if SANITIZER_APPLE
@@ -314,8 +314,8 @@ TEST(TestRadsanInterceptors, osSpinLockLockDiesWhenRealtime) {
auto spin_lock = OSSpinLock{};
OSSpinLockLock(&spin_lock);
};
- expectRealtimeDeath(func, "OSSpinLockLock");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "OSSpinLockLock");
+ ExpectNonRealtimeSurvival(func);
}
#pragma clang diagnostic pop
@@ -324,8 +324,8 @@ TEST(TestRadsanInterceptors, osUnfairLockLockDiesWhenRealtime) {
auto unfair_lock = os_unfair_lock_s{};
os_unfair_lock_lock(&unfair_lock);
};
- expectRealtimeDeath(func, "os_unfair_lock_lock");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "os_unfair_lock_lock");
+ ExpectNonRealtimeSurvival(func);
}
#endif
@@ -334,8 +334,8 @@ TEST(TestRadsanInterceptors, spinLockLockDiesWhenRealtime) {
auto spinlock = pthread_spinlock_t{};
pthread_spin_init(&spinlock, PTHREAD_PROCESS_SHARED);
auto func = [&]() { pthread_spin_lock(&spinlock); };
- expectRealtimeDeath(func, "pthread_spin_lock");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "pthread_spin_lock");
+ ExpectNonRealtimeSurvival(func);
}
#endif
@@ -344,8 +344,8 @@ TEST(TestRadsanInterceptors, pthreadCondSignalDiesWhenRealtime) {
auto cond = pthread_cond_t{};
pthread_cond_signal(&cond);
};
- expectRealtimeDeath(func, "pthread_cond_signal");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "pthread_cond_signal");
+ ExpectNonRealtimeSurvival(func);
}
TEST(TestRadsanInterceptors, pthreadCondBroadcastDiesWhenRealtime) {
@@ -353,8 +353,8 @@ TEST(TestRadsanInterceptors, pthreadCondBroadcastDiesWhenRealtime) {
auto cond = pthread_cond_t{};
pthread_cond_broadcast(&cond);
};
- expectRealtimeDeath(func, "pthread_cond_broadcast");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "pthread_cond_broadcast");
+ ExpectNonRealtimeSurvival(func);
}
TEST(TestRadsanInterceptors, pthreadCondWaitDiesWhenRealtime) {
@@ -363,7 +363,7 @@ TEST(TestRadsanInterceptors, pthreadCondWaitDiesWhenRealtime) {
ASSERT_EQ(0, pthread_cond_init(&cond, nullptr));
ASSERT_EQ(0, pthread_mutex_init(&mutex, nullptr));
auto func = [&]() { pthread_cond_wait(&cond, &mutex); };
- expectRealtimeDeath(func, "pthread_cond_wait");
+ ExpectRealtimeDeath(func, "pthread_cond_wait");
// It's very difficult to test the success case here without doing some
// sleeping, which is at the mercy of the scheduler. What's really important
// here is the interception - so we're only testing that for now.
@@ -374,8 +374,8 @@ TEST(TestRadsanInterceptors, pthreadRwlockRdlockDiesWhenRealtime) {
auto rwlock = pthread_rwlock_t{};
pthread_rwlock_rdlock(&rwlock);
};
- expectRealtimeDeath(func, "pthread_rwlock_rdlock");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "pthread_rwlock_rdlock");
+ ExpectNonRealtimeSurvival(func);
}
TEST(TestRadsanInterceptors, pthreadRwlockUnlockDiesWhenRealtime) {
@@ -383,8 +383,8 @@ TEST(TestRadsanInterceptors, pthreadRwlockUnlockDiesWhenRealtime) {
auto rwlock = pthread_rwlock_t{};
pthread_rwlock_unlock(&rwlock);
};
- expectRealtimeDeath(func, "pthread_rwlock_unlock");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "pthread_rwlock_unlock");
+ ExpectNonRealtimeSurvival(func);
}
TEST(TestRadsanInterceptors, pthreadRwlockWrlockDiesWhenRealtime) {
@@ -392,8 +392,8 @@ TEST(TestRadsanInterceptors, pthreadRwlockWrlockDiesWhenRealtime) {
auto rwlock = pthread_rwlock_t{};
pthread_rwlock_wrlock(&rwlock);
};
- expectRealtimeDeath(func, "pthread_rwlock_wrlock");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "pthread_rwlock_wrlock");
+ ExpectNonRealtimeSurvival(func);
}
/*
@@ -401,54 +401,54 @@ TEST(TestRadsanInterceptors, pthreadRwlockWrlockDiesWhenRealtime) {
*/
TEST(TestRadsanInterceptors, openingASocketDiesWhenRealtime) {
auto func = []() { socket(PF_INET, SOCK_STREAM, 0); };
- expectRealtimeDeath(func, "socket");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "socket");
+ ExpectNonRealtimeSurvival(func);
}
TEST(TestRadsanInterceptors, sendToASocketDiesWhenRealtime) {
auto func = []() { send(0, nullptr, 0, 0); };
- expectRealtimeDeath(func, "send");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "send");
+ ExpectNonRealtimeSurvival(func);
}
TEST(TestRadsanInterceptors, sendmsgToASocketDiesWhenRealtime) {
auto const msg = msghdr{};
auto func = [&]() { sendmsg(0, &msg, 0); };
- expectRealtimeDeath(func, "sendmsg");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "sendmsg");
+ ExpectNonRealtimeSurvival(func);
}
TEST(TestRadsanInterceptors, sendtoToASocketDiesWhenRealtime) {
auto const addr = sockaddr{};
auto const len = socklen_t{};
auto func = [&]() { sendto(0, nullptr, 0, 0, &addr, len); };
- expectRealtimeDeath(func, "sendto");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "sendto");
+ ExpectNonRealtimeSurvival(func);
}
TEST(TestRadsanInterceptors, recvFromASocketDiesWhenRealtime) {
auto func = []() { recv(0, nullptr, 0, 0); };
- expectRealtimeDeath(func, "recv");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "recv");
+ ExpectNonRealtimeSurvival(func);
}
TEST(TestRadsanInterceptors, recvfromOnASocketDiesWhenRealtime) {
auto addr = sockaddr{};
auto len = socklen_t{};
auto func = [&]() { recvfrom(0, nullptr, 0, 0, &addr, &len); };
- expectRealtimeDeath(func, "recvfrom");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "recvfrom");
+ ExpectNonRealtimeSurvival(func);
}
TEST(TestRadsanInterceptors, recvmsgOnASocketDiesWhenRealtime) {
auto msg = msghdr{};
auto func = [&]() { recvmsg(0, &msg, 0); };
- expectRealtimeDeath(func, "recvmsg");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "recvmsg");
+ ExpectNonRealtimeSurvival(func);
}
TEST(TestRadsanInterceptors, shutdownOnASocketDiesWhenRealtime) {
auto func = [&]() { shutdown(0, 0); };
- expectRealtimeDeath(func, "shutdown");
- expectNonrealtimeSurvival(func);
+ ExpectRealtimeDeath(func, "shutdown");
+ ExpectNonRealtimeSurvival(func);
}
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h b/compiler-rt/lib/radsan/tests/radsan_test_utilities.h
index fb3681aa97b06..dac88e4dd1c46 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h
+++ b/compiler-rt/lib/radsan/tests/radsan_test_utilities.h
@@ -25,7 +25,7 @@ void realtimeInvoke(Function &&func)
}
template <typename Function>
-void expectRealtimeDeath(Function &&func,
+void ExpectRealtimeDeath(Function &&func,
const char *intercepted_method_name = nullptr) {
using namespace testing;
@@ -42,7 +42,7 @@ void expectRealtimeDeath(Function &&func,
ExitedWithCode(EXIT_FAILURE), expected_error_substr());
}
-template <typename Function> void expectNonrealtimeSurvival(Function &&func) {
+template <typename Function> void ExpectNonRealtimeSurvival(Function &&func) {
std::forward<Function>(func)();
}
>From 2e5f8accc7d054b405a0802f384c3e8e505d99af Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Tue, 7 May 2024 15:36:27 -0700
Subject: [PATCH 03/33] One round of renaming
---
compiler-rt/lib/radsan/radsan.cpp | 8 +-
compiler-rt/lib/radsan/radsan_context.cpp | 50 +++++-----
compiler-rt/lib/radsan/radsan_context.h | 20 ++--
.../lib/radsan/radsan_interceptors.cpp | 96 +++++++++----------
.../lib/radsan/tests/radsan_test_context.cpp | 60 ++++++------
5 files changed, 117 insertions(+), 117 deletions(-)
diff --git a/compiler-rt/lib/radsan/radsan.cpp b/compiler-rt/lib/radsan/radsan.cpp
index 32a1f8223e55d..b4e56479b944a 100644
--- a/compiler-rt/lib/radsan/radsan.cpp
+++ b/compiler-rt/lib/radsan/radsan.cpp
@@ -17,18 +17,18 @@ extern "C" {
RADSAN_EXPORT void radsan_init() { radsan::initialiseInterceptors(); }
RADSAN_EXPORT void radsan_realtime_enter() {
- radsan::getContextForThisThread().realtimePush();
+ radsan::getContextForThisThread().RealtimePush();
}
RADSAN_EXPORT void radsan_realtime_exit() {
- radsan::getContextForThisThread().realtimePop();
+ radsan::getContextForThisThread().RealtimePop();
}
RADSAN_EXPORT void radsan_off() {
- radsan::getContextForThisThread().bypassPush();
+ radsan::getContextForThisThread().BypassPush();
}
RADSAN_EXPORT void radsan_on() {
- radsan::getContextForThisThread().bypassPop();
+ radsan::getContextForThisThread().BypassPop();
}
}
diff --git a/compiler-rt/lib/radsan/radsan_context.cpp b/compiler-rt/lib/radsan/radsan_context.cpp
index 5ca70d3fd9dc5..03e0a01d7cd97 100644
--- a/compiler-rt/lib/radsan/radsan_context.cpp
+++ b/compiler-rt/lib/radsan/radsan_context.cpp
@@ -24,9 +24,9 @@ using namespace __sanitizer;
namespace detail {
-static pthread_key_t key;
-static pthread_once_t key_once = PTHREAD_ONCE_INIT;
-void internalFree(void *ptr) { InternalFree(ptr); }
+static pthread_key_t Key;
+static pthread_once_t KeyOnce = PTHREAD_ONCE_INIT;
+void internalFree(void *Ptr) { __sanitizer::InternalFree(Ptr); }
} // namespace detail
@@ -34,49 +34,49 @@ namespace radsan {
Context::Context() = default;
-void Context::realtimePush() { realtime_depth_++; }
+void Context::RealtimePush() { RealtimeDepth++; }
-void Context::realtimePop() { realtime_depth_--; }
+void Context::RealtimePop() { RealtimeDepth--; }
-void Context::bypassPush() { bypass_depth_++; }
+void Context::BypassPush() { BypassDepth++; }
-void Context::bypassPop() { bypass_depth_--; }
+void Context::BypassPop() { BypassDepth--; }
-void Context::expectNotRealtime(const char *intercepted_function_name) {
- if (inRealtimeContext() && !isBypassed()) {
- bypassPush();
- printDiagnostics(intercepted_function_name);
+void Context::ExpectNotRealtime(const char *InterceptedFunctionName) {
+ if (InRealtimeContext() && !IsBypassed()) {
+ BypassPush();
+ PrintDiagnostics(InterceptedFunctionName);
exit(EXIT_FAILURE);
- bypassPop();
+ BypassPop();
}
}
-bool Context::inRealtimeContext() const { return realtime_depth_ > 0; }
+bool Context::InRealtimeContext() const { return RealtimeDepth > 0; }
-bool Context::isBypassed() const { return bypass_depth_ > 0; }
+bool Context::IsBypassed() const { return BypassDepth > 0; }
-void Context::printDiagnostics(const char *intercepted_function_name) {
+void Context::PrintDiagnostics(const char *InterceptedFunctionName) {
fprintf(stderr,
"Real-time violation: intercepted call to real-time unsafe function "
"`%s` in real-time context! Stack trace:\n",
- intercepted_function_name);
+ InterceptedFunctionName);
radsan::printStackTrace();
}
Context &getContextForThisThread() {
- auto make_tls_key = []() {
- CHECK_EQ(pthread_key_create(&detail::key, detail::internalFree), 0);
+ auto MakeTlsKey = []() {
+ CHECK_EQ(pthread_key_create(&detail::Key, detail::internalFree), 0);
};
- pthread_once(&detail::key_once, make_tls_key);
- auto *ptr = static_cast<Context *>(pthread_getspecific(detail::key));
- if (ptr == nullptr) {
- ptr = static_cast<Context *>(InternalAlloc(sizeof(Context)));
- new(ptr) Context();
- pthread_setspecific(detail::key, ptr);
+ pthread_once(&detail::KeyOnce, MakeTlsKey);
+ Context *CurrentThreadContext = static_cast<Context *>(pthread_getspecific(detail::Key));
+ if (CurrentThreadContext == nullptr) {
+ CurrentThreadContext = static_cast<Context *>(InternalAlloc(sizeof(Context)));
+ new(CurrentThreadContext) Context();
+ pthread_setspecific(detail::Key, CurrentThreadContext);
}
- return *ptr;
+ return *CurrentThreadContext;
}
} // namespace radsan
diff --git a/compiler-rt/lib/radsan/radsan_context.h b/compiler-rt/lib/radsan/radsan_context.h
index efd3677107469..1b841446b7c1f 100644
--- a/compiler-rt/lib/radsan/radsan_context.h
+++ b/compiler-rt/lib/radsan/radsan_context.h
@@ -16,21 +16,21 @@ class Context {
public:
Context();
- void realtimePush();
- void realtimePop();
+ void RealtimePush();
+ void RealtimePop();
- void bypassPush();
- void bypassPop();
+ void BypassPush();
+ void BypassPop();
- void expectNotRealtime(const char *interpreted_function_name);
+ void ExpectNotRealtime(const char *interpreted_function_name);
private:
- bool inRealtimeContext() const;
- bool isBypassed() const;
- void printDiagnostics(const char *intercepted_function_name);
+ bool InRealtimeContext() const;
+ bool IsBypassed() const;
+ void PrintDiagnostics(const char *InterceptedFunctionName);
- int realtime_depth_{0};
- int bypass_depth_{0};
+ int RealtimeDepth{0};
+ int BypassDepth{0};
};
Context &getContextForThisThread();
diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/radsan/radsan_interceptors.cpp
index 6d0bc52893b35..4318f4382257d 100644
--- a/compiler-rt/lib/radsan/radsan_interceptors.cpp
+++ b/compiler-rt/lib/radsan/radsan_interceptors.cpp
@@ -40,8 +40,8 @@
using namespace __sanitizer;
namespace radsan {
-void expectNotRealtime(const char *intercepted_function_name) {
- getContextForThisThread().expectNotRealtime(intercepted_function_name);
+void ExpectNotRealtime(const char *InterceptedFunctionName) {
+ getContextForThisThread().ExpectNotRealtime(InterceptedFunctionName);
}
} // namespace radsan
@@ -52,7 +52,7 @@ void expectNotRealtime(const char *intercepted_function_name) {
INTERCEPTOR(int, open, const char *path, int oflag, ...) {
// TODO Establish whether we should intercept here if the flag contains
// O_NONBLOCK
- radsan::expectNotRealtime("open");
+ radsan::ExpectNotRealtime("open");
va_list args;
va_start(args, oflag);
const int result = REAL(open)(path, oflag, args);
@@ -63,7 +63,7 @@ INTERCEPTOR(int, open, const char *path, int oflag, ...) {
INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) {
// TODO Establish whether we should intercept here if the flag contains
// O_NONBLOCK
- radsan::expectNotRealtime("openat");
+ radsan::ExpectNotRealtime("openat");
va_list args;
va_start(args, oflag);
const int result = REAL(openat)(fd, path, oflag, args);
@@ -74,13 +74,13 @@ INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) {
INTERCEPTOR(int, creat, const char *path, mode_t mode) {
// TODO Establish whether we should intercept here if the flag contains
// O_NONBLOCK
- radsan::expectNotRealtime("creat");
+ radsan::ExpectNotRealtime("creat");
const int result = REAL(creat)(path, mode);
return result;
}
INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) {
- radsan::expectNotRealtime("fcntl");
+ radsan::ExpectNotRealtime("fcntl");
va_list args;
va_start(args, cmd);
const int result = REAL(fcntl)(filedes, cmd, args);
@@ -89,34 +89,34 @@ INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) {
}
INTERCEPTOR(int, close, int filedes) {
- radsan::expectNotRealtime("close");
+ radsan::ExpectNotRealtime("close");
return REAL(close)(filedes);
}
INTERCEPTOR(FILE *, fopen, const char *path, const char *mode) {
- radsan::expectNotRealtime("fopen");
+ radsan::ExpectNotRealtime("fopen");
return REAL(fopen)(path, mode);
}
INTERCEPTOR(size_t, fread, void *ptr, size_t size, size_t nitems,
FILE *stream) {
- radsan::expectNotRealtime("fread");
+ radsan::ExpectNotRealtime("fread");
return REAL(fread)(ptr, size, nitems, stream);
}
INTERCEPTOR(size_t, fwrite, const void *ptr, size_t size, size_t nitems,
FILE *stream) {
- radsan::expectNotRealtime("fwrite");
+ radsan::ExpectNotRealtime("fwrite");
return REAL(fwrite)(ptr, size, nitems, stream);
}
INTERCEPTOR(int, fclose, FILE *stream) {
- radsan::expectNotRealtime("fclose");
+ radsan::ExpectNotRealtime("fclose");
return REAL(fclose)(stream);
}
INTERCEPTOR(int, fputs, const char *s, FILE *stream) {
- radsan::expectNotRealtime("fputs");
+ radsan::ExpectNotRealtime("fputs");
return REAL(fputs)(s, stream);
}
@@ -125,7 +125,7 @@ INTERCEPTOR(int, fputs, const char *s, FILE *stream) {
*/
INTERCEPTOR(int, puts, const char *s) {
- radsan::expectNotRealtime("puts");
+ radsan::ExpectNotRealtime("puts");
return REAL(puts)(s);
}
@@ -138,77 +138,77 @@ INTERCEPTOR(int, puts, const char *s) {
// OSSpinLockLock is deprecated, but still in use in libc++
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
INTERCEPTOR(void, OSSpinLockLock, volatile OSSpinLock *lock) {
- radsan::expectNotRealtime("OSSpinLockLock");
+ radsan::ExpectNotRealtime("OSSpinLockLock");
return REAL(OSSpinLockLock)(lock);
}
#pragma clang diagnostic pop
INTERCEPTOR(void, os_unfair_lock_lock, os_unfair_lock_t lock) {
- radsan::expectNotRealtime("os_unfair_lock_lock");
+ radsan::ExpectNotRealtime("os_unfair_lock_lock");
return REAL(os_unfair_lock_lock)(lock);
}
#elif SANITIZER_LINUX
INTERCEPTOR(int, pthread_spin_lock, pthread_spinlock_t *spinlock) {
- radsan::expectNotRealtime("pthread_spin_lock");
+ radsan::ExpectNotRealtime("pthread_spin_lock");
return REAL(pthread_spin_lock)(spinlock);
}
#endif
INTERCEPTOR(int, pthread_create, pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg) {
- radsan::expectNotRealtime("pthread_create");
+ radsan::ExpectNotRealtime("pthread_create");
return REAL(pthread_create)(thread, attr, start_routine, arg);
}
INTERCEPTOR(int, pthread_mutex_lock, pthread_mutex_t *mutex) {
- radsan::expectNotRealtime("pthread_mutex_lock");
+ radsan::ExpectNotRealtime("pthread_mutex_lock");
return REAL(pthread_mutex_lock)(mutex);
}
INTERCEPTOR(int, pthread_mutex_unlock, pthread_mutex_t *mutex) {
- radsan::expectNotRealtime("pthread_mutex_unlock");
+ radsan::ExpectNotRealtime("pthread_mutex_unlock");
return REAL(pthread_mutex_unlock)(mutex);
}
INTERCEPTOR(int, pthread_join, pthread_t thread, void **value_ptr) {
- radsan::expectNotRealtime("pthread_join");
+ radsan::ExpectNotRealtime("pthread_join");
return REAL(pthread_join)(thread, value_ptr);
}
INTERCEPTOR(int, pthread_cond_signal, pthread_cond_t *cond) {
- radsan::expectNotRealtime("pthread_cond_signal");
+ radsan::ExpectNotRealtime("pthread_cond_signal");
return REAL(pthread_cond_signal)(cond);
}
INTERCEPTOR(int, pthread_cond_broadcast, pthread_cond_t *cond) {
- radsan::expectNotRealtime("pthread_cond_broadcast");
+ radsan::ExpectNotRealtime("pthread_cond_broadcast");
return REAL(pthread_cond_broadcast)(cond);
}
INTERCEPTOR(int, pthread_cond_wait, pthread_cond_t *cond,
pthread_mutex_t *mutex) {
- radsan::expectNotRealtime("pthread_cond_wait");
+ radsan::ExpectNotRealtime("pthread_cond_wait");
return REAL(pthread_cond_wait)(cond, mutex);
}
INTERCEPTOR(int, pthread_cond_timedwait, pthread_cond_t *cond,
pthread_mutex_t *mutex, const timespec *ts) {
- radsan::expectNotRealtime("pthread_cond_timedwait");
+ radsan::ExpectNotRealtime("pthread_cond_timedwait");
return REAL(pthread_cond_timedwait)(cond, mutex, ts);
}
INTERCEPTOR(int, pthread_rwlock_rdlock, pthread_rwlock_t *lock) {
- radsan::expectNotRealtime("pthread_rwlock_rdlock");
+ radsan::ExpectNotRealtime("pthread_rwlock_rdlock");
return REAL(pthread_rwlock_rdlock)(lock);
}
INTERCEPTOR(int, pthread_rwlock_unlock, pthread_rwlock_t *lock) {
- radsan::expectNotRealtime("pthread_rwlock_unlock");
+ radsan::ExpectNotRealtime("pthread_rwlock_unlock");
return REAL(pthread_rwlock_unlock)(lock);
}
INTERCEPTOR(int, pthread_rwlock_wrlock, pthread_rwlock_t *lock) {
- radsan::expectNotRealtime("pthread_rwlock_wrlock");
+ radsan::ExpectNotRealtime("pthread_rwlock_wrlock");
return REAL(pthread_rwlock_wrlock)(lock);
}
@@ -217,18 +217,18 @@ INTERCEPTOR(int, pthread_rwlock_wrlock, pthread_rwlock_t *lock) {
*/
INTERCEPTOR(unsigned int, sleep, unsigned int s) {
- radsan::expectNotRealtime("sleep");
+ radsan::ExpectNotRealtime("sleep");
return REAL(sleep)(s);
}
INTERCEPTOR(int, usleep, useconds_t u) {
- radsan::expectNotRealtime("usleep");
+ radsan::ExpectNotRealtime("usleep");
return REAL(usleep)(u);
}
INTERCEPTOR(int, nanosleep, const struct timespec *rqtp,
struct timespec *rmtp) {
- radsan::expectNotRealtime("nanosleep");
+ radsan::ExpectNotRealtime("nanosleep");
return REAL(nanosleep)(rqtp, rmtp);
}
@@ -237,40 +237,40 @@ INTERCEPTOR(int, nanosleep, const struct timespec *rqtp,
*/
INTERCEPTOR(void *, calloc, SIZE_T num, SIZE_T size) {
- radsan::expectNotRealtime("calloc");
+ radsan::ExpectNotRealtime("calloc");
return REAL(calloc)(num, size);
}
INTERCEPTOR(void, free, void *ptr) {
if (ptr != NULL) {
- radsan::expectNotRealtime("free");
+ radsan::ExpectNotRealtime("free");
}
return REAL(free)(ptr);
}
INTERCEPTOR(void *, malloc, SIZE_T size) {
- radsan::expectNotRealtime("malloc");
+ radsan::ExpectNotRealtime("malloc");
return REAL(malloc)(size);
}
INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) {
- radsan::expectNotRealtime("realloc");
+ radsan::ExpectNotRealtime("realloc");
return REAL(realloc)(ptr, size);
}
INTERCEPTOR(void *, reallocf, void *ptr, SIZE_T size) {
- radsan::expectNotRealtime("reallocf");
+ radsan::ExpectNotRealtime("reallocf");
return REAL(reallocf)(ptr, size);
}
INTERCEPTOR(void *, valloc, SIZE_T size) {
- radsan::expectNotRealtime("valloc");
+ radsan::ExpectNotRealtime("valloc");
return REAL(valloc)(size);
}
#if SANITIZER_INTERCEPT_ALIGNED_ALLOC
INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) {
- radsan::expectNotRealtime("aligned_alloc");
+ radsan::ExpectNotRealtime("aligned_alloc");
return REAL(aligned_alloc)(alignment, size);
}
#define RADSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(aligned_alloc)
@@ -279,20 +279,20 @@ INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) {
#endif
INTERCEPTOR(int, posix_memalign, void **memptr, size_t alignment, size_t size) {
- radsan::expectNotRealtime("posix_memalign");
+ radsan::ExpectNotRealtime("posix_memalign");
return REAL(posix_memalign)(memptr, alignment, size);
}
#if SANITIZER_INTERCEPT_MEMALIGN
INTERCEPTOR(void *, memalign, size_t alignment, size_t size) {
- radsan::expectNotRealtime("memalign");
+ radsan::ExpectNotRealtime("memalign");
return REAL(memalign)(alignment, size);
}
#endif
#if SANITIZER_INTERCEPT_PVALLOC
INTERCEPTOR(void *, pvalloc, size_t size) {
- radsan::expectNotRealtime("pvalloc");
+ radsan::ExpectNotRealtime("pvalloc");
return REAL(pvalloc)(size);
}
#endif
@@ -302,45 +302,45 @@ INTERCEPTOR(void *, pvalloc, size_t size) {
*/
INTERCEPTOR(int, socket, int domain, int type, int protocol) {
- radsan::expectNotRealtime("socket");
+ radsan::ExpectNotRealtime("socket");
return REAL(socket)(domain, type, protocol);
}
INTERCEPTOR(ssize_t, send, int sockfd, const void *buf, size_t len, int flags) {
- radsan::expectNotRealtime("send");
+ radsan::ExpectNotRealtime("send");
return REAL(send)(sockfd, buf, len, flags);
}
INTERCEPTOR(ssize_t, sendmsg, int socket, const struct msghdr *message,
int flags) {
- radsan::expectNotRealtime("sendmsg");
+ radsan::ExpectNotRealtime("sendmsg");
return REAL(sendmsg)(socket, message, flags);
}
INTERCEPTOR(ssize_t, sendto, int socket, const void *buffer, size_t length,
int flags, const struct sockaddr *dest_addr, socklen_t dest_len) {
- radsan::expectNotRealtime("sendto");
+ radsan::ExpectNotRealtime("sendto");
return REAL(sendto)(socket, buffer, length, flags, dest_addr, dest_len);
}
INTERCEPTOR(ssize_t, recv, int socket, void *buffer, size_t length, int flags) {
- radsan::expectNotRealtime("recv");
+ radsan::ExpectNotRealtime("recv");
return REAL(recv)(socket, buffer, length, flags);
}
INTERCEPTOR(ssize_t, recvfrom, int socket, void *buffer, size_t length,
int flags, struct sockaddr *address, socklen_t *address_len) {
- radsan::expectNotRealtime("recvfrom");
+ radsan::ExpectNotRealtime("recvfrom");
return REAL(recvfrom)(socket, buffer, length, flags, address, address_len);
}
INTERCEPTOR(ssize_t, recvmsg, int socket, struct msghdr *message, int flags) {
- radsan::expectNotRealtime("recvmsg");
+ radsan::ExpectNotRealtime("recvmsg");
return REAL(recvmsg)(socket, message, flags);
}
INTERCEPTOR(int, shutdown, int socket, int how) {
- radsan::expectNotRealtime("shutdown");
+ radsan::ExpectNotRealtime("shutdown");
return REAL(shutdown)(socket, how);
}
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp
index c52a0fff3b7ef..b654ac958be4b 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp
@@ -14,56 +14,56 @@
TEST(TestRadsanContext, canCreateContext) { auto context = radsan::Context{}; }
-TEST(TestRadsanContext, expectNotRealtimeDoesNotDieBeforeRealtimePush) {
+TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieBeforeRealtimePush) {
auto context = radsan::Context{};
- context.expectNotRealtime("do_some_stuff");
+ context.ExpectNotRealtime("do_some_stuff");
}
-TEST(TestRadsanContext, expectNotRealtimeDoesNotDieAfterPushAndPop) {
+TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieAfterPushAndPop) {
auto context = radsan::Context{};
- context.realtimePush();
- context.realtimePop();
- context.expectNotRealtime("do_some_stuff");
+ context.RealtimePush();
+ context.RealtimePop();
+ context.ExpectNotRealtime("do_some_stuff");
}
-TEST(TestRadsanContext, expectNotRealtimeDiesAfterRealtimePush) {
+TEST(TestRadsanContext, ExpectNotRealtimeDiesAfterRealtimePush) {
auto context = radsan::Context{};
- context.realtimePush();
- EXPECT_DEATH(context.expectNotRealtime("do_some_stuff"), "");
+ context.RealtimePush();
+ EXPECT_DEATH(context.ExpectNotRealtime("do_some_stuff"), "");
}
TEST(TestRadsanContext,
- expectNotRealtimeDiesAfterRealtimeAfterMorePushesThanPops) {
+ ExpectNotRealtimeDiesAfterRealtimeAfterMorePushesThanPops) {
auto context = radsan::Context{};
- context.realtimePush();
- context.realtimePush();
- context.realtimePush();
- context.realtimePop();
- context.realtimePop();
- EXPECT_DEATH(context.expectNotRealtime("do_some_stuff"), "");
+ context.RealtimePush();
+ context.RealtimePush();
+ context.RealtimePush();
+ context.RealtimePop();
+ context.RealtimePop();
+ EXPECT_DEATH(context.ExpectNotRealtime("do_some_stuff"), "");
}
-TEST(TestRadsanContext, expectNotRealtimeDoesNotDieAfterBypassPush) {
+TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieAfterBypassPush) {
auto context = radsan::Context{};
- context.realtimePush();
- context.bypassPush();
- context.expectNotRealtime("do_some_stuff");
+ context.RealtimePush();
+ context.BypassPush();
+ context.ExpectNotRealtime("do_some_stuff");
}
TEST(TestRadsanContext,
- expectNotRealtimeDoesNotDieIfBypassDepthIsGreaterThanZero) {
+ ExpectNotRealtimeDoesNotDieIfBypassDepthIsGreaterThanZero) {
auto context = radsan::Context{};
- context.realtimePush();
- context.bypassPush();
- context.bypassPush();
- context.bypassPush();
- context.bypassPop();
- context.bypassPop();
- context.expectNotRealtime("do_some_stuff");
- context.bypassPop();
- EXPECT_DEATH(context.expectNotRealtime("do_some_stuff"), "");
+ context.RealtimePush();
+ context.BypassPush();
+ context.BypassPush();
+ context.BypassPush();
+ context.BypassPop();
+ context.BypassPop();
+ context.ExpectNotRealtime("do_some_stuff");
+ context.BypassPop();
+ EXPECT_DEATH(context.ExpectNotRealtime("do_some_stuff"), "");
}
>From 7fc523693a81802e10959586ec5e77a716d56653 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Tue, 7 May 2024 15:54:08 -0700
Subject: [PATCH 04/33] Another round of style cleanups
---
compiler-rt/lib/radsan/radsan.cpp | 18 +++---
compiler-rt/lib/radsan/radsan.h | 12 ++--
compiler-rt/lib/radsan/radsan_context.cpp | 4 +-
compiler-rt/lib/radsan/radsan_context.h | 2 +-
.../lib/radsan/radsan_interceptors.cpp | 4 +-
compiler-rt/lib/radsan/radsan_interceptors.h | 2 +-
compiler-rt/lib/radsan/radsan_stack.cpp | 12 ++--
compiler-rt/lib/radsan/radsan_stack.h | 2 +-
compiler-rt/lib/radsan/tests/radsan_test.cpp | 4 +-
.../lib/radsan/tests/radsan_test_context.cpp | 62 +++++++++----------
.../radsan/tests/radsan_test_interceptors.cpp | 2 +-
.../lib/radsan/tests/radsan_test_utilities.h | 16 ++---
12 files changed, 70 insertions(+), 70 deletions(-)
diff --git a/compiler-rt/lib/radsan/radsan.cpp b/compiler-rt/lib/radsan/radsan.cpp
index b4e56479b944a..a859e8f4ce112 100644
--- a/compiler-rt/lib/radsan/radsan.cpp
+++ b/compiler-rt/lib/radsan/radsan.cpp
@@ -14,21 +14,21 @@
#include <unistd.h>
extern "C" {
-RADSAN_EXPORT void radsan_init() { radsan::initialiseInterceptors(); }
+SANITIZER_INTERFACE_ATTRIBUTE void radsan_init() { radsan::InitializeInterceptors(); }
-RADSAN_EXPORT void radsan_realtime_enter() {
- radsan::getContextForThisThread().RealtimePush();
+SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_enter() {
+ radsan::GetContextForThisThread().RealtimePush();
}
-RADSAN_EXPORT void radsan_realtime_exit() {
- radsan::getContextForThisThread().RealtimePop();
+SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_exit() {
+ radsan::GetContextForThisThread().RealtimePop();
}
-RADSAN_EXPORT void radsan_off() {
- radsan::getContextForThisThread().BypassPush();
+SANITIZER_INTERFACE_ATTRIBUTE void radsan_off() {
+ radsan::GetContextForThisThread().BypassPush();
}
-RADSAN_EXPORT void radsan_on() {
- radsan::getContextForThisThread().BypassPop();
+SANITIZER_INTERFACE_ATTRIBUTE void radsan_on() {
+ radsan::GetContextForThisThread().BypassPop();
}
}
diff --git a/compiler-rt/lib/radsan/radsan.h b/compiler-rt/lib/radsan/radsan.h
index 684cedd499ae7..ac644a80a0347 100644
--- a/compiler-rt/lib/radsan/radsan.h
+++ b/compiler-rt/lib/radsan/radsan.h
@@ -10,7 +10,7 @@
#pragma once
-#define RADSAN_EXPORT __attribute__((visibility("default")))
+#include "sanitizer_common/sanitizer_internal_defs.h"
extern "C" {
@@ -20,7 +20,7 @@ extern "C" {
@warning Do not call this method as a user.
*/
-RADSAN_EXPORT void radsan_init();
+SANITIZER_INTERFACE_ATTRIBUTE void radsan_init();
/** Enter real-time context.
@@ -30,7 +30,7 @@ RADSAN_EXPORT void radsan_init();
@warning Do not call this method as a user
*/
-RADSAN_EXPORT void radsan_realtime_enter();
+SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_enter();
/** Exit the real-time context.
@@ -39,7 +39,7 @@ RADSAN_EXPORT void radsan_realtime_enter();
@warning Do not call this method as a user
*/
-RADSAN_EXPORT void radsan_realtime_exit();
+SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_exit();
/** Disable all RADSan error reporting.
@@ -64,12 +64,12 @@ RADSAN_EXPORT void radsan_realtime_exit();
}
*/
-RADSAN_EXPORT void radsan_off();
+SANITIZER_INTERFACE_ATTRIBUTE void radsan_off();
/** Re-enable all RADSan error reporting.
The counterpart to `radsan_off`. See the description for `radsan_off` for
details about how to use this method.
*/
-RADSAN_EXPORT void radsan_on();
+SANITIZER_INTERFACE_ATTRIBUTE void radsan_on();
}
diff --git a/compiler-rt/lib/radsan/radsan_context.cpp b/compiler-rt/lib/radsan/radsan_context.cpp
index 03e0a01d7cd97..16fdf967ff4d8 100644
--- a/compiler-rt/lib/radsan/radsan_context.cpp
+++ b/compiler-rt/lib/radsan/radsan_context.cpp
@@ -60,10 +60,10 @@ void Context::PrintDiagnostics(const char *InterceptedFunctionName) {
"Real-time violation: intercepted call to real-time unsafe function "
"`%s` in real-time context! Stack trace:\n",
InterceptedFunctionName);
- radsan::printStackTrace();
+ radsan::PrintStackTrace();
}
-Context &getContextForThisThread() {
+Context &GetContextForThisThread() {
auto MakeTlsKey = []() {
CHECK_EQ(pthread_key_create(&detail::Key, detail::internalFree), 0);
};
diff --git a/compiler-rt/lib/radsan/radsan_context.h b/compiler-rt/lib/radsan/radsan_context.h
index 1b841446b7c1f..0cf8a61cbdde2 100644
--- a/compiler-rt/lib/radsan/radsan_context.h
+++ b/compiler-rt/lib/radsan/radsan_context.h
@@ -33,6 +33,6 @@ class Context {
int BypassDepth{0};
};
-Context &getContextForThisThread();
+Context &GetContextForThisThread();
} // namespace radsan
diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/radsan/radsan_interceptors.cpp
index 4318f4382257d..f7fd005aa004d 100644
--- a/compiler-rt/lib/radsan/radsan_interceptors.cpp
+++ b/compiler-rt/lib/radsan/radsan_interceptors.cpp
@@ -41,7 +41,7 @@ using namespace __sanitizer;
namespace radsan {
void ExpectNotRealtime(const char *InterceptedFunctionName) {
- getContextForThisThread().ExpectNotRealtime(InterceptedFunctionName);
+ GetContextForThisThread().ExpectNotRealtime(InterceptedFunctionName);
}
} // namespace radsan
@@ -349,7 +349,7 @@ INTERCEPTOR(int, shutdown, int socket, int how) {
*/
namespace radsan {
-void initialiseInterceptors() {
+void InitializeInterceptors() {
INTERCEPT_FUNCTION(calloc);
INTERCEPT_FUNCTION(free);
INTERCEPT_FUNCTION(malloc);
diff --git a/compiler-rt/lib/radsan/radsan_interceptors.h b/compiler-rt/lib/radsan/radsan_interceptors.h
index d10f4a01d8c80..30b37fb24a70f 100644
--- a/compiler-rt/lib/radsan/radsan_interceptors.h
+++ b/compiler-rt/lib/radsan/radsan_interceptors.h
@@ -11,5 +11,5 @@
#pragma once
namespace radsan {
-void initialiseInterceptors();
+void InitializeInterceptors();
}
diff --git a/compiler-rt/lib/radsan/radsan_stack.cpp b/compiler-rt/lib/radsan/radsan_stack.cpp
index b3cffa98b3ab9..e8cb4ae19ce88 100644
--- a/compiler-rt/lib/radsan/radsan_stack.cpp
+++ b/compiler-rt/lib/radsan/radsan_stack.cpp
@@ -28,7 +28,7 @@ void BufferedStackTrace::UnwindImpl(uptr pc, uptr bp, void *context,
} // namespace __sanitizer
namespace {
-void setGlobalStackTraceFormat() {
+void SetGlobalStackTraceFormat() {
SetCommonFlagsDefaults();
CommonFlags cf;
cf.CopyFrom(*common_flags());
@@ -39,14 +39,14 @@ void setGlobalStackTraceFormat() {
} // namespace
namespace radsan {
-void printStackTrace() {
+void PrintStackTrace() {
- auto stack = BufferedStackTrace{};
+ BufferedStackTrace Stack{};
GET_CURRENT_PC_BP;
- stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_fatal);
+ Stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_fatal);
- setGlobalStackTraceFormat();
- stack.Print();
+ SetGlobalStackTraceFormat();
+ Stack.Print();
}
} // namespace radsan
diff --git a/compiler-rt/lib/radsan/radsan_stack.h b/compiler-rt/lib/radsan/radsan_stack.h
index ee65a959431aa..29ef7d016f1ef 100644
--- a/compiler-rt/lib/radsan/radsan_stack.h
+++ b/compiler-rt/lib/radsan/radsan_stack.h
@@ -11,5 +11,5 @@
#pragma once
namespace radsan {
-void printStackTrace();
+void PrintStackTrace();
}
diff --git a/compiler-rt/lib/radsan/tests/radsan_test.cpp b/compiler-rt/lib/radsan/tests/radsan_test.cpp
index 9769e7a72779e..e049ee928c58c 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test.cpp
@@ -152,7 +152,7 @@ TEST(TestRadsan, CopyingALambdaWithLargeCaptureDiesWhenRealtime) {
TEST(TestRadsan, AccessingALargeAtomicVariableDiesWhenRealtime) {
std::atomic<float> SmallAtomic{0.0f};
ASSERT_TRUE(SmallAtomic.is_lock_free());
- realtimeInvoke([&SmallAtomic]() { float x = SmallAtomic.load(); });
+ RealtimeInvoke([&SmallAtomic]() { float x = SmallAtomic.load(); });
std::atomic<std::array<float, 2048>> LargeAtomic{};
ASSERT_FALSE(LargeAtomic.is_lock_free());
@@ -199,5 +199,5 @@ TEST(TestRadsan, DoesNotDieIfTurnedOff) {
Mutex.unlock();
radsan_on();
};
- realtimeInvoke(RealtimeUnsafeFunc);
+ RealtimeInvoke(RealtimeUnsafeFunc);
}
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp
index b654ac958be4b..91822df5a841d 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp
@@ -12,58 +12,58 @@
#include "radsan_context.h"
-TEST(TestRadsanContext, canCreateContext) { auto context = radsan::Context{}; }
+TEST(TestRadsanContext, CanCreateContext) { radsan::Context Context{}; }
TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieBeforeRealtimePush) {
- auto context = radsan::Context{};
- context.ExpectNotRealtime("do_some_stuff");
+ radsan::Context Context{};
+ Context.ExpectNotRealtime("do_some_stuff");
}
TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieAfterPushAndPop) {
- auto context = radsan::Context{};
- context.RealtimePush();
- context.RealtimePop();
- context.ExpectNotRealtime("do_some_stuff");
+ radsan::Context Context{};
+ Context.RealtimePush();
+ Context.RealtimePop();
+ Context.ExpectNotRealtime("do_some_stuff");
}
TEST(TestRadsanContext, ExpectNotRealtimeDiesAfterRealtimePush) {
- auto context = radsan::Context{};
+ radsan::Context Context{};
- context.RealtimePush();
- EXPECT_DEATH(context.ExpectNotRealtime("do_some_stuff"), "");
+ Context.RealtimePush();
+ EXPECT_DEATH(Context.ExpectNotRealtime("do_some_stuff"), "");
}
TEST(TestRadsanContext,
ExpectNotRealtimeDiesAfterRealtimeAfterMorePushesThanPops) {
- auto context = radsan::Context{};
+ radsan::Context Context{};
- context.RealtimePush();
- context.RealtimePush();
- context.RealtimePush();
- context.RealtimePop();
- context.RealtimePop();
- EXPECT_DEATH(context.ExpectNotRealtime("do_some_stuff"), "");
+ Context.RealtimePush();
+ Context.RealtimePush();
+ Context.RealtimePush();
+ Context.RealtimePop();
+ Context.RealtimePop();
+ EXPECT_DEATH(Context.ExpectNotRealtime("do_some_stuff"), "");
}
TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieAfterBypassPush) {
- auto context = radsan::Context{};
+ radsan::Context Context{};
- context.RealtimePush();
- context.BypassPush();
- context.ExpectNotRealtime("do_some_stuff");
+ Context.RealtimePush();
+ Context.BypassPush();
+ Context.ExpectNotRealtime("do_some_stuff");
}
TEST(TestRadsanContext,
ExpectNotRealtimeDoesNotDieIfBypassDepthIsGreaterThanZero) {
- auto context = radsan::Context{};
+ radsan::Context Context{};
- context.RealtimePush();
- context.BypassPush();
- context.BypassPush();
- context.BypassPush();
- context.BypassPop();
- context.BypassPop();
- context.ExpectNotRealtime("do_some_stuff");
- context.BypassPop();
- EXPECT_DEATH(context.ExpectNotRealtime("do_some_stuff"), "");
+ Context.RealtimePush();
+ Context.BypassPush();
+ Context.BypassPush();
+ Context.BypassPush();
+ Context.BypassPop();
+ Context.BypassPop();
+ Context.ExpectNotRealtime("do_some_stuff");
+ Context.BypassPop();
+ EXPECT_DEATH(Context.ExpectNotRealtime("do_some_stuff"), "");
}
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
index 95735d2059de3..a94fb5c7012df 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
@@ -109,7 +109,7 @@ TEST(TestRadsanInterceptors, freeDiesWhenRealtime) {
}
TEST(TestRadsanInterceptors, freeSurvivesWhenRealtimeIfArgumentIsNull) {
- realtimeInvoke([]() { free(NULL); });
+ RealtimeInvoke([]() { free(NULL); });
ExpectNonRealtimeSurvival([]() { free(NULL); });
}
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h b/compiler-rt/lib/radsan/tests/radsan_test_utilities.h
index dac88e4dd1c46..4a2510d5f87d4 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h
+++ b/compiler-rt/lib/radsan/tests/radsan_test_utilities.h
@@ -17,20 +17,20 @@
namespace radsan_testing {
template <typename Function>
-void realtimeInvoke(Function &&func)
+void RealtimeInvoke(Function &&Func)
{
radsan_realtime_enter();
- std::forward<Function>(func)();
+ std::forward<Function>(Func)();
radsan_realtime_exit();
}
template <typename Function>
-void ExpectRealtimeDeath(Function &&func,
+void ExpectRealtimeDeath(Function &&Func,
const char *intercepted_method_name = nullptr) {
using namespace testing;
- auto expected_error_substr = [&]() -> std::string {
+ auto ExpectedErrorSubstring = [&]() -> std::string {
return intercepted_method_name != nullptr
? "Real-time violation: intercepted call to real-time unsafe "
"function `" +
@@ -38,12 +38,12 @@ void ExpectRealtimeDeath(Function &&func,
: "";
};
- EXPECT_EXIT(realtimeInvoke(std::forward<Function>(func)),
- ExitedWithCode(EXIT_FAILURE), expected_error_substr());
+ EXPECT_EXIT(RealtimeInvoke(std::forward<Function>(Func)),
+ ExitedWithCode(EXIT_FAILURE), ExpectedErrorSubstring());
}
-template <typename Function> void ExpectNonRealtimeSurvival(Function &&func) {
- std::forward<Function>(func)();
+template <typename Function> void ExpectNonRealtimeSurvival(Function &&Func) {
+ std::forward<Function>(Func)();
}
} // namespace radsan_testing
>From 3232a4b89f830b8f36b7dc7275cc582083179830 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Tue, 7 May 2024 16:10:47 -0700
Subject: [PATCH 05/33] more auto removal, more case fixing
---
compiler-rt/lib/radsan/tests/radsan_test.cpp | 8 +-
.../radsan/tests/radsan_test_interceptors.cpp | 484 +++++++++---------
2 files changed, 246 insertions(+), 246 deletions(-)
diff --git a/compiler-rt/lib/radsan/tests/radsan_test.cpp b/compiler-rt/lib/radsan/tests/radsan_test.cpp
index e049ee928c58c..521545ca8a9e2 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test.cpp
@@ -61,14 +61,14 @@ TEST(TestRadsan, SleepingAThreadDiesWhenRealtime) {
}
TEST(TestRadsan, IfstreamCreationDiesWhenRealtime) {
- auto Func = []() { auto ifs = std::ifstream("./file.txt"); };
+ auto Func = []() { std::ifstream ifs{"./file.txt"}; };
ExpectRealtimeDeath(Func);
ExpectNonRealtimeSurvival(Func);
std::remove("./file.txt");
}
TEST(TestRadsan, OfstreamCreationDiesWhenRealtime) {
- auto Func = []() { auto ofs = std::ofstream("./file.txt"); };
+ auto Func = []() { std::ofstream ofs{"./file.txt"}; };
ExpectRealtimeDeath(Func);
ExpectNonRealtimeSurvival(Func);
std::remove("./file.txt");
@@ -125,8 +125,8 @@ TEST(TestRadsan, SharedUnlockingASharedMutexDiesWhenRealtime) {
TEST(TestRadsan, LaunchingAThreadDiesWhenRealtime) {
auto Func = [&]() {
- auto t = std::thread([]() {});
- t.join();
+ std::thread Thread{[]() {}};
+ Thread.join();
};
ExpectRealtimeDeath(Func);
ExpectNonRealtimeSurvival(Func);
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
index a94fb5c7012df..20ed7c7542d03 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
@@ -38,7 +38,7 @@ using namespace radsan_testing;
using namespace std::chrono_literals;
namespace {
-void *fake_thread_entry_point(void *) { return nullptr; }
+void *FakeThreadEntryPoint(void *) { return nullptr; }
/*
The creat function doesn't seem to work on an ubuntu Docker image when the
@@ -47,7 +47,7 @@ void *fake_thread_entry_point(void *) { return nullptr; }
shared volume (/tmp). This is volatile and will be cleaned up as soon as the
container is stopped.
*/
-constexpr const char *temporary_file_path() {
+constexpr const char *TemporaryFilePath() {
#if SANITIZER_LINUX
return "/tmp/radsan_temporary_test_file.txt";
#elif SANITIZER_APPLE
@@ -60,46 +60,46 @@ constexpr const char *temporary_file_path() {
Allocation and deallocation
*/
-TEST(TestRadsanInterceptors, mallocDiesWhenRealtime) {
- auto func = []() { EXPECT_NE(nullptr, malloc(1)); };
- ExpectRealtimeDeath(func, "malloc");
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, MallocDiesWhenRealtime) {
+ auto Func = []() { EXPECT_NE(nullptr, malloc(1)); };
+ ExpectRealtimeDeath(Func, "malloc");
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsanInterceptors, reallocDiesWhenRealtime) {
- auto *ptr_1 = malloc(1);
- auto func = [ptr_1]() { EXPECT_NE(nullptr, realloc(ptr_1, 8)); };
- ExpectRealtimeDeath(func, "realloc");
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, ReallocDiesWhenRealtime) {
+ void *ptr_1 = malloc(1);
+ auto Func = [ptr_1]() { EXPECT_NE(nullptr, realloc(ptr_1, 8)); };
+ ExpectRealtimeDeath(Func, "realloc");
+ ExpectNonRealtimeSurvival(Func);
}
#if SANITIZER_APPLE
-TEST(TestRadsanInterceptors, reallocfDiesWhenRealtime) {
- auto *ptr_1 = malloc(1);
- auto func = [ptr_1]() { EXPECT_NE(nullptr, reallocf(ptr_1, 8)); };
- ExpectRealtimeDeath(func, "reallocf");
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, ReallocfDiesWhenRealtime) {
+ void *ptr_1 = malloc(1);
+ auto Func = [ptr_1]() { EXPECT_NE(nullptr, reallocf(ptr_1, 8)); };
+ ExpectRealtimeDeath(Func, "reallocf");
+ ExpectNonRealtimeSurvival(Func);
}
#endif
-TEST(TestRadsanInterceptors, vallocDiesWhenRealtime) {
- auto func = []() { EXPECT_NE(nullptr, valloc(4)); };
- ExpectRealtimeDeath(func, "valloc");
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, VallocDiesWhenRealtime) {
+ auto Func = []() { EXPECT_NE(nullptr, valloc(4)); };
+ ExpectRealtimeDeath(Func, "valloc");
+ ExpectNonRealtimeSurvival(Func);
}
#if SANITIZER_INTERCEPT_ALIGNED_ALLOC
-TEST(TestRadsanInterceptors, alignedAllocDiesWhenRealtime) {
- auto func = []() { EXPECT_NE(nullptr, aligned_alloc(16, 32)); };
- ExpectRealtimeDeath(func, "aligned_alloc");
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, AlignedAllocDiesWhenRealtime) {
+ auto Func = []() { EXPECT_NE(nullptr, aligned_alloc(16, 32)); };
+ ExpectRealtimeDeath(Func, "aligned_alloc");
+ ExpectNonRealtimeSurvival(Func);
}
#endif
// free_sized and free_aligned_sized (both C23) are not yet supported
-TEST(TestRadsanInterceptors, freeDiesWhenRealtime) {
- auto *ptr_1 = malloc(1);
- auto *ptr_2 = malloc(1);
+TEST(TestRadsanInterceptors, FreeDiesWhenRealtime) {
+ void *ptr_1 = malloc(1);
+ void *ptr_2 = malloc(1);
ExpectRealtimeDeath([ptr_1]() { free(ptr_1); }, "free");
ExpectNonRealtimeSurvival([ptr_2]() { free(ptr_2); });
@@ -108,33 +108,33 @@ TEST(TestRadsanInterceptors, freeDiesWhenRealtime) {
ASSERT_NE(nullptr, ptr_2);
}
-TEST(TestRadsanInterceptors, freeSurvivesWhenRealtimeIfArgumentIsNull) {
+TEST(TestRadsanInterceptors, FreeSurvivesWhenRealtimeIfArgumentIsNull) {
RealtimeInvoke([]() { free(NULL); });
ExpectNonRealtimeSurvival([]() { free(NULL); });
}
-TEST(TestRadsanInterceptors, posixMemalignDiesWhenRealtime) {
- auto func = []() {
- void *mem;
- posix_memalign(&mem, 4, 4);
+TEST(TestRadsanInterceptors, PosixMemalignDiesWhenRealtime) {
+ auto Func = []() {
+ void *Mem;
+ posix_memalign(&Mem, 4, 4);
};
- ExpectRealtimeDeath(func, "posix_memalign");
- ExpectNonRealtimeSurvival(func);
+ ExpectRealtimeDeath(Func, "posix_memalign");
+ ExpectNonRealtimeSurvival(Func);
}
#if SANITIZER_INTERCEPT_MEMALIGN
-TEST(TestRadsanInterceptors, memalignDiesWhenRealtime) {
- auto func = []() { EXPECT_NE(memalign(2, 2048), nullptr); };
- ExpectRealtimeDeath(func, "memalign");
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, MemalignDiesWhenRealtime) {
+ auto Func = []() { EXPECT_NE(memalign(2, 2048), nullptr); };
+ ExpectRealtimeDeath(Func, "memalign");
+ ExpectNonRealtimeSurvival(Func);
}
#endif
#if SANITIZER_INTERCEPT_PVALLOC
-TEST(TestRadsanInterceptors, pvallocDiesWhenRealtime) {
- auto func = []() { EXPECT_NE(pvalloc(2048), nullptr); };
- ExpectRealtimeDeath(func, "pvalloc");
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, PvallocDiesWhenRealtime) {
+ auto Func = []() { EXPECT_NE(pvalloc(2048), nullptr); };
+ ExpectRealtimeDeath(Func, "pvalloc");
+ ExpectNonRealtimeSurvival(Func);
}
#endif
@@ -142,166 +142,166 @@ TEST(TestRadsanInterceptors, pvallocDiesWhenRealtime) {
Sleeping
*/
-TEST(TestRadsanInterceptors, sleepDiesWhenRealtime) {
- auto func = []() { sleep(0u); };
- ExpectRealtimeDeath(func, "sleep");
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, SleepDiesWhenRealtime) {
+ auto Func = []() { sleep(0u); };
+ ExpectRealtimeDeath(Func, "sleep");
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsanInterceptors, usleepDiesWhenRealtime) {
- auto func = []() { usleep(1u); };
- ExpectRealtimeDeath(func, "usleep");
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, UsleepDiesWhenRealtime) {
+ auto Func = []() { usleep(1u); };
+ ExpectRealtimeDeath(Func, "usleep");
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsanInterceptors, nanosleepDiesWhenRealtime) {
- auto func = []() {
- auto t = timespec{};
- nanosleep(&t, &t);
+TEST(TestRadsanInterceptors, NanosleepDiesWhenRealtime) {
+ auto Func = []() {
+ timespec T{};
+ nanosleep(&T, &T);
};
- ExpectRealtimeDeath(func, "nanosleep");
- ExpectNonRealtimeSurvival(func);
+ ExpectRealtimeDeath(Func, "nanosleep");
+ ExpectNonRealtimeSurvival(Func);
}
/*
Filesystem
*/
-TEST(TestRadsanInterceptors, openDiesWhenRealtime) {
- auto func = []() { open(temporary_file_path(), O_RDONLY); };
- ExpectRealtimeDeath(func, "open");
- ExpectNonRealtimeSurvival(func);
- std::remove(temporary_file_path());
+TEST(TestRadsanInterceptors, OpenDiesWhenRealtime) {
+ auto Func = []() { open(TemporaryFilePath(), O_RDONLY); };
+ ExpectRealtimeDeath(Func, "open");
+ ExpectNonRealtimeSurvival(Func);
+ std::remove(TemporaryFilePath());
}
-TEST(TestRadsanInterceptors, openatDiesWhenRealtime) {
- auto func = []() { openat(0, temporary_file_path(), O_RDONLY); };
- ExpectRealtimeDeath(func, "openat");
- ExpectNonRealtimeSurvival(func);
- std::remove(temporary_file_path());
+TEST(TestRadsanInterceptors, OpenatDiesWhenRealtime) {
+ auto Func = []() { openat(0, TemporaryFilePath(), O_RDONLY); };
+ ExpectRealtimeDeath(Func, "openat");
+ ExpectNonRealtimeSurvival(Func);
+ std::remove(TemporaryFilePath());
}
-TEST(TestRadsanInterceptors, creatDiesWhenRealtime) {
- auto func = []() { creat(temporary_file_path(), S_IWOTH | S_IROTH); };
- ExpectRealtimeDeath(func, "creat");
- ExpectNonRealtimeSurvival(func);
- std::remove(temporary_file_path());
+TEST(TestRadsanInterceptors, CreatDiesWhenRealtime) {
+ auto Func = []() { creat(TemporaryFilePath(), S_IWOTH | S_IROTH); };
+ ExpectRealtimeDeath(Func, "creat");
+ ExpectNonRealtimeSurvival(Func);
+ std::remove(TemporaryFilePath());
}
-TEST(TestRadsanInterceptors, fcntlDiesWhenRealtime) {
- auto func = []() { fcntl(0, F_GETFL); };
- ExpectRealtimeDeath(func, "fcntl");
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, FcntlDiesWhenRealtime) {
+ auto Func = []() { fcntl(0, F_GETFL); };
+ ExpectRealtimeDeath(Func, "fcntl");
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsanInterceptors, closeDiesWhenRealtime) {
- auto func = []() { close(0); };
- ExpectRealtimeDeath(func, "close");
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, CloseDiesWhenRealtime) {
+ auto Func = []() { close(0); };
+ ExpectRealtimeDeath(Func, "close");
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsanInterceptors, fopenDiesWhenRealtime) {
- auto func = []() {
- auto fd = fopen(temporary_file_path(), "w");
- EXPECT_THAT(fd, Ne(nullptr));
+TEST(TestRadsanInterceptors, FopenDiesWhenRealtime) {
+ auto Func = []() {
+ FILE* Fd = fopen(TemporaryFilePath(), "w");
+ EXPECT_THAT(Fd, Ne(nullptr));
};
- ExpectRealtimeDeath(func, "fopen");
- ExpectNonRealtimeSurvival(func);
- std::remove(temporary_file_path());
+ ExpectRealtimeDeath(Func, "fopen");
+ ExpectNonRealtimeSurvival(Func);
+ std::remove(TemporaryFilePath());
}
-TEST(TestRadsanInterceptors, freadDiesWhenRealtime) {
- auto fd = fopen(temporary_file_path(), "w");
- auto func = [fd]() {
+TEST(TestRadsanInterceptors, FreadDiesWhenRealtime) {
+ FILE* Fd = fopen(TemporaryFilePath(), "w");
+ auto Func = [Fd]() {
char c{};
- fread(&c, 1, 1, fd);
+ fread(&c, 1, 1, Fd);
};
- ExpectRealtimeDeath(func, "fread");
- ExpectNonRealtimeSurvival(func);
- if (fd != nullptr)
- fclose(fd);
- std::remove(temporary_file_path());
+ ExpectRealtimeDeath(Func, "fread");
+ ExpectNonRealtimeSurvival(Func);
+ if (Fd != nullptr)
+ fclose(Fd);
+ std::remove(TemporaryFilePath());
}
-TEST(TestRadsanInterceptors, fwriteDiesWhenRealtime) {
- auto fd = fopen(temporary_file_path(), "w");
- ASSERT_NE(nullptr, fd);
- auto message = "Hello, world!";
- auto func = [&]() { fwrite(&message, 1, 4, fd); };
- ExpectRealtimeDeath(func, "fwrite");
- ExpectNonRealtimeSurvival(func);
- std::remove(temporary_file_path());
+TEST(TestRadsanInterceptors, FwriteDiesWhenRealtime) {
+ FILE* Fd = fopen(TemporaryFilePath(), "w");
+ ASSERT_NE(nullptr, Fd);
+ const char* Message = "Hello, world!";
+ auto Func = [&]() { fwrite(&Message, 1, 4, Fd); };
+ ExpectRealtimeDeath(Func, "fwrite");
+ ExpectNonRealtimeSurvival(Func);
+ std::remove(TemporaryFilePath());
}
-TEST(TestRadsanInterceptors, fcloseDiesWhenRealtime) {
- auto fd = fopen(temporary_file_path(), "w");
- EXPECT_THAT(fd, Ne(nullptr));
- auto func = [fd]() { fclose(fd); };
- ExpectRealtimeDeath(func, "fclose");
- ExpectNonRealtimeSurvival(func);
- std::remove(temporary_file_path());
+TEST(TestRadsanInterceptors, FcloseDiesWhenRealtime) {
+ FILE* Fd = fopen(TemporaryFilePath(), "w");
+ EXPECT_THAT(Fd, Ne(nullptr));
+ auto Func = [Fd]() { fclose(Fd); };
+ ExpectRealtimeDeath(Func, "fclose");
+ ExpectNonRealtimeSurvival(Func);
+ std::remove(TemporaryFilePath());
}
-TEST(TestRadsanInterceptors, putsDiesWhenRealtime) {
- auto func = []() { puts("Hello, world!\n"); };
- ExpectRealtimeDeath(func);
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, PutsDiesWhenRealtime) {
+ auto Func = []() { puts("Hello, world!\n"); };
+ ExpectRealtimeDeath(Func);
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsanInterceptors, fputsDiesWhenRealtime) {
- auto fd = fopen(temporary_file_path(), "w");
- ASSERT_THAT(fd, Ne(nullptr)) << errno;
- auto func = [fd]() { fputs("Hello, world!\n", fd); };
- ExpectRealtimeDeath(func);
- ExpectNonRealtimeSurvival(func);
- if (fd != nullptr)
- fclose(fd);
- std::remove(temporary_file_path());
+TEST(TestRadsanInterceptors, FputsDiesWhenRealtime) {
+ FILE* Fd = fopen(TemporaryFilePath(), "w");
+ ASSERT_THAT(Fd, Ne(nullptr)) << errno;
+ auto Func = [Fd]() { fputs("Hello, world!\n", Fd); };
+ ExpectRealtimeDeath(Func);
+ ExpectNonRealtimeSurvival(Func);
+ if (Fd != nullptr)
+ fclose(Fd);
+ std::remove(TemporaryFilePath());
}
/*
Concurrency
*/
-TEST(TestRadsanInterceptors, pthreadCreateDiesWhenRealtime) {
- auto func = []() {
- auto thread = pthread_t{};
- auto const attr = pthread_attr_t{};
- struct thread_info *tinfo;
- pthread_create(&thread, &attr, &fake_thread_entry_point, tinfo);
+TEST(TestRadsanInterceptors, PthreadCreateDiesWhenRealtime) {
+ auto Func = []() {
+ pthread_t Thread{};
+ const pthread_attr_t Attr{};
+ struct thread_info *ThreadInfo;
+ pthread_create(&Thread, &Attr, &FakeThreadEntryPoint, ThreadInfo);
};
- ExpectRealtimeDeath(func, "pthread_create");
- ExpectNonRealtimeSurvival(func);
+ ExpectRealtimeDeath(Func, "pthread_create");
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsanInterceptors, pthreadMutexLockDiesWhenRealtime) {
- auto func = []() {
- auto mutex = pthread_mutex_t{};
- pthread_mutex_lock(&mutex);
+TEST(TestRadsanInterceptors, PthreadMutexLockDiesWhenRealtime) {
+ auto Func = []() {
+ pthread_mutex_t Mutex{};
+ pthread_mutex_lock(&Mutex);
};
- ExpectRealtimeDeath(func, "pthread_mutex_lock");
- ExpectNonRealtimeSurvival(func);
+ ExpectRealtimeDeath(Func, "pthread_mutex_lock");
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsanInterceptors, pthreadMutexUnlockDiesWhenRealtime) {
- auto func = []() {
- auto mutex = pthread_mutex_t{};
- pthread_mutex_unlock(&mutex);
+TEST(TestRadsanInterceptors, PthreadMutexUnlockDiesWhenRealtime) {
+ auto Func = []() {
+ pthread_mutex_t Mutex{};
+ pthread_mutex_unlock(&Mutex);
};
- ExpectRealtimeDeath(func, "pthread_mutex_unlock");
- ExpectNonRealtimeSurvival(func);
+ ExpectRealtimeDeath(Func, "pthread_mutex_unlock");
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsanInterceptors, pthreadMutexJoinDiesWhenRealtime) {
- auto func = []() {
- auto thread = pthread_t{};
- pthread_join(thread, nullptr);
+TEST(TestRadsanInterceptors, PthreadMutexJoinDiesWhenRealtime) {
+ auto Func = []() {
+ pthread_t Thread{};
+ pthread_join(Thread, nullptr);
};
- ExpectRealtimeDeath(func, "pthread_join");
- ExpectNonRealtimeSurvival(func);
+ ExpectRealtimeDeath(Func, "pthread_join");
+ ExpectNonRealtimeSurvival(Func);
}
#if SANITIZER_APPLE
@@ -309,146 +309,146 @@ TEST(TestRadsanInterceptors, pthreadMutexJoinDiesWhenRealtime) {
#pragma clang diagnostic push
// OSSpinLockLock is deprecated, but still in use in libc++
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-TEST(TestRadsanInterceptors, osSpinLockLockDiesWhenRealtime) {
- auto func = []() {
- auto spin_lock = OSSpinLock{};
- OSSpinLockLock(&spin_lock);
+TEST(TestRadsanInterceptors, OsSpinLockLockDiesWhenRealtime) {
+ auto Func = []() {
+ OSSpinLock SpinLock{};
+ OSSpinLockLock(&SpinLock);
};
- ExpectRealtimeDeath(func, "OSSpinLockLock");
- ExpectNonRealtimeSurvival(func);
+ ExpectRealtimeDeath(Func, "OSSpinLockLock");
+ ExpectNonRealtimeSurvival(Func);
}
#pragma clang diagnostic pop
-TEST(TestRadsanInterceptors, osUnfairLockLockDiesWhenRealtime) {
- auto func = []() {
- auto unfair_lock = os_unfair_lock_s{};
- os_unfair_lock_lock(&unfair_lock);
+TEST(TestRadsanInterceptors, OsUnfairLockLockDiesWhenRealtime) {
+ auto Func = []() {
+ os_unfair_lock_s UnfairLock{};
+ os_unfair_lock_lock(&UnfairLock);
};
- ExpectRealtimeDeath(func, "os_unfair_lock_lock");
- ExpectNonRealtimeSurvival(func);
+ ExpectRealtimeDeath(Func, "os_unfair_lock_lock");
+ ExpectNonRealtimeSurvival(Func);
}
#endif
#if SANITIZER_LINUX
-TEST(TestRadsanInterceptors, spinLockLockDiesWhenRealtime) {
- auto spinlock = pthread_spinlock_t{};
- pthread_spin_init(&spinlock, PTHREAD_PROCESS_SHARED);
- auto func = [&]() { pthread_spin_lock(&spinlock); };
- ExpectRealtimeDeath(func, "pthread_spin_lock");
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, SpinLockLockDiesWhenRealtime) {
+ pthread_spinlock_t SpinLock;
+ pthread_spin_init(&SpinLock, PTHREAD_PROCESS_SHARED);
+ auto Func = [&]() { pthread_spin_lock(&SpinLock); };
+ ExpectRealtimeDeath(Func, "pthread_spin_lock");
+ ExpectNonRealtimeSurvival(Func);
}
#endif
-TEST(TestRadsanInterceptors, pthreadCondSignalDiesWhenRealtime) {
- auto func = []() {
- auto cond = pthread_cond_t{};
- pthread_cond_signal(&cond);
+TEST(TestRadsanInterceptors, PthreadCondSignalDiesWhenRealtime) {
+ auto Func = []() {
+ pthread_cond_t Cond{};
+ pthread_cond_signal(&Cond);
};
- ExpectRealtimeDeath(func, "pthread_cond_signal");
- ExpectNonRealtimeSurvival(func);
+ ExpectRealtimeDeath(Func, "pthread_cond_signal");
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsanInterceptors, pthreadCondBroadcastDiesWhenRealtime) {
- auto func = []() {
- auto cond = pthread_cond_t{};
- pthread_cond_broadcast(&cond);
+TEST(TestRadsanInterceptors, PthreadCondBroadcastDiesWhenRealtime) {
+ auto Func = []() {
+ pthread_cond_t Cond;
+ pthread_cond_broadcast(&Cond);
};
- ExpectRealtimeDeath(func, "pthread_cond_broadcast");
- ExpectNonRealtimeSurvival(func);
+ ExpectRealtimeDeath(Func, "pthread_cond_broadcast");
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsanInterceptors, pthreadCondWaitDiesWhenRealtime) {
- auto cond = pthread_cond_t{};
- auto mutex = pthread_mutex_t{};
- ASSERT_EQ(0, pthread_cond_init(&cond, nullptr));
- ASSERT_EQ(0, pthread_mutex_init(&mutex, nullptr));
- auto func = [&]() { pthread_cond_wait(&cond, &mutex); };
- ExpectRealtimeDeath(func, "pthread_cond_wait");
+TEST(TestRadsanInterceptors, PthreadCondWaitDiesWhenRealtime) {
+ pthread_cond_t Cond;
+ pthread_mutex_t Mutex;
+ ASSERT_EQ(0, pthread_cond_init(&Cond, nullptr));
+ ASSERT_EQ(0, pthread_mutex_init(&Mutex, nullptr));
+ auto Func = [&]() { pthread_cond_wait(&Cond, &Mutex); };
+ ExpectRealtimeDeath(Func, "pthread_cond_wait");
// It's very difficult to test the success case here without doing some
// sleeping, which is at the mercy of the scheduler. What's really important
// here is the interception - so we're only testing that for now.
}
-TEST(TestRadsanInterceptors, pthreadRwlockRdlockDiesWhenRealtime) {
- auto func = []() {
- auto rwlock = pthread_rwlock_t{};
- pthread_rwlock_rdlock(&rwlock);
+TEST(TestRadsanInterceptors, PthreadRwlockRdlockDiesWhenRealtime) {
+ auto Func = []() {
+ pthread_rwlock_t RwLock;
+ pthread_rwlock_rdlock(&RwLock);
};
- ExpectRealtimeDeath(func, "pthread_rwlock_rdlock");
- ExpectNonRealtimeSurvival(func);
+ ExpectRealtimeDeath(Func, "pthread_rwlock_rdlock");
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsanInterceptors, pthreadRwlockUnlockDiesWhenRealtime) {
- auto func = []() {
- auto rwlock = pthread_rwlock_t{};
- pthread_rwlock_unlock(&rwlock);
+TEST(TestRadsanInterceptors, PthreadRwlockUnlockDiesWhenRealtime) {
+ auto Func = []() {
+ pthread_rwlock_t RwLock;
+ pthread_rwlock_unlock(&RwLock);
};
- ExpectRealtimeDeath(func, "pthread_rwlock_unlock");
- ExpectNonRealtimeSurvival(func);
+ ExpectRealtimeDeath(Func, "pthread_rwlock_unlock");
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsanInterceptors, pthreadRwlockWrlockDiesWhenRealtime) {
- auto func = []() {
- auto rwlock = pthread_rwlock_t{};
- pthread_rwlock_wrlock(&rwlock);
+TEST(TestRadsanInterceptors, PthreadRwlockWrlockDiesWhenRealtime) {
+ auto Func = []() {
+ pthread_rwlock_t RwLock;
+ pthread_rwlock_wrlock(&RwLock);
};
- ExpectRealtimeDeath(func, "pthread_rwlock_wrlock");
- ExpectNonRealtimeSurvival(func);
+ ExpectRealtimeDeath(Func, "pthread_rwlock_wrlock");
+ ExpectNonRealtimeSurvival(Func);
}
/*
Sockets
*/
-TEST(TestRadsanInterceptors, openingASocketDiesWhenRealtime) {
- auto func = []() { socket(PF_INET, SOCK_STREAM, 0); };
- ExpectRealtimeDeath(func, "socket");
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, OpeningASocketDiesWhenRealtime) {
+ auto Func = []() { socket(PF_INET, SOCK_STREAM, 0); };
+ ExpectRealtimeDeath(Func, "socket");
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsanInterceptors, sendToASocketDiesWhenRealtime) {
- auto func = []() { send(0, nullptr, 0, 0); };
- ExpectRealtimeDeath(func, "send");
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, SendToASocketDiesWhenRealtime) {
+ auto Func = []() { send(0, nullptr, 0, 0); };
+ ExpectRealtimeDeath(Func, "send");
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsanInterceptors, sendmsgToASocketDiesWhenRealtime) {
- auto const msg = msghdr{};
- auto func = [&]() { sendmsg(0, &msg, 0); };
- ExpectRealtimeDeath(func, "sendmsg");
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, SendmsgToASocketDiesWhenRealtime) {
+ msghdr Msg{};
+ auto Func = [&]() { sendmsg(0, &Msg, 0); };
+ ExpectRealtimeDeath(Func, "sendmsg");
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsanInterceptors, sendtoToASocketDiesWhenRealtime) {
- auto const addr = sockaddr{};
- auto const len = socklen_t{};
- auto func = [&]() { sendto(0, nullptr, 0, 0, &addr, len); };
- ExpectRealtimeDeath(func, "sendto");
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, SendtoToASocketDiesWhenRealtime) {
+ sockaddr Addr{};
+ socklen_t Len{};
+ auto Func = [&]() { sendto(0, nullptr, 0, 0, &Addr, Len); };
+ ExpectRealtimeDeath(Func, "sendto");
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsanInterceptors, recvFromASocketDiesWhenRealtime) {
- auto func = []() { recv(0, nullptr, 0, 0); };
- ExpectRealtimeDeath(func, "recv");
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, RecvFromASocketDiesWhenRealtime) {
+ auto Func = []() { recv(0, nullptr, 0, 0); };
+ ExpectRealtimeDeath(Func, "recv");
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsanInterceptors, recvfromOnASocketDiesWhenRealtime) {
- auto addr = sockaddr{};
- auto len = socklen_t{};
- auto func = [&]() { recvfrom(0, nullptr, 0, 0, &addr, &len); };
- ExpectRealtimeDeath(func, "recvfrom");
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, RecvfromOnASocketDiesWhenRealtime) {
+ sockaddr Addr{};
+ socklen_t Len{};
+ auto Func = [&]() { recvfrom(0, nullptr, 0, 0, &Addr, &Len); };
+ ExpectRealtimeDeath(Func, "recvfrom");
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsanInterceptors, recvmsgOnASocketDiesWhenRealtime) {
- auto msg = msghdr{};
- auto func = [&]() { recvmsg(0, &msg, 0); };
- ExpectRealtimeDeath(func, "recvmsg");
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, RecvmsgOnASocketDiesWhenRealtime) {
+ msghdr Msg{};
+ auto Func = [&]() { recvmsg(0, &Msg, 0); };
+ ExpectRealtimeDeath(Func, "recvmsg");
+ ExpectNonRealtimeSurvival(Func);
}
-TEST(TestRadsanInterceptors, shutdownOnASocketDiesWhenRealtime) {
- auto func = [&]() { shutdown(0, 0); };
- ExpectRealtimeDeath(func, "shutdown");
- ExpectNonRealtimeSurvival(func);
+TEST(TestRadsanInterceptors, ShutdownOnASocketDiesWhenRealtime) {
+ auto Func = [&]() { shutdown(0, 0); };
+ ExpectRealtimeDeath(Func, "shutdown");
+ ExpectNonRealtimeSurvival(Func);
}
>From 2dd39a3e5951be1360af960b0da5b23272d44445 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Tue, 7 May 2024 16:15:32 -0700
Subject: [PATCH 06/33] Missing end of namespace comment
---
compiler-rt/lib/radsan/radsan.cpp | 8 ++++++--
compiler-rt/lib/radsan/radsan.h | 3 ++-
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/compiler-rt/lib/radsan/radsan.cpp b/compiler-rt/lib/radsan/radsan.cpp
index a859e8f4ce112..dbe787ea6f6e4 100644
--- a/compiler-rt/lib/radsan/radsan.cpp
+++ b/compiler-rt/lib/radsan/radsan.cpp
@@ -14,7 +14,10 @@
#include <unistd.h>
extern "C" {
-SANITIZER_INTERFACE_ATTRIBUTE void radsan_init() { radsan::InitializeInterceptors(); }
+
+SANITIZER_INTERFACE_ATTRIBUTE void radsan_init() {
+ radsan::InitializeInterceptors();
+}
SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_enter() {
radsan::GetContextForThisThread().RealtimePush();
@@ -31,4 +34,5 @@ SANITIZER_INTERFACE_ATTRIBUTE void radsan_off() {
SANITIZER_INTERFACE_ATTRIBUTE void radsan_on() {
radsan::GetContextForThisThread().BypassPop();
}
-}
+
+} // extern "C"
diff --git a/compiler-rt/lib/radsan/radsan.h b/compiler-rt/lib/radsan/radsan.h
index ac644a80a0347..61205e93e29ed 100644
--- a/compiler-rt/lib/radsan/radsan.h
+++ b/compiler-rt/lib/radsan/radsan.h
@@ -72,4 +72,5 @@ SANITIZER_INTERFACE_ATTRIBUTE void radsan_off();
details about how to use this method.
*/
SANITIZER_INTERFACE_ATTRIBUTE void radsan_on();
-}
+
+} // extern "C"
>From 3ae58fadd058710b124f95970ce990318e95a7d3 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Wed, 8 May 2024 12:16:29 -0700
Subject: [PATCH 07/33] Fix one naming issue
---
compiler-rt/lib/radsan/radsan_context.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/compiler-rt/lib/radsan/radsan_context.h b/compiler-rt/lib/radsan/radsan_context.h
index 0cf8a61cbdde2..6f8f937ca0739 100644
--- a/compiler-rt/lib/radsan/radsan_context.h
+++ b/compiler-rt/lib/radsan/radsan_context.h
@@ -22,7 +22,7 @@ class Context {
void BypassPush();
void BypassPop();
- void ExpectNotRealtime(const char *interpreted_function_name);
+ void ExpectNotRealtime(const char *InterceptedFunctionName);
private:
bool InRealtimeContext() const;
>From 9d1624d12b527758f94008dba39fb642eb1a3a68 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Mon, 13 May 2024 13:43:00 -0700
Subject: [PATCH 08/33] No more unistd
---
compiler-rt/lib/radsan/radsan.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/compiler-rt/lib/radsan/radsan.cpp b/compiler-rt/lib/radsan/radsan.cpp
index dbe787ea6f6e4..e5117ac0d5f78 100644
--- a/compiler-rt/lib/radsan/radsan.cpp
+++ b/compiler-rt/lib/radsan/radsan.cpp
@@ -11,7 +11,6 @@
#include <radsan/radsan.h>
#include <radsan/radsan_context.h>
#include <radsan/radsan_interceptors.h>
-#include <unistd.h>
extern "C" {
>From a03a2286e8329ea0b5f4bb91fbcf150fe7f21583 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Mon, 13 May 2024 13:43:18 -0700
Subject: [PATCH 09/33] Radsan context moved to impl
---
compiler-rt/lib/radsan/radsan_context.cpp | 31 +++++++++++++----------
1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/compiler-rt/lib/radsan/radsan_context.cpp b/compiler-rt/lib/radsan/radsan_context.cpp
index 16fdf967ff4d8..37f4faaff61a8 100644
--- a/compiler-rt/lib/radsan/radsan_context.cpp
+++ b/compiler-rt/lib/radsan/radsan_context.cpp
@@ -28,6 +28,23 @@ static pthread_key_t Key;
static pthread_once_t KeyOnce = PTHREAD_ONCE_INIT;
void internalFree(void *Ptr) { __sanitizer::InternalFree(Ptr); }
+using radsan::Context;
+
+Context &GetContextForThisThreadImpl() {
+ auto MakeTlsKey = []() {
+ CHECK_EQ(pthread_key_create(&detail::Key, detail::internalFree), 0);
+ };
+
+ pthread_once(&detail::KeyOnce, MakeTlsKey);
+ Context *CurrentThreadContext = static_cast<Context *>(pthread_getspecific(detail::Key));
+ if (CurrentThreadContext == nullptr) {
+ CurrentThreadContext = static_cast<Context *>(InternalAlloc(sizeof(Context)));
+ new(CurrentThreadContext) Context();
+ pthread_setspecific(detail::Key, CurrentThreadContext);
+ }
+
+ return *CurrentThreadContext;
+}
} // namespace detail
namespace radsan {
@@ -64,19 +81,7 @@ void Context::PrintDiagnostics(const char *InterceptedFunctionName) {
}
Context &GetContextForThisThread() {
- auto MakeTlsKey = []() {
- CHECK_EQ(pthread_key_create(&detail::Key, detail::internalFree), 0);
- };
-
- pthread_once(&detail::KeyOnce, MakeTlsKey);
- Context *CurrentThreadContext = static_cast<Context *>(pthread_getspecific(detail::Key));
- if (CurrentThreadContext == nullptr) {
- CurrentThreadContext = static_cast<Context *>(InternalAlloc(sizeof(Context)));
- new(CurrentThreadContext) Context();
- pthread_setspecific(detail::Key, CurrentThreadContext);
- }
-
- return *CurrentThreadContext;
+ return detail::GetContextForThisThreadImpl();
}
} // namespace radsan
>From 4c721db30375caeaf1c012a06ce9580f44af1c80 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Mon, 13 May 2024 14:02:36 -0700
Subject: [PATCH 10/33] Promise lit tests later
---
compiler-rt/test/radsan/CMakeLists.txt | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/compiler-rt/test/radsan/CMakeLists.txt b/compiler-rt/test/radsan/CMakeLists.txt
index 51a3ff72859b6..d6b8dc9652879 100644
--- a/compiler-rt/test/radsan/CMakeLists.txt
+++ b/compiler-rt/test/radsan/CMakeLists.txt
@@ -1,3 +1,14 @@
+
+
+
+
+######
+# TODO: Full lit tests coming in a future review when we introduce the codegen
+######
+
+
+
+
set(RADSAN_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(RADSAN_TESTSUITES)
>From 6ac0c66b8c2c489b3b89b9c41114930e104424b6 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Mon, 13 May 2024 14:05:57 -0700
Subject: [PATCH 11/33] Move radsan_test and add helper comment to top of file
---
compiler-rt/lib/radsan/tests/CMakeLists.txt | 2 +-
.../tests/{radsan_test.cpp => radsan_test_functional.cpp} | 4 ++++
2 files changed, 5 insertions(+), 1 deletion(-)
rename compiler-rt/lib/radsan/tests/{radsan_test.cpp => radsan_test_functional.cpp} (96%)
diff --git a/compiler-rt/lib/radsan/tests/CMakeLists.txt b/compiler-rt/lib/radsan/tests/CMakeLists.txt
index 73cedac2765d6..79a3d2d3d6c23 100644
--- a/compiler-rt/lib/radsan/tests/CMakeLists.txt
+++ b/compiler-rt/lib/radsan/tests/CMakeLists.txt
@@ -15,7 +15,7 @@ set(RADSAN_UNITTEST_CFLAGS
-O2)
set(RADSAN_INST_TEST_SOURCES
- radsan_test.cpp
+ radsan_test_functional.cpp
radsan_test_interceptors.cpp
radsan_test_main.cpp)
diff --git a/compiler-rt/lib/radsan/tests/radsan_test.cpp b/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp
similarity index 96%
rename from compiler-rt/lib/radsan/tests/radsan_test.cpp
rename to compiler-rt/lib/radsan/tests/radsan_test_functional.cpp
index 521545ca8a9e2..8adb3b94c5406 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp
@@ -6,6 +6,10 @@
//
//===----------------------------------------------------------------------===//
//
+// Introduces basic functional tests for the realtime sanitizer.
+// Not meant to be exhaustive, testing all interceptors, please see
+// test_radsan_interceptors.cpp for those tests.
+//
//===----------------------------------------------------------------------===//
#include "gtest/gtest.h"
>From 1be7de3305891565dd99c58c3e6b3878ca565126 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Mon, 13 May 2024 14:06:13 -0700
Subject: [PATCH 12/33] Only link radsan statically
---
clang/lib/Driver/ToolChains/CommonArgs.cpp | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 002bf456dc026..7f5ab360f2458 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1357,8 +1357,6 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
if (!Args.hasArg(options::OPT_shared))
HelperStaticRuntimes.push_back("hwasan-preinit");
}
- if (SanArgs.needsRadsanRt() && SanArgs.linkRuntimes())
- SharedRuntimes.push_back("radsan");
}
// The stats_client library is also statically linked into DSOs.
@@ -1384,7 +1382,7 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
StaticRuntimes.push_back("asan_cxx");
}
- if (!SanArgs.needsSharedRt() && SanArgs.needsRadsanRt() && SanArgs.linkRuntimes()) {
+ if (!SanArgs.needsSharedRt() && SanArgs.needsRadsanRt()) {
StaticRuntimes.push_back("radsan");
}
>From de92a9c65b61b83ca05773b782a6faf2de370004 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Wed, 15 May 2024 13:54:13 -0700
Subject: [PATCH 13/33] Fix comments in radsan.h
---
compiler-rt/lib/radsan/radsan.h | 44 +++++++--------------------------
1 file changed, 9 insertions(+), 35 deletions(-)
diff --git a/compiler-rt/lib/radsan/radsan.h b/compiler-rt/lib/radsan/radsan.h
index 61205e93e29ed..b79933fde5171 100644
--- a/compiler-rt/lib/radsan/radsan.h
+++ b/compiler-rt/lib/radsan/radsan.h
@@ -14,62 +14,36 @@
extern "C" {
-/**
- Initialise radsan interceptors. A call to this method is added to the
- preinit array on Linux systems.
+/** Initialise radsan interceptors.
- @warning Do not call this method as a user.
+ A call to this method is added to the preinit array on Linux systems.
*/
SANITIZER_INTERFACE_ATTRIBUTE void radsan_init();
/** Enter real-time context.
- When in a real-time context, RADSan interceptors will error if realtime
- violations are detected. Calls to this method are injected at the code
- generation stage when RADSan is enabled.
-
- @warning Do not call this method as a user
+ When in a real-time context, RADSan interceptors will error if realtime
+ violations are detected. Calls to this method are injected at the code
+ generation stage when RADSan is enabled.
*/
SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_enter();
/** Exit the real-time context.
- When not in a real-time context, RADSan interceptors will simply forward
- intercepted method calls to the real methods.
-
- @warning Do not call this method as a user
+ When not in a real-time context, RADSan interceptors will simply forward
+ intercepted method calls to the real methods.
*/
SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_exit();
/** Disable all RADSan error reporting.
- This method might be useful to you if RADSan is presenting you with an error
- for some code you are confident is realtime safe. For example, you might
- know that a mutex is never contested, and that locking it will never block
- on your particular system. Be careful!
-
- A call to `radsan_off()` MUST be paired with a corresponding `radsan_on()`
- to reactivate interception after the code in question. If you don't, radsan
- will cease to work.
-
- Example:
-
- float process (float x) [[clang::nonblocking]]
- {
- auto const y = 2.0f * x;
-
- radsan_off();
- i_know_this_method_is_realtime_safe_but_radsan_complains_about_it();
- radsan_on();
- }
-
+ Injected into the code if "nosanitize(realtime)" is on a function.
*/
SANITIZER_INTERFACE_ATTRIBUTE void radsan_off();
/** Re-enable all RADSan error reporting.
- The counterpart to `radsan_off`. See the description for `radsan_off` for
- details about how to use this method.
+ The counterpart to `radsan_off`.
*/
SANITIZER_INTERFACE_ATTRIBUTE void radsan_on();
>From 688422dd669785537f49c26e4663d20bb9d4cd65 Mon Sep 17 00:00:00 2001
From: David Trevelyan <david.trevelyan at gmail.com>
Date: Thu, 16 May 2024 22:18:07 +0100
Subject: [PATCH 14/33] Replace inlined exit with selected action stub
---
compiler-rt/lib/radsan/radsan_context.cpp | 27 +++++++++++++++++++----
1 file changed, 23 insertions(+), 4 deletions(-)
diff --git a/compiler-rt/lib/radsan/radsan_context.cpp b/compiler-rt/lib/radsan/radsan_context.cpp
index 37f4faaff61a8..97bee5e57c016 100644
--- a/compiler-rt/lib/radsan/radsan_context.cpp
+++ b/compiler-rt/lib/radsan/radsan_context.cpp
@@ -36,15 +36,34 @@ Context &GetContextForThisThreadImpl() {
};
pthread_once(&detail::KeyOnce, MakeTlsKey);
- Context *CurrentThreadContext = static_cast<Context *>(pthread_getspecific(detail::Key));
+ Context *CurrentThreadContext =
+ static_cast<Context *>(pthread_getspecific(detail::Key));
if (CurrentThreadContext == nullptr) {
- CurrentThreadContext = static_cast<Context *>(InternalAlloc(sizeof(Context)));
- new(CurrentThreadContext) Context();
+ CurrentThreadContext =
+ static_cast<Context *>(InternalAlloc(sizeof(Context)));
+ new (CurrentThreadContext) Context();
pthread_setspecific(detail::Key, CurrentThreadContext);
}
return *CurrentThreadContext;
}
+
+/*
+ This is a placeholder stub for a future feature that will allow
+ a user to configure RADSan's behaviour when a real-time safety
+ violation is detected. The RADSan developers intend for the
+ following choices to be made available, via a RADSAN_OPTIONS
+ environment variable, in a future PR:
+
+ i) exit,
+ ii) continue, or
+ iii) wait for user input from stdin.
+
+ Until then, and to keep the first PRs small, only the exit mode
+ is available.
+*/
+void InvokeViolationDetectedAction() { exit(EXIT_FAILURE); }
+
} // namespace detail
namespace radsan {
@@ -63,7 +82,7 @@ void Context::ExpectNotRealtime(const char *InterceptedFunctionName) {
if (InRealtimeContext() && !IsBypassed()) {
BypassPush();
PrintDiagnostics(InterceptedFunctionName);
- exit(EXIT_FAILURE);
+ detail::InvokeViolationDetectedAction();
BypassPop();
}
}
>From ee7c1c4613207e1d4c05b5a5d82f34bb28026239 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Thu, 16 May 2024 13:54:01 -0700
Subject: [PATCH 15/33] Codeowners
---
compiler-rt/CODE_OWNERS.TXT | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/compiler-rt/CODE_OWNERS.TXT b/compiler-rt/CODE_OWNERS.TXT
index ad136edf96781..2db0357fc1a7f 100644
--- a/compiler-rt/CODE_OWNERS.TXT
+++ b/compiler-rt/CODE_OWNERS.TXT
@@ -67,3 +67,7 @@ D: ThreadSanitizer
N: Bill Wendling
E: isanbard at gmail.com
D: Profile runtime library
+
+N: Christopher Apple, David Trevelyan
+E: cja-private at pm.me, realtime.sanitizer at gmail.com
+D: Realtime Sanitizer (RADSan)
>From e4d26090313cf85ab28abaaa86e53fd42eed365f Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Thu, 16 May 2024 14:40:46 -0700
Subject: [PATCH 16/33] Fix python formatting errors
---
compiler-rt/test/radsan/lit.cfg.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/compiler-rt/test/radsan/lit.cfg.py b/compiler-rt/test/radsan/lit.cfg.py
index 773b624900fa6..32af62dfb8e04 100644
--- a/compiler-rt/test/radsan/lit.cfg.py
+++ b/compiler-rt/test/radsan/lit.cfg.py
@@ -40,7 +40,9 @@ def build_invocation(compile_flags):
("%clangxx ", build_invocation(config.cxx_mode_flags + [config.target_cflags]))
)
config.substitutions.append(("%clang_radsan ", build_invocation(clang_radsan_cflags)))
-config.substitutions.append(("%clangxx_radsan", build_invocation(clang_radsan_cxxflags)))
+config.substitutions.append(
+ ("%clangxx_radsan", build_invocation(clang_radsan_cxxflags))
+)
config.substitutions.append(("%llvm_radsan", llvm_radsan))
config.substitutions.append(
(
>From 37f60b73208b9f805c535c54ba1c5088c70f7d2d Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Thu, 16 May 2024 14:43:43 -0700
Subject: [PATCH 17/33] Fix cpp style issues
---
clang/lib/Driver/ToolChains/Darwin.cpp | 6 +++---
compiler-rt/lib/radsan/radsan.cpp | 4 ++--
compiler-rt/lib/radsan/radsan.h | 4 ++--
compiler-rt/lib/radsan/radsan_interceptors.cpp | 3 ++-
compiler-rt/lib/radsan/radsan_interceptors.h | 3 ++-
compiler-rt/lib/radsan/radsan_preinit.cpp | 4 ++--
.../lib/radsan/tests/radsan_test_context.cpp | 3 ++-
.../lib/radsan/tests/radsan_test_interceptors.cpp | 15 ++++++++-------
.../lib/radsan/tests/radsan_test_utilities.h | 9 ++++-----
9 files changed, 27 insertions(+), 24 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index 1e04be42e4085..a395c3bcfd8fb 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -1511,9 +1511,9 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
AddLinkSanitizerLibArgs(Args, CmdArgs, "asan");
}
}
- if(Sanitize.needsRadsanRt())
- {
- assert(Sanitize.needsSharedRt() && "Static sanitizer runtimes not supported");
+ if (Sanitize.needsRadsanRt()) {
+ assert(Sanitize.needsSharedRt() &&
+ "Static sanitizer runtimes not supported");
AddLinkSanitizerLibArgs(Args, CmdArgs, "radsan");
}
if (Sanitize.needsLsanRt())
diff --git a/compiler-rt/lib/radsan/radsan.cpp b/compiler-rt/lib/radsan/radsan.cpp
index e5117ac0d5f78..97069a0ac1299 100644
--- a/compiler-rt/lib/radsan/radsan.cpp
+++ b/compiler-rt/lib/radsan/radsan.cpp
@@ -14,8 +14,8 @@
extern "C" {
-SANITIZER_INTERFACE_ATTRIBUTE void radsan_init() {
- radsan::InitializeInterceptors();
+SANITIZER_INTERFACE_ATTRIBUTE void radsan_init() {
+ radsan::InitializeInterceptors();
}
SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_enter() {
diff --git a/compiler-rt/lib/radsan/radsan.h b/compiler-rt/lib/radsan/radsan.h
index b79933fde5171..28682cb9c1b24 100644
--- a/compiler-rt/lib/radsan/radsan.h
+++ b/compiler-rt/lib/radsan/radsan.h
@@ -14,7 +14,7 @@
extern "C" {
-/** Initialise radsan interceptors.
+/** Initialise radsan interceptors.
A call to this method is added to the preinit array on Linux systems.
*/
@@ -43,7 +43,7 @@ SANITIZER_INTERFACE_ATTRIBUTE void radsan_off();
/** Re-enable all RADSan error reporting.
- The counterpart to `radsan_off`.
+ The counterpart to `radsan_off`.
*/
SANITIZER_INTERFACE_ATTRIBUTE void radsan_on();
diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/radsan/radsan_interceptors.cpp
index f7fd005aa004d..0719d327585ff 100644
--- a/compiler-rt/lib/radsan/radsan_interceptors.cpp
+++ b/compiler-rt/lib/radsan/radsan_interceptors.cpp
@@ -1,4 +1,5 @@
-//===--- radsan_interceptors.cpp - Realtime Sanitizer --------------*- C++ -*-===//
+//===--- radsan_interceptors.cpp - Realtime Sanitizer --------------*- C++
+//-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/compiler-rt/lib/radsan/radsan_interceptors.h b/compiler-rt/lib/radsan/radsan_interceptors.h
index 30b37fb24a70f..9f020fa9d4df5 100644
--- a/compiler-rt/lib/radsan/radsan_interceptors.h
+++ b/compiler-rt/lib/radsan/radsan_interceptors.h
@@ -1,4 +1,5 @@
-//===--- radsan_interceptors.h - Realtime Sanitizer --------------*- C++ -*-===//
+//===--- radsan_interceptors.h - Realtime Sanitizer --------------*- C++
+//-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/compiler-rt/lib/radsan/radsan_preinit.cpp b/compiler-rt/lib/radsan/radsan_preinit.cpp
index e5e92becb1eac..d3ee60f939861 100644
--- a/compiler-rt/lib/radsan/radsan_preinit.cpp
+++ b/compiler-rt/lib/radsan/radsan_preinit.cpp
@@ -17,7 +17,7 @@
// exported.
// This code is linked into the main executable when -fsanitize=realtime is in
// the link flags. It can only use exported interface functions.
-__attribute__((section(".preinit_array"), used))
-void (*__local_radsan_preinit)(void) = radsan_init;
+__attribute__((section(".preinit_array"),
+ used)) void (*__local_radsan_preinit)(void) = radsan_init;
#endif
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp
index 91822df5a841d..d389b60e8cd90 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp
@@ -1,4 +1,5 @@
-//===--- radsan_test_context.cpp - Realtime Sanitizer --------------*- C++ -*-===//
+//===--- radsan_test_context.cpp - Realtime Sanitizer --------------*- C++
+//-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
index 20ed7c7542d03..e3b2e34fbe48a 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
@@ -1,4 +1,5 @@
-//===--- radsan_test_interceptors.cpp - Realtime Sanitizer --------------*- C++ -*-===//
+//===--- radsan_test_interceptors.cpp - Realtime Sanitizer --------------*- C++
+//-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -202,7 +203,7 @@ TEST(TestRadsanInterceptors, CloseDiesWhenRealtime) {
TEST(TestRadsanInterceptors, FopenDiesWhenRealtime) {
auto Func = []() {
- FILE* Fd = fopen(TemporaryFilePath(), "w");
+ FILE *Fd = fopen(TemporaryFilePath(), "w");
EXPECT_THAT(Fd, Ne(nullptr));
};
ExpectRealtimeDeath(Func, "fopen");
@@ -211,7 +212,7 @@ TEST(TestRadsanInterceptors, FopenDiesWhenRealtime) {
}
TEST(TestRadsanInterceptors, FreadDiesWhenRealtime) {
- FILE* Fd = fopen(TemporaryFilePath(), "w");
+ FILE *Fd = fopen(TemporaryFilePath(), "w");
auto Func = [Fd]() {
char c{};
fread(&c, 1, 1, Fd);
@@ -224,9 +225,9 @@ TEST(TestRadsanInterceptors, FreadDiesWhenRealtime) {
}
TEST(TestRadsanInterceptors, FwriteDiesWhenRealtime) {
- FILE* Fd = fopen(TemporaryFilePath(), "w");
+ FILE *Fd = fopen(TemporaryFilePath(), "w");
ASSERT_NE(nullptr, Fd);
- const char* Message = "Hello, world!";
+ const char *Message = "Hello, world!";
auto Func = [&]() { fwrite(&Message, 1, 4, Fd); };
ExpectRealtimeDeath(Func, "fwrite");
ExpectNonRealtimeSurvival(Func);
@@ -234,7 +235,7 @@ TEST(TestRadsanInterceptors, FwriteDiesWhenRealtime) {
}
TEST(TestRadsanInterceptors, FcloseDiesWhenRealtime) {
- FILE* Fd = fopen(TemporaryFilePath(), "w");
+ FILE *Fd = fopen(TemporaryFilePath(), "w");
EXPECT_THAT(Fd, Ne(nullptr));
auto Func = [Fd]() { fclose(Fd); };
ExpectRealtimeDeath(Func, "fclose");
@@ -249,7 +250,7 @@ TEST(TestRadsanInterceptors, PutsDiesWhenRealtime) {
}
TEST(TestRadsanInterceptors, FputsDiesWhenRealtime) {
- FILE* Fd = fopen(TemporaryFilePath(), "w");
+ FILE *Fd = fopen(TemporaryFilePath(), "w");
ASSERT_THAT(Fd, Ne(nullptr)) << errno;
auto Func = [Fd]() { fputs("Hello, world!\n", Fd); };
ExpectRealtimeDeath(Func);
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h b/compiler-rt/lib/radsan/tests/radsan_test_utilities.h
index 4a2510d5f87d4..8c2821e9825ea 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h
+++ b/compiler-rt/lib/radsan/tests/radsan_test_utilities.h
@@ -1,4 +1,5 @@
-//===--- radsan_test_utilities.h - Realtime Sanitizer --------------*- C++ -*-===//
+//===--- radsan_test_utilities.h - Realtime Sanitizer --------------*- C++
+//-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -10,15 +11,13 @@
#pragma once
-#include "gmock/gmock.h"
#include "radsan.h"
+#include "gmock/gmock.h"
#include <string>
namespace radsan_testing {
-template <typename Function>
-void RealtimeInvoke(Function &&Func)
-{
+template <typename Function> void RealtimeInvoke(Function &&Func) {
radsan_realtime_enter();
std::forward<Function>(Func)();
radsan_realtime_exit();
>From 1cfac7db715220fb9023e70b7dbe5bf8fb5fff82 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Sun, 19 May 2024 22:12:18 -0700
Subject: [PATCH 18/33] PR: Delete python header comment
---
compiler-rt/test/radsan/lit.cfg.py | 2 --
1 file changed, 2 deletions(-)
diff --git a/compiler-rt/test/radsan/lit.cfg.py b/compiler-rt/test/radsan/lit.cfg.py
index 32af62dfb8e04..b9e4dbc03abb6 100644
--- a/compiler-rt/test/radsan/lit.cfg.py
+++ b/compiler-rt/test/radsan/lit.cfg.py
@@ -1,5 +1,3 @@
-# -*- Python -*-
-
import os
# Setup config name.
>From 8b7da4bf50872adfe03d0b10895c49f034140628 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Sun, 19 May 2024 22:28:39 -0700
Subject: [PATCH 19/33] PR: Change main namespace name to __radsan
---
compiler-rt/lib/radsan/radsan.cpp | 10 +-
compiler-rt/lib/radsan/radsan_context.cpp | 8 +-
compiler-rt/lib/radsan/radsan_context.h | 4 +-
.../lib/radsan/radsan_interceptors.cpp | 100 +++++++++---------
compiler-rt/lib/radsan/radsan_interceptors.h | 2 +-
compiler-rt/lib/radsan/radsan_stack.cpp | 7 +-
compiler-rt/lib/radsan/radsan_stack.h | 2 +-
.../lib/radsan/tests/radsan_test_context.cpp | 14 +--
8 files changed, 73 insertions(+), 74 deletions(-)
diff --git a/compiler-rt/lib/radsan/radsan.cpp b/compiler-rt/lib/radsan/radsan.cpp
index 97069a0ac1299..52b228dd93195 100644
--- a/compiler-rt/lib/radsan/radsan.cpp
+++ b/compiler-rt/lib/radsan/radsan.cpp
@@ -15,23 +15,23 @@
extern "C" {
SANITIZER_INTERFACE_ATTRIBUTE void radsan_init() {
- radsan::InitializeInterceptors();
+ __radsan::InitializeInterceptors();
}
SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_enter() {
- radsan::GetContextForThisThread().RealtimePush();
+ __radsan::GetContextForThisThread().RealtimePush();
}
SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_exit() {
- radsan::GetContextForThisThread().RealtimePop();
+ __radsan::GetContextForThisThread().RealtimePop();
}
SANITIZER_INTERFACE_ATTRIBUTE void radsan_off() {
- radsan::GetContextForThisThread().BypassPush();
+ __radsan::GetContextForThisThread().BypassPush();
}
SANITIZER_INTERFACE_ATTRIBUTE void radsan_on() {
- radsan::GetContextForThisThread().BypassPop();
+ __radsan::GetContextForThisThread().BypassPop();
}
} // extern "C"
diff --git a/compiler-rt/lib/radsan/radsan_context.cpp b/compiler-rt/lib/radsan/radsan_context.cpp
index 97bee5e57c016..bb83b1e9f16c8 100644
--- a/compiler-rt/lib/radsan/radsan_context.cpp
+++ b/compiler-rt/lib/radsan/radsan_context.cpp
@@ -28,7 +28,7 @@ static pthread_key_t Key;
static pthread_once_t KeyOnce = PTHREAD_ONCE_INIT;
void internalFree(void *Ptr) { __sanitizer::InternalFree(Ptr); }
-using radsan::Context;
+using __radsan::Context;
Context &GetContextForThisThreadImpl() {
auto MakeTlsKey = []() {
@@ -66,7 +66,7 @@ void InvokeViolationDetectedAction() { exit(EXIT_FAILURE); }
} // namespace detail
-namespace radsan {
+namespace __radsan {
Context::Context() = default;
@@ -96,11 +96,11 @@ void Context::PrintDiagnostics(const char *InterceptedFunctionName) {
"Real-time violation: intercepted call to real-time unsafe function "
"`%s` in real-time context! Stack trace:\n",
InterceptedFunctionName);
- radsan::PrintStackTrace();
+ __radsan::PrintStackTrace();
}
Context &GetContextForThisThread() {
return detail::GetContextForThisThreadImpl();
}
-} // namespace radsan
+} // namespace __radsan
diff --git a/compiler-rt/lib/radsan/radsan_context.h b/compiler-rt/lib/radsan/radsan_context.h
index 6f8f937ca0739..103f055508d47 100644
--- a/compiler-rt/lib/radsan/radsan_context.h
+++ b/compiler-rt/lib/radsan/radsan_context.h
@@ -10,7 +10,7 @@
#pragma once
-namespace radsan {
+namespace __radsan {
class Context {
public:
@@ -35,4 +35,4 @@ class Context {
Context &GetContextForThisThread();
-} // namespace radsan
+} // namespace __radsan
diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/radsan/radsan_interceptors.cpp
index 0719d327585ff..61b56269ac3ea 100644
--- a/compiler-rt/lib/radsan/radsan_interceptors.cpp
+++ b/compiler-rt/lib/radsan/radsan_interceptors.cpp
@@ -40,11 +40,11 @@
using namespace __sanitizer;
-namespace radsan {
+namespace __radsan {
void ExpectNotRealtime(const char *InterceptedFunctionName) {
GetContextForThisThread().ExpectNotRealtime(InterceptedFunctionName);
}
-} // namespace radsan
+} // namespace __radsan
/*
Filesystem
@@ -53,7 +53,7 @@ void ExpectNotRealtime(const char *InterceptedFunctionName) {
INTERCEPTOR(int, open, const char *path, int oflag, ...) {
// TODO Establish whether we should intercept here if the flag contains
// O_NONBLOCK
- radsan::ExpectNotRealtime("open");
+ __radsan::ExpectNotRealtime("open");
va_list args;
va_start(args, oflag);
const int result = REAL(open)(path, oflag, args);
@@ -64,7 +64,7 @@ INTERCEPTOR(int, open, const char *path, int oflag, ...) {
INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) {
// TODO Establish whether we should intercept here if the flag contains
// O_NONBLOCK
- radsan::ExpectNotRealtime("openat");
+ __radsan::ExpectNotRealtime("openat");
va_list args;
va_start(args, oflag);
const int result = REAL(openat)(fd, path, oflag, args);
@@ -75,13 +75,13 @@ INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) {
INTERCEPTOR(int, creat, const char *path, mode_t mode) {
// TODO Establish whether we should intercept here if the flag contains
// O_NONBLOCK
- radsan::ExpectNotRealtime("creat");
+ __radsan::ExpectNotRealtime("creat");
const int result = REAL(creat)(path, mode);
return result;
}
INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) {
- radsan::ExpectNotRealtime("fcntl");
+ __radsan::ExpectNotRealtime("fcntl");
va_list args;
va_start(args, cmd);
const int result = REAL(fcntl)(filedes, cmd, args);
@@ -90,34 +90,34 @@ INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) {
}
INTERCEPTOR(int, close, int filedes) {
- radsan::ExpectNotRealtime("close");
+ __radsan::ExpectNotRealtime("close");
return REAL(close)(filedes);
}
INTERCEPTOR(FILE *, fopen, const char *path, const char *mode) {
- radsan::ExpectNotRealtime("fopen");
+ __radsan::ExpectNotRealtime("fopen");
return REAL(fopen)(path, mode);
}
INTERCEPTOR(size_t, fread, void *ptr, size_t size, size_t nitems,
FILE *stream) {
- radsan::ExpectNotRealtime("fread");
+ __radsan::ExpectNotRealtime("fread");
return REAL(fread)(ptr, size, nitems, stream);
}
INTERCEPTOR(size_t, fwrite, const void *ptr, size_t size, size_t nitems,
FILE *stream) {
- radsan::ExpectNotRealtime("fwrite");
+ __radsan::ExpectNotRealtime("fwrite");
return REAL(fwrite)(ptr, size, nitems, stream);
}
INTERCEPTOR(int, fclose, FILE *stream) {
- radsan::ExpectNotRealtime("fclose");
+ __radsan::ExpectNotRealtime("fclose");
return REAL(fclose)(stream);
}
INTERCEPTOR(int, fputs, const char *s, FILE *stream) {
- radsan::ExpectNotRealtime("fputs");
+ __radsan::ExpectNotRealtime("fputs");
return REAL(fputs)(s, stream);
}
@@ -126,7 +126,7 @@ INTERCEPTOR(int, fputs, const char *s, FILE *stream) {
*/
INTERCEPTOR(int, puts, const char *s) {
- radsan::ExpectNotRealtime("puts");
+ __radsan::ExpectNotRealtime("puts");
return REAL(puts)(s);
}
@@ -139,77 +139,77 @@ INTERCEPTOR(int, puts, const char *s) {
// OSSpinLockLock is deprecated, but still in use in libc++
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
INTERCEPTOR(void, OSSpinLockLock, volatile OSSpinLock *lock) {
- radsan::ExpectNotRealtime("OSSpinLockLock");
+ __radsan::ExpectNotRealtime("OSSpinLockLock");
return REAL(OSSpinLockLock)(lock);
}
#pragma clang diagnostic pop
INTERCEPTOR(void, os_unfair_lock_lock, os_unfair_lock_t lock) {
- radsan::ExpectNotRealtime("os_unfair_lock_lock");
+ __radsan::ExpectNotRealtime("os_unfair_lock_lock");
return REAL(os_unfair_lock_lock)(lock);
}
#elif SANITIZER_LINUX
INTERCEPTOR(int, pthread_spin_lock, pthread_spinlock_t *spinlock) {
- radsan::ExpectNotRealtime("pthread_spin_lock");
+ __radsan::ExpectNotRealtime("pthread_spin_lock");
return REAL(pthread_spin_lock)(spinlock);
}
#endif
INTERCEPTOR(int, pthread_create, pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg) {
- radsan::ExpectNotRealtime("pthread_create");
+ __radsan::ExpectNotRealtime("pthread_create");
return REAL(pthread_create)(thread, attr, start_routine, arg);
}
INTERCEPTOR(int, pthread_mutex_lock, pthread_mutex_t *mutex) {
- radsan::ExpectNotRealtime("pthread_mutex_lock");
+ __radsan::ExpectNotRealtime("pthread_mutex_lock");
return REAL(pthread_mutex_lock)(mutex);
}
INTERCEPTOR(int, pthread_mutex_unlock, pthread_mutex_t *mutex) {
- radsan::ExpectNotRealtime("pthread_mutex_unlock");
+ __radsan::ExpectNotRealtime("pthread_mutex_unlock");
return REAL(pthread_mutex_unlock)(mutex);
}
INTERCEPTOR(int, pthread_join, pthread_t thread, void **value_ptr) {
- radsan::ExpectNotRealtime("pthread_join");
+ __radsan::ExpectNotRealtime("pthread_join");
return REAL(pthread_join)(thread, value_ptr);
}
INTERCEPTOR(int, pthread_cond_signal, pthread_cond_t *cond) {
- radsan::ExpectNotRealtime("pthread_cond_signal");
+ __radsan::ExpectNotRealtime("pthread_cond_signal");
return REAL(pthread_cond_signal)(cond);
}
INTERCEPTOR(int, pthread_cond_broadcast, pthread_cond_t *cond) {
- radsan::ExpectNotRealtime("pthread_cond_broadcast");
+ __radsan::ExpectNotRealtime("pthread_cond_broadcast");
return REAL(pthread_cond_broadcast)(cond);
}
INTERCEPTOR(int, pthread_cond_wait, pthread_cond_t *cond,
pthread_mutex_t *mutex) {
- radsan::ExpectNotRealtime("pthread_cond_wait");
+ __radsan::ExpectNotRealtime("pthread_cond_wait");
return REAL(pthread_cond_wait)(cond, mutex);
}
INTERCEPTOR(int, pthread_cond_timedwait, pthread_cond_t *cond,
pthread_mutex_t *mutex, const timespec *ts) {
- radsan::ExpectNotRealtime("pthread_cond_timedwait");
+ __radsan::ExpectNotRealtime("pthread_cond_timedwait");
return REAL(pthread_cond_timedwait)(cond, mutex, ts);
}
INTERCEPTOR(int, pthread_rwlock_rdlock, pthread_rwlock_t *lock) {
- radsan::ExpectNotRealtime("pthread_rwlock_rdlock");
+ __radsan::ExpectNotRealtime("pthread_rwlock_rdlock");
return REAL(pthread_rwlock_rdlock)(lock);
}
INTERCEPTOR(int, pthread_rwlock_unlock, pthread_rwlock_t *lock) {
- radsan::ExpectNotRealtime("pthread_rwlock_unlock");
+ __radsan::ExpectNotRealtime("pthread_rwlock_unlock");
return REAL(pthread_rwlock_unlock)(lock);
}
INTERCEPTOR(int, pthread_rwlock_wrlock, pthread_rwlock_t *lock) {
- radsan::ExpectNotRealtime("pthread_rwlock_wrlock");
+ __radsan::ExpectNotRealtime("pthread_rwlock_wrlock");
return REAL(pthread_rwlock_wrlock)(lock);
}
@@ -218,18 +218,18 @@ INTERCEPTOR(int, pthread_rwlock_wrlock, pthread_rwlock_t *lock) {
*/
INTERCEPTOR(unsigned int, sleep, unsigned int s) {
- radsan::ExpectNotRealtime("sleep");
+ __radsan::ExpectNotRealtime("sleep");
return REAL(sleep)(s);
}
INTERCEPTOR(int, usleep, useconds_t u) {
- radsan::ExpectNotRealtime("usleep");
+ __radsan::ExpectNotRealtime("usleep");
return REAL(usleep)(u);
}
INTERCEPTOR(int, nanosleep, const struct timespec *rqtp,
struct timespec *rmtp) {
- radsan::ExpectNotRealtime("nanosleep");
+ __radsan::ExpectNotRealtime("nanosleep");
return REAL(nanosleep)(rqtp, rmtp);
}
@@ -238,40 +238,40 @@ INTERCEPTOR(int, nanosleep, const struct timespec *rqtp,
*/
INTERCEPTOR(void *, calloc, SIZE_T num, SIZE_T size) {
- radsan::ExpectNotRealtime("calloc");
+ __radsan::ExpectNotRealtime("calloc");
return REAL(calloc)(num, size);
}
INTERCEPTOR(void, free, void *ptr) {
if (ptr != NULL) {
- radsan::ExpectNotRealtime("free");
+ __radsan::ExpectNotRealtime("free");
}
return REAL(free)(ptr);
}
INTERCEPTOR(void *, malloc, SIZE_T size) {
- radsan::ExpectNotRealtime("malloc");
+ __radsan::ExpectNotRealtime("malloc");
return REAL(malloc)(size);
}
INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) {
- radsan::ExpectNotRealtime("realloc");
+ __radsan::ExpectNotRealtime("realloc");
return REAL(realloc)(ptr, size);
}
INTERCEPTOR(void *, reallocf, void *ptr, SIZE_T size) {
- radsan::ExpectNotRealtime("reallocf");
+ __radsan::ExpectNotRealtime("reallocf");
return REAL(reallocf)(ptr, size);
}
INTERCEPTOR(void *, valloc, SIZE_T size) {
- radsan::ExpectNotRealtime("valloc");
+ __radsan::ExpectNotRealtime("valloc");
return REAL(valloc)(size);
}
#if SANITIZER_INTERCEPT_ALIGNED_ALLOC
INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) {
- radsan::ExpectNotRealtime("aligned_alloc");
+ __radsan::ExpectNotRealtime("aligned_alloc");
return REAL(aligned_alloc)(alignment, size);
}
#define RADSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(aligned_alloc)
@@ -280,20 +280,20 @@ INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) {
#endif
INTERCEPTOR(int, posix_memalign, void **memptr, size_t alignment, size_t size) {
- radsan::ExpectNotRealtime("posix_memalign");
+ __radsan::ExpectNotRealtime("posix_memalign");
return REAL(posix_memalign)(memptr, alignment, size);
}
#if SANITIZER_INTERCEPT_MEMALIGN
INTERCEPTOR(void *, memalign, size_t alignment, size_t size) {
- radsan::ExpectNotRealtime("memalign");
+ __radsan::ExpectNotRealtime("memalign");
return REAL(memalign)(alignment, size);
}
#endif
#if SANITIZER_INTERCEPT_PVALLOC
INTERCEPTOR(void *, pvalloc, size_t size) {
- radsan::ExpectNotRealtime("pvalloc");
+ __radsan::ExpectNotRealtime("pvalloc");
return REAL(pvalloc)(size);
}
#endif
@@ -303,45 +303,45 @@ INTERCEPTOR(void *, pvalloc, size_t size) {
*/
INTERCEPTOR(int, socket, int domain, int type, int protocol) {
- radsan::ExpectNotRealtime("socket");
+ __radsan::ExpectNotRealtime("socket");
return REAL(socket)(domain, type, protocol);
}
INTERCEPTOR(ssize_t, send, int sockfd, const void *buf, size_t len, int flags) {
- radsan::ExpectNotRealtime("send");
+ __radsan::ExpectNotRealtime("send");
return REAL(send)(sockfd, buf, len, flags);
}
INTERCEPTOR(ssize_t, sendmsg, int socket, const struct msghdr *message,
int flags) {
- radsan::ExpectNotRealtime("sendmsg");
+ __radsan::ExpectNotRealtime("sendmsg");
return REAL(sendmsg)(socket, message, flags);
}
INTERCEPTOR(ssize_t, sendto, int socket, const void *buffer, size_t length,
int flags, const struct sockaddr *dest_addr, socklen_t dest_len) {
- radsan::ExpectNotRealtime("sendto");
+ __radsan::ExpectNotRealtime("sendto");
return REAL(sendto)(socket, buffer, length, flags, dest_addr, dest_len);
}
INTERCEPTOR(ssize_t, recv, int socket, void *buffer, size_t length, int flags) {
- radsan::ExpectNotRealtime("recv");
+ __radsan::ExpectNotRealtime("recv");
return REAL(recv)(socket, buffer, length, flags);
}
INTERCEPTOR(ssize_t, recvfrom, int socket, void *buffer, size_t length,
int flags, struct sockaddr *address, socklen_t *address_len) {
- radsan::ExpectNotRealtime("recvfrom");
+ __radsan::ExpectNotRealtime("recvfrom");
return REAL(recvfrom)(socket, buffer, length, flags, address, address_len);
}
INTERCEPTOR(ssize_t, recvmsg, int socket, struct msghdr *message, int flags) {
- radsan::ExpectNotRealtime("recvmsg");
+ __radsan::ExpectNotRealtime("recvmsg");
return REAL(recvmsg)(socket, message, flags);
}
INTERCEPTOR(int, shutdown, int socket, int how) {
- radsan::ExpectNotRealtime("shutdown");
+ __radsan::ExpectNotRealtime("shutdown");
return REAL(shutdown)(socket, how);
}
@@ -349,7 +349,7 @@ INTERCEPTOR(int, shutdown, int socket, int how) {
Preinit
*/
-namespace radsan {
+namespace __radsan {
void InitializeInterceptors() {
INTERCEPT_FUNCTION(calloc);
INTERCEPT_FUNCTION(free);
@@ -410,4 +410,4 @@ void InitializeInterceptors() {
INTERCEPT_FUNCTION(recvfrom);
INTERCEPT_FUNCTION(shutdown);
}
-} // namespace radsan
+} // namespace __radsan
diff --git a/compiler-rt/lib/radsan/radsan_interceptors.h b/compiler-rt/lib/radsan/radsan_interceptors.h
index 9f020fa9d4df5..223d2afb93b10 100644
--- a/compiler-rt/lib/radsan/radsan_interceptors.h
+++ b/compiler-rt/lib/radsan/radsan_interceptors.h
@@ -11,6 +11,6 @@
#pragma once
-namespace radsan {
+namespace __radsan {
void InitializeInterceptors();
}
diff --git a/compiler-rt/lib/radsan/radsan_stack.cpp b/compiler-rt/lib/radsan/radsan_stack.cpp
index e8cb4ae19ce88..72236185e003c 100644
--- a/compiler-rt/lib/radsan/radsan_stack.cpp
+++ b/compiler-rt/lib/radsan/radsan_stack.cpp
@@ -27,7 +27,8 @@ void BufferedStackTrace::UnwindImpl(uptr pc, uptr bp, void *context,
}
} // namespace __sanitizer
-namespace {
+namespace __radsan {
+
void SetGlobalStackTraceFormat() {
SetCommonFlagsDefaults();
CommonFlags cf;
@@ -36,9 +37,7 @@ void SetGlobalStackTraceFormat() {
cf.external_symbolizer_path = GetEnv("RADSAN_SYMBOLIZER_PATH");
OverrideCommonFlags(cf);
}
-} // namespace
-namespace radsan {
void PrintStackTrace() {
BufferedStackTrace Stack{};
@@ -49,4 +48,4 @@ void PrintStackTrace() {
SetGlobalStackTraceFormat();
Stack.Print();
}
-} // namespace radsan
+} // namespace __radsan
diff --git a/compiler-rt/lib/radsan/radsan_stack.h b/compiler-rt/lib/radsan/radsan_stack.h
index 29ef7d016f1ef..356209d625c1e 100644
--- a/compiler-rt/lib/radsan/radsan_stack.h
+++ b/compiler-rt/lib/radsan/radsan_stack.h
@@ -10,6 +10,6 @@
#pragma once
-namespace radsan {
+namespace __radsan {
void PrintStackTrace();
}
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp
index d389b60e8cd90..69d788b37ba01 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp
@@ -13,22 +13,22 @@
#include "radsan_context.h"
-TEST(TestRadsanContext, CanCreateContext) { radsan::Context Context{}; }
+TEST(TestRadsanContext, CanCreateContext) { __radsan::Context Context{}; }
TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieBeforeRealtimePush) {
- radsan::Context Context{};
+ __radsan::Context Context{};
Context.ExpectNotRealtime("do_some_stuff");
}
TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieAfterPushAndPop) {
- radsan::Context Context{};
+ __radsan::Context Context{};
Context.RealtimePush();
Context.RealtimePop();
Context.ExpectNotRealtime("do_some_stuff");
}
TEST(TestRadsanContext, ExpectNotRealtimeDiesAfterRealtimePush) {
- radsan::Context Context{};
+ __radsan::Context Context{};
Context.RealtimePush();
EXPECT_DEATH(Context.ExpectNotRealtime("do_some_stuff"), "");
@@ -36,7 +36,7 @@ TEST(TestRadsanContext, ExpectNotRealtimeDiesAfterRealtimePush) {
TEST(TestRadsanContext,
ExpectNotRealtimeDiesAfterRealtimeAfterMorePushesThanPops) {
- radsan::Context Context{};
+ __radsan::Context Context{};
Context.RealtimePush();
Context.RealtimePush();
@@ -47,7 +47,7 @@ TEST(TestRadsanContext,
}
TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieAfterBypassPush) {
- radsan::Context Context{};
+ __radsan::Context Context{};
Context.RealtimePush();
Context.BypassPush();
@@ -56,7 +56,7 @@ TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieAfterBypassPush) {
TEST(TestRadsanContext,
ExpectNotRealtimeDoesNotDieIfBypassDepthIsGreaterThanZero) {
- radsan::Context Context{};
+ __radsan::Context Context{};
Context.RealtimePush();
Context.BypassPush();
>From 4d6008c7bd850fa50f27eb554b6990f0381a51a6 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Sun, 19 May 2024 22:31:49 -0700
Subject: [PATCH 20/33] PR: Fix stack trace namespace
---
compiler-rt/lib/radsan/radsan_stack.cpp | 8 +++++---
compiler-rt/lib/radsan/radsan_stack.h | 2 +-
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/compiler-rt/lib/radsan/radsan_stack.cpp b/compiler-rt/lib/radsan/radsan_stack.cpp
index 72236185e003c..6563893231b50 100644
--- a/compiler-rt/lib/radsan/radsan_stack.cpp
+++ b/compiler-rt/lib/radsan/radsan_stack.cpp
@@ -8,6 +8,8 @@
//
//===----------------------------------------------------------------------===//
+#include "radsan_stack.h"
+
#include <sanitizer_common/sanitizer_flags.h>
#include <sanitizer_common/sanitizer_stacktrace.h>
@@ -28,7 +30,6 @@ void BufferedStackTrace::UnwindImpl(uptr pc, uptr bp, void *context,
} // namespace __sanitizer
namespace __radsan {
-
void SetGlobalStackTraceFormat() {
SetCommonFlagsDefaults();
CommonFlags cf;
@@ -37,8 +38,10 @@ void SetGlobalStackTraceFormat() {
cf.external_symbolizer_path = GetEnv("RADSAN_SYMBOLIZER_PATH");
OverrideCommonFlags(cf);
}
+} // namespace __radsan
-void PrintStackTrace() {
+using namespace __radsan;
+void __radsan::PrintStackTrace() {
BufferedStackTrace Stack{};
@@ -48,4 +51,3 @@ void PrintStackTrace() {
SetGlobalStackTraceFormat();
Stack.Print();
}
-} // namespace __radsan
diff --git a/compiler-rt/lib/radsan/radsan_stack.h b/compiler-rt/lib/radsan/radsan_stack.h
index 356209d625c1e..73958f98d221d 100644
--- a/compiler-rt/lib/radsan/radsan_stack.h
+++ b/compiler-rt/lib/radsan/radsan_stack.h
@@ -12,4 +12,4 @@
namespace __radsan {
void PrintStackTrace();
-}
+} // namespace __radsan
>From 0038d3f9ec82e1bc378db166ad6340fbb89b3a12 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Sun, 19 May 2024 22:35:21 -0700
Subject: [PATCH 21/33] PR: Fix incorrect C++ style comments
---
.../lib/radsan/radsan_interceptors.cpp | 32 ++++---------------
1 file changed, 7 insertions(+), 25 deletions(-)
diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/radsan/radsan_interceptors.cpp
index 61b56269ac3ea..23077dbb32f31 100644
--- a/compiler-rt/lib/radsan/radsan_interceptors.cpp
+++ b/compiler-rt/lib/radsan/radsan_interceptors.cpp
@@ -46,9 +46,7 @@ void ExpectNotRealtime(const char *InterceptedFunctionName) {
}
} // namespace __radsan
-/*
- Filesystem
-*/
+// Filesystem
INTERCEPTOR(int, open, const char *path, int oflag, ...) {
// TODO Establish whether we should intercept here if the flag contains
@@ -121,19 +119,13 @@ INTERCEPTOR(int, fputs, const char *s, FILE *stream) {
return REAL(fputs)(s, stream);
}
-/*
- Streams
-*/
-
+// Streams
INTERCEPTOR(int, puts, const char *s) {
__radsan::ExpectNotRealtime("puts");
return REAL(puts)(s);
}
-/*
- Concurrency
-*/
-
+ // Concurrency
#if SANITIZER_APPLE
#pragma clang diagnostic push
// OSSpinLockLock is deprecated, but still in use in libc++
@@ -213,9 +205,7 @@ INTERCEPTOR(int, pthread_rwlock_wrlock, pthread_rwlock_t *lock) {
return REAL(pthread_rwlock_wrlock)(lock);
}
-/*
- Sleeping
-*/
+// Sleeping
INTERCEPTOR(unsigned int, sleep, unsigned int s) {
__radsan::ExpectNotRealtime("sleep");
@@ -233,9 +223,7 @@ INTERCEPTOR(int, nanosleep, const struct timespec *rqtp,
return REAL(nanosleep)(rqtp, rmtp);
}
-/*
- Memory
-*/
+// Memory
INTERCEPTOR(void *, calloc, SIZE_T num, SIZE_T size) {
__radsan::ExpectNotRealtime("calloc");
@@ -298,10 +286,7 @@ INTERCEPTOR(void *, pvalloc, size_t size) {
}
#endif
-/*
- Sockets
-*/
-
+// Sockets
INTERCEPTOR(int, socket, int domain, int type, int protocol) {
__radsan::ExpectNotRealtime("socket");
return REAL(socket)(domain, type, protocol);
@@ -345,10 +330,7 @@ INTERCEPTOR(int, shutdown, int socket, int how) {
return REAL(shutdown)(socket, how);
}
-/*
- Preinit
-*/
-
+// Preinit
namespace __radsan {
void InitializeInterceptors() {
INTERCEPT_FUNCTION(calloc);
>From 73cfdc7e100c79cf3c60a8ba00b4169337993097 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Sun, 19 May 2024 22:37:52 -0700
Subject: [PATCH 22/33] PR: Prefix external API with dunderscores
---
compiler-rt/lib/radsan/radsan.cpp | 10 +++++-----
compiler-rt/lib/radsan/radsan.h | 12 ++++++------
compiler-rt/lib/radsan/radsan_preinit.cpp | 2 +-
.../lib/radsan/tests/radsan_test_functional.cpp | 4 ++--
compiler-rt/lib/radsan/tests/radsan_test_utilities.h | 4 ++--
5 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/compiler-rt/lib/radsan/radsan.cpp b/compiler-rt/lib/radsan/radsan.cpp
index 52b228dd93195..5fc7d1ab8beea 100644
--- a/compiler-rt/lib/radsan/radsan.cpp
+++ b/compiler-rt/lib/radsan/radsan.cpp
@@ -14,23 +14,23 @@
extern "C" {
-SANITIZER_INTERFACE_ATTRIBUTE void radsan_init() {
+SANITIZER_INTERFACE_ATTRIBUTE void __radsan_init() {
__radsan::InitializeInterceptors();
}
-SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_enter() {
+SANITIZER_INTERFACE_ATTRIBUTE void __radsan_realtime_enter() {
__radsan::GetContextForThisThread().RealtimePush();
}
-SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_exit() {
+SANITIZER_INTERFACE_ATTRIBUTE void __radsan_realtime_exit() {
__radsan::GetContextForThisThread().RealtimePop();
}
-SANITIZER_INTERFACE_ATTRIBUTE void radsan_off() {
+SANITIZER_INTERFACE_ATTRIBUTE void __radsan_off() {
__radsan::GetContextForThisThread().BypassPush();
}
-SANITIZER_INTERFACE_ATTRIBUTE void radsan_on() {
+SANITIZER_INTERFACE_ATTRIBUTE void __radsan_on() {
__radsan::GetContextForThisThread().BypassPop();
}
diff --git a/compiler-rt/lib/radsan/radsan.h b/compiler-rt/lib/radsan/radsan.h
index 28682cb9c1b24..3f2df5ef05dff 100644
--- a/compiler-rt/lib/radsan/radsan.h
+++ b/compiler-rt/lib/radsan/radsan.h
@@ -18,7 +18,7 @@ extern "C" {
A call to this method is added to the preinit array on Linux systems.
*/
-SANITIZER_INTERFACE_ATTRIBUTE void radsan_init();
+SANITIZER_INTERFACE_ATTRIBUTE void __radsan_init();
/** Enter real-time context.
@@ -26,25 +26,25 @@ SANITIZER_INTERFACE_ATTRIBUTE void radsan_init();
violations are detected. Calls to this method are injected at the code
generation stage when RADSan is enabled.
*/
-SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_enter();
+SANITIZER_INTERFACE_ATTRIBUTE void __radsan_realtime_enter();
/** Exit the real-time context.
When not in a real-time context, RADSan interceptors will simply forward
intercepted method calls to the real methods.
*/
-SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_exit();
+SANITIZER_INTERFACE_ATTRIBUTE void __radsan_realtime_exit();
/** Disable all RADSan error reporting.
Injected into the code if "nosanitize(realtime)" is on a function.
*/
-SANITIZER_INTERFACE_ATTRIBUTE void radsan_off();
+SANITIZER_INTERFACE_ATTRIBUTE void __radsan_off();
/** Re-enable all RADSan error reporting.
- The counterpart to `radsan_off`.
+ The counterpart to `__radsan_off`.
*/
-SANITIZER_INTERFACE_ATTRIBUTE void radsan_on();
+SANITIZER_INTERFACE_ATTRIBUTE void __radsan_on();
} // extern "C"
diff --git a/compiler-rt/lib/radsan/radsan_preinit.cpp b/compiler-rt/lib/radsan/radsan_preinit.cpp
index d3ee60f939861..43bf1d6714a40 100644
--- a/compiler-rt/lib/radsan/radsan_preinit.cpp
+++ b/compiler-rt/lib/radsan/radsan_preinit.cpp
@@ -18,6 +18,6 @@
// This code is linked into the main executable when -fsanitize=realtime is in
// the link flags. It can only use exported interface functions.
__attribute__((section(".preinit_array"),
- used)) void (*__local_radsan_preinit)(void) = radsan_init;
+ used)) void (*__local_radsan_preinit)(void) = __radsan_init;
#endif
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp b/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp
index 8adb3b94c5406..c4bcb9952df2a 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp
@@ -198,10 +198,10 @@ TEST(TestRadsan, ThrowingAnExceptionDiesWhenRealtime) {
TEST(TestRadsan, DoesNotDieIfTurnedOff) {
std::mutex Mutex{};
auto RealtimeUnsafeFunc = [&]() {
- radsan_off();
+ __radsan_off();
Mutex.lock();
Mutex.unlock();
- radsan_on();
+ __radsan_on();
};
RealtimeInvoke(RealtimeUnsafeFunc);
}
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h b/compiler-rt/lib/radsan/tests/radsan_test_utilities.h
index 8c2821e9825ea..950c018aff304 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h
+++ b/compiler-rt/lib/radsan/tests/radsan_test_utilities.h
@@ -18,9 +18,9 @@
namespace radsan_testing {
template <typename Function> void RealtimeInvoke(Function &&Func) {
- radsan_realtime_enter();
+ __radsan_realtime_enter();
std::forward<Function>(Func)();
- radsan_realtime_exit();
+ __radsan_realtime_exit();
}
template <typename Function>
>From 53a18284b9d422ef22fb45d359ddded23f6e0942 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Mon, 20 May 2024 08:39:46 -0700
Subject: [PATCH 23/33] PR: Fix variable naming cases for variables, leave
lambdas for now
---
compiler-rt/lib/radsan/radsan_context.cpp | 46 +++----
compiler-rt/lib/radsan/radsan_context.h | 8 +-
.../lib/radsan/radsan_interceptors.cpp | 4 +-
compiler-rt/lib/radsan/radsan_interceptors.h | 2 +-
compiler-rt/lib/radsan/radsan_stack.cpp | 6 +-
.../lib/radsan/tests/radsan_test_context.cpp | 62 ++++-----
.../radsan/tests/radsan_test_functional.cpp | 74 +++++-----
.../radsan/tests/radsan_test_interceptors.cpp | 126 +++++++++---------
.../lib/radsan/tests/radsan_test_utilities.h | 4 +-
9 files changed, 166 insertions(+), 166 deletions(-)
diff --git a/compiler-rt/lib/radsan/radsan_context.cpp b/compiler-rt/lib/radsan/radsan_context.cpp
index bb83b1e9f16c8..344dfb6bdcdd1 100644
--- a/compiler-rt/lib/radsan/radsan_context.cpp
+++ b/compiler-rt/lib/radsan/radsan_context.cpp
@@ -24,28 +24,28 @@ using namespace __sanitizer;
namespace detail {
-static pthread_key_t Key;
-static pthread_once_t KeyOnce = PTHREAD_ONCE_INIT;
-void internalFree(void *Ptr) { __sanitizer::InternalFree(Ptr); }
+static pthread_key_t key;
+static pthread_once_t key_once = PTHREAD_ONCE_INIT;
+void internalFree(void *ptr) { __sanitizer::InternalFree(ptr); }
using __radsan::Context;
Context &GetContextForThisThreadImpl() {
- auto MakeTlsKey = []() {
- CHECK_EQ(pthread_key_create(&detail::Key, detail::internalFree), 0);
+ auto make_tls_key = []() {
+ CHECK_EQ(pthread_key_create(&detail::key, detail::internalFree), 0);
};
- pthread_once(&detail::KeyOnce, MakeTlsKey);
- Context *CurrentThreadContext =
- static_cast<Context *>(pthread_getspecific(detail::Key));
- if (CurrentThreadContext == nullptr) {
- CurrentThreadContext =
+ pthread_once(&detail::key_once, make_tls_key);
+ Context *current_thread_context =
+ static_cast<Context *>(pthread_getspecific(detail::key));
+ if (current_thread_context == nullptr) {
+ current_thread_context =
static_cast<Context *>(InternalAlloc(sizeof(Context)));
- new (CurrentThreadContext) Context();
- pthread_setspecific(detail::Key, CurrentThreadContext);
+ new (current_thread_context) Context();
+ pthread_setspecific(detail::key, current_thread_context);
}
- return *CurrentThreadContext;
+ return *current_thread_context;
}
/*
@@ -70,32 +70,32 @@ namespace __radsan {
Context::Context() = default;
-void Context::RealtimePush() { RealtimeDepth++; }
+void Context::RealtimePush() { realtime_depth++; }
-void Context::RealtimePop() { RealtimeDepth--; }
+void Context::RealtimePop() { realtime_depth--; }
-void Context::BypassPush() { BypassDepth++; }
+void Context::BypassPush() { bypass_depth++; }
-void Context::BypassPop() { BypassDepth--; }
+void Context::BypassPop() { bypass_depth--; }
-void Context::ExpectNotRealtime(const char *InterceptedFunctionName) {
+void Context::ExpectNotRealtime(const char *intercepted_function_name) {
if (InRealtimeContext() && !IsBypassed()) {
BypassPush();
- PrintDiagnostics(InterceptedFunctionName);
+ PrintDiagnostics(intercepted_function_name);
detail::InvokeViolationDetectedAction();
BypassPop();
}
}
-bool Context::InRealtimeContext() const { return RealtimeDepth > 0; }
+bool Context::InRealtimeContext() const { return realtime_depth > 0; }
-bool Context::IsBypassed() const { return BypassDepth > 0; }
+bool Context::IsBypassed() const { return bypass_depth > 0; }
-void Context::PrintDiagnostics(const char *InterceptedFunctionName) {
+void Context::PrintDiagnostics(const char *intercepted_function_name) {
fprintf(stderr,
"Real-time violation: intercepted call to real-time unsafe function "
"`%s` in real-time context! Stack trace:\n",
- InterceptedFunctionName);
+ intercepted_function_name);
__radsan::PrintStackTrace();
}
diff --git a/compiler-rt/lib/radsan/radsan_context.h b/compiler-rt/lib/radsan/radsan_context.h
index 103f055508d47..8fddae0291e45 100644
--- a/compiler-rt/lib/radsan/radsan_context.h
+++ b/compiler-rt/lib/radsan/radsan_context.h
@@ -22,15 +22,15 @@ class Context {
void BypassPush();
void BypassPop();
- void ExpectNotRealtime(const char *InterceptedFunctionName);
+ void ExpectNotRealtime(const char *intercepted_function_name);
private:
bool InRealtimeContext() const;
bool IsBypassed() const;
- void PrintDiagnostics(const char *InterceptedFunctionName);
+ void PrintDiagnostics(const char *intercepted_function_name);
- int RealtimeDepth{0};
- int BypassDepth{0};
+ int realtime_depth{0};
+ int bypass_depth{0};
};
Context &GetContextForThisThread();
diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/radsan/radsan_interceptors.cpp
index 23077dbb32f31..b157b9d25bdb1 100644
--- a/compiler-rt/lib/radsan/radsan_interceptors.cpp
+++ b/compiler-rt/lib/radsan/radsan_interceptors.cpp
@@ -41,8 +41,8 @@
using namespace __sanitizer;
namespace __radsan {
-void ExpectNotRealtime(const char *InterceptedFunctionName) {
- GetContextForThisThread().ExpectNotRealtime(InterceptedFunctionName);
+void ExpectNotRealtime(const char *intercepted_function_name) {
+ GetContextForThisThread().ExpectNotRealtime(intercepted_function_name);
}
} // namespace __radsan
diff --git a/compiler-rt/lib/radsan/radsan_interceptors.h b/compiler-rt/lib/radsan/radsan_interceptors.h
index 223d2afb93b10..95dd44ca5bc80 100644
--- a/compiler-rt/lib/radsan/radsan_interceptors.h
+++ b/compiler-rt/lib/radsan/radsan_interceptors.h
@@ -13,4 +13,4 @@
namespace __radsan {
void InitializeInterceptors();
-}
+} // namespace __radsan
diff --git a/compiler-rt/lib/radsan/radsan_stack.cpp b/compiler-rt/lib/radsan/radsan_stack.cpp
index 6563893231b50..1ba56a7068343 100644
--- a/compiler-rt/lib/radsan/radsan_stack.cpp
+++ b/compiler-rt/lib/radsan/radsan_stack.cpp
@@ -43,11 +43,11 @@ void SetGlobalStackTraceFormat() {
using namespace __radsan;
void __radsan::PrintStackTrace() {
- BufferedStackTrace Stack{};
+ BufferedStackTrace stack{};
GET_CURRENT_PC_BP;
- Stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_fatal);
+ stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_fatal);
SetGlobalStackTraceFormat();
- Stack.Print();
+ stack.Print();
}
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp
index 69d788b37ba01..1c098fcabd2ad 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp
@@ -13,58 +13,58 @@
#include "radsan_context.h"
-TEST(TestRadsanContext, CanCreateContext) { __radsan::Context Context{}; }
+TEST(TestRadsanContext, CanCreateContext) { __radsan::Context context{}; }
TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieBeforeRealtimePush) {
- __radsan::Context Context{};
- Context.ExpectNotRealtime("do_some_stuff");
+ __radsan::Context context{};
+ context.ExpectNotRealtime("do_some_stuff");
}
TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieAfterPushAndPop) {
- __radsan::Context Context{};
- Context.RealtimePush();
- Context.RealtimePop();
- Context.ExpectNotRealtime("do_some_stuff");
+ __radsan::Context context{};
+ context.RealtimePush();
+ context.RealtimePop();
+ context.ExpectNotRealtime("do_some_stuff");
}
TEST(TestRadsanContext, ExpectNotRealtimeDiesAfterRealtimePush) {
- __radsan::Context Context{};
+ __radsan::Context context{};
- Context.RealtimePush();
- EXPECT_DEATH(Context.ExpectNotRealtime("do_some_stuff"), "");
+ context.RealtimePush();
+ EXPECT_DEATH(context.ExpectNotRealtime("do_some_stuff"), "");
}
TEST(TestRadsanContext,
ExpectNotRealtimeDiesAfterRealtimeAfterMorePushesThanPops) {
- __radsan::Context Context{};
+ __radsan::Context context{};
- Context.RealtimePush();
- Context.RealtimePush();
- Context.RealtimePush();
- Context.RealtimePop();
- Context.RealtimePop();
- EXPECT_DEATH(Context.ExpectNotRealtime("do_some_stuff"), "");
+ context.RealtimePush();
+ context.RealtimePush();
+ context.RealtimePush();
+ context.RealtimePop();
+ context.RealtimePop();
+ EXPECT_DEATH(context.ExpectNotRealtime("do_some_stuff"), "");
}
TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieAfterBypassPush) {
- __radsan::Context Context{};
+ __radsan::Context context{};
- Context.RealtimePush();
- Context.BypassPush();
- Context.ExpectNotRealtime("do_some_stuff");
+ context.RealtimePush();
+ context.BypassPush();
+ context.ExpectNotRealtime("do_some_stuff");
}
TEST(TestRadsanContext,
ExpectNotRealtimeDoesNotDieIfBypassDepthIsGreaterThanZero) {
- __radsan::Context Context{};
+ __radsan::Context context{};
- Context.RealtimePush();
- Context.BypassPush();
- Context.BypassPush();
- Context.BypassPush();
- Context.BypassPop();
- Context.BypassPop();
- Context.ExpectNotRealtime("do_some_stuff");
- Context.BypassPop();
- EXPECT_DEATH(Context.ExpectNotRealtime("do_some_stuff"), "");
+ context.RealtimePush();
+ context.BypassPush();
+ context.BypassPush();
+ context.BypassPush();
+ context.BypassPop();
+ context.BypassPop();
+ context.ExpectNotRealtime("do_some_stuff");
+ context.BypassPop();
+ EXPECT_DEATH(context.ExpectNotRealtime("do_some_stuff"), "");
}
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp b/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp
index c4bcb9952df2a..2b314043c320a 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp
@@ -41,21 +41,21 @@ using namespace radsan_testing;
using namespace std::chrono_literals;
TEST(TestRadsan, VectorPushBackAllocationDiesWhenRealtime) {
- std::vector<float> Vec{};
- auto Func = [&Vec]() { Vec.push_back(0.4f); };
+ std::vector<float> vec{};
+ auto Func = [&vec]() { vec.push_back(0.4f); };
ExpectRealtimeDeath(Func);
- ASSERT_EQ(0u, Vec.size());
+ ASSERT_EQ(0u, vec.size());
ExpectNonRealtimeSurvival(Func);
- ASSERT_EQ(1u, Vec.size());
+ ASSERT_EQ(1u, vec.size());
}
TEST(TestRadsan, DestructionOfObjectOnHeapDiesWhenRealtime) {
- auto AllocatedPtr = std::make_unique<std::array<float, 256>>();
- auto Func = [&AllocatedPtr]() { AllocatedPtr.reset(); };
+ auto allocated_ptr = std::make_unique<std::array<float, 256>>();
+ auto Func = [&allocated_ptr]() { allocated_ptr.reset(); };
ExpectRealtimeDeath(Func);
- ASSERT_NE(nullptr, AllocatedPtr.get());
+ ASSERT_NE(nullptr, allocated_ptr.get());
ExpectNonRealtimeSurvival(Func);
- ASSERT_EQ(nullptr, AllocatedPtr.get());
+ ASSERT_EQ(nullptr, allocated_ptr.get());
}
TEST(TestRadsan, SleepingAThreadDiesWhenRealtime) {
@@ -79,16 +79,16 @@ TEST(TestRadsan, OfstreamCreationDiesWhenRealtime) {
}
TEST(TestRadsan, LockingAMutexDiesWhenRealtime) {
- std::mutex Mutex{};
- auto Func = [&]() { Mutex.lock(); };
+ std::mutex mutex{};
+ auto Func = [&]() { mutex.lock(); };
ExpectRealtimeDeath(Func);
ExpectNonRealtimeSurvival(Func);
}
TEST(TestRadsan, UnlockingAMutexDiesWhenRealtime) {
- std::mutex Mutex{};
- Mutex.lock();
- auto Func = [&]() { Mutex.unlock(); };
+ std::mutex mutex{};
+ mutex.lock();
+ auto Func = [&]() { mutex.unlock(); };
ExpectRealtimeDeath(Func);
ExpectNonRealtimeSurvival(Func);
}
@@ -96,31 +96,31 @@ TEST(TestRadsan, UnlockingAMutexDiesWhenRealtime) {
#if RADSAN_TEST_SHARED_MUTEX
TEST(TestRadsan, LockingASharedMutexDiesWhenRealtime) {
- std::shared_mutex Mutex{};
- auto Func = [&]() { Mutex.lock(); };
+ std::shared_mutex mutex{};
+ auto Func = [&]() { mutex.lock(); };
ExpectRealtimeDeath(Func);
ExpectNonRealtimeSurvival(Func);
}
TEST(TestRadsan, UnlockingASharedMutexDiesWhenRealtime) {
- std::shared_mutex Mutex{};
- Mutex.lock();
- auto Func = [&]() { Mutex.unlock(); };
+ std::shared_mutex mutex{};
+ mutex.lock();
+ auto Func = [&]() { mutex.unlock(); };
ExpectRealtimeDeath(Func);
ExpectNonRealtimeSurvival(Func);
}
TEST(TestRadsan, SharedLockingASharedMutexDiesWhenRealtime) {
- std::shared_mutex Mutex{};
- auto Func = [&]() { Mutex.lock_shared(); };
+ std::shared_mutex mutex{};
+ auto Func = [&]() { mutex.lock_shared(); };
ExpectRealtimeDeath(Func);
ExpectNonRealtimeSurvival(Func);
}
TEST(TestRadsan, SharedUnlockingASharedMutexDiesWhenRealtime) {
- std::shared_mutex Mutex{};
- Mutex.lock_shared();
- auto Func = [&]() { Mutex.unlock_shared(); };
+ std::shared_mutex mutex{};
+ mutex.lock_shared();
+ auto Func = [&]() { mutex.unlock_shared(); };
ExpectRealtimeDeath(Func);
ExpectNonRealtimeSurvival(Func);
}
@@ -141,12 +141,12 @@ void InvokeStdFunction(std::function<void()> &&function) { function(); }
} // namespace
TEST(TestRadsan, CopyingALambdaWithLargeCaptureDiesWhenRealtime) {
- std::array<float, 16> LotsOfData{};
- auto lambda = [LotsOfData]() mutable {
+ std::array<float, 16> lots_of_data{};
+ auto lambda = [lots_of_data]() mutable {
// Stop everything getting optimised out
- LotsOfData[3] = 0.25f;
- EXPECT_EQ(16, LotsOfData.size());
- EXPECT_EQ(0.25f, LotsOfData[3]);
+ lots_of_data[3] = 0.25f;
+ EXPECT_EQ(16, lots_of_data.size());
+ EXPECT_EQ(0.25f, lots_of_data[3]);
};
auto Func = [&]() { InvokeStdFunction(lambda); };
ExpectRealtimeDeath(Func);
@@ -154,13 +154,13 @@ TEST(TestRadsan, CopyingALambdaWithLargeCaptureDiesWhenRealtime) {
}
TEST(TestRadsan, AccessingALargeAtomicVariableDiesWhenRealtime) {
- std::atomic<float> SmallAtomic{0.0f};
- ASSERT_TRUE(SmallAtomic.is_lock_free());
- RealtimeInvoke([&SmallAtomic]() { float x = SmallAtomic.load(); });
+ std::atomic<float> small_atomic{0.0f};
+ ASSERT_TRUE(small_atomic.is_lock_free());
+ RealtimeInvoke([&small_atomic]() { float x = small_atomic.load(); });
- std::atomic<std::array<float, 2048>> LargeAtomic{};
- ASSERT_FALSE(LargeAtomic.is_lock_free());
- auto Func = [&]() { auto x = LargeAtomic.load(); };
+ std::atomic<std::array<float, 2048>> large_atomic{};
+ ASSERT_FALSE(large_atomic.is_lock_free());
+ auto Func = [&]() { auto x = large_atomic.load(); };
ExpectRealtimeDeath(Func);
ExpectNonRealtimeSurvival(Func);
}
@@ -196,11 +196,11 @@ TEST(TestRadsan, ThrowingAnExceptionDiesWhenRealtime) {
}
TEST(TestRadsan, DoesNotDieIfTurnedOff) {
- std::mutex Mutex{};
+ std::mutex mutex{};
auto RealtimeUnsafeFunc = [&]() {
__radsan_off();
- Mutex.lock();
- Mutex.unlock();
+ mutex.lock();
+ mutex.unlock();
__radsan_on();
};
RealtimeInvoke(RealtimeUnsafeFunc);
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
index e3b2e34fbe48a..182cdef071a30 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
@@ -116,8 +116,8 @@ TEST(TestRadsanInterceptors, FreeSurvivesWhenRealtimeIfArgumentIsNull) {
TEST(TestRadsanInterceptors, PosixMemalignDiesWhenRealtime) {
auto Func = []() {
- void *Mem;
- posix_memalign(&Mem, 4, 4);
+ void *ptr;
+ posix_memalign(&ptr, 4, 4);
};
ExpectRealtimeDeath(Func, "posix_memalign");
ExpectNonRealtimeSurvival(Func);
@@ -203,8 +203,8 @@ TEST(TestRadsanInterceptors, CloseDiesWhenRealtime) {
TEST(TestRadsanInterceptors, FopenDiesWhenRealtime) {
auto Func = []() {
- FILE *Fd = fopen(TemporaryFilePath(), "w");
- EXPECT_THAT(Fd, Ne(nullptr));
+ FILE *fd = fopen(TemporaryFilePath(), "w");
+ EXPECT_THAT(fd, Ne(nullptr));
};
ExpectRealtimeDeath(Func, "fopen");
ExpectNonRealtimeSurvival(Func);
@@ -212,32 +212,32 @@ TEST(TestRadsanInterceptors, FopenDiesWhenRealtime) {
}
TEST(TestRadsanInterceptors, FreadDiesWhenRealtime) {
- FILE *Fd = fopen(TemporaryFilePath(), "w");
- auto Func = [Fd]() {
+ FILE *fd = fopen(TemporaryFilePath(), "w");
+ auto Func = [fd]() {
char c{};
- fread(&c, 1, 1, Fd);
+ fread(&c, 1, 1, fd);
};
ExpectRealtimeDeath(Func, "fread");
ExpectNonRealtimeSurvival(Func);
- if (Fd != nullptr)
- fclose(Fd);
+ if (fd != nullptr)
+ fclose(fd);
std::remove(TemporaryFilePath());
}
TEST(TestRadsanInterceptors, FwriteDiesWhenRealtime) {
- FILE *Fd = fopen(TemporaryFilePath(), "w");
- ASSERT_NE(nullptr, Fd);
- const char *Message = "Hello, world!";
- auto Func = [&]() { fwrite(&Message, 1, 4, Fd); };
+ FILE *fd = fopen(TemporaryFilePath(), "w");
+ ASSERT_NE(nullptr, fd);
+ const char *message = "Hello, world!";
+ auto Func = [&]() { fwrite(&message, 1, 4, fd); };
ExpectRealtimeDeath(Func, "fwrite");
ExpectNonRealtimeSurvival(Func);
std::remove(TemporaryFilePath());
}
TEST(TestRadsanInterceptors, FcloseDiesWhenRealtime) {
- FILE *Fd = fopen(TemporaryFilePath(), "w");
- EXPECT_THAT(Fd, Ne(nullptr));
- auto Func = [Fd]() { fclose(Fd); };
+ FILE *fd = fopen(TemporaryFilePath(), "w");
+ EXPECT_THAT(fd, Ne(nullptr));
+ auto Func = [fd]() { fclose(fd); };
ExpectRealtimeDeath(Func, "fclose");
ExpectNonRealtimeSurvival(Func);
std::remove(TemporaryFilePath());
@@ -250,13 +250,13 @@ TEST(TestRadsanInterceptors, PutsDiesWhenRealtime) {
}
TEST(TestRadsanInterceptors, FputsDiesWhenRealtime) {
- FILE *Fd = fopen(TemporaryFilePath(), "w");
- ASSERT_THAT(Fd, Ne(nullptr)) << errno;
- auto Func = [Fd]() { fputs("Hello, world!\n", Fd); };
+ FILE *fd = fopen(TemporaryFilePath(), "w");
+ ASSERT_THAT(fd, Ne(nullptr)) << errno;
+ auto Func = [fd]() { fputs("Hello, world!\n", fd); };
ExpectRealtimeDeath(Func);
ExpectNonRealtimeSurvival(Func);
- if (Fd != nullptr)
- fclose(Fd);
+ if (fd != nullptr)
+ fclose(fd);
std::remove(TemporaryFilePath());
}
@@ -266,10 +266,10 @@ TEST(TestRadsanInterceptors, FputsDiesWhenRealtime) {
TEST(TestRadsanInterceptors, PthreadCreateDiesWhenRealtime) {
auto Func = []() {
- pthread_t Thread{};
- const pthread_attr_t Attr{};
- struct thread_info *ThreadInfo;
- pthread_create(&Thread, &Attr, &FakeThreadEntryPoint, ThreadInfo);
+ pthread_t thread{};
+ const pthread_attr_t attr{};
+ struct thread_info *thread_info;
+ pthread_create(&thread, &attr, &FakeThreadEntryPoint, thread_info);
};
ExpectRealtimeDeath(Func, "pthread_create");
ExpectNonRealtimeSurvival(Func);
@@ -277,8 +277,8 @@ TEST(TestRadsanInterceptors, PthreadCreateDiesWhenRealtime) {
TEST(TestRadsanInterceptors, PthreadMutexLockDiesWhenRealtime) {
auto Func = []() {
- pthread_mutex_t Mutex{};
- pthread_mutex_lock(&Mutex);
+ pthread_mutex_t mutex{};
+ pthread_mutex_lock(&mutex);
};
ExpectRealtimeDeath(Func, "pthread_mutex_lock");
@@ -287,8 +287,8 @@ TEST(TestRadsanInterceptors, PthreadMutexLockDiesWhenRealtime) {
TEST(TestRadsanInterceptors, PthreadMutexUnlockDiesWhenRealtime) {
auto Func = []() {
- pthread_mutex_t Mutex{};
- pthread_mutex_unlock(&Mutex);
+ pthread_mutex_t mutex{};
+ pthread_mutex_unlock(&mutex);
};
ExpectRealtimeDeath(Func, "pthread_mutex_unlock");
@@ -297,8 +297,8 @@ TEST(TestRadsanInterceptors, PthreadMutexUnlockDiesWhenRealtime) {
TEST(TestRadsanInterceptors, PthreadMutexJoinDiesWhenRealtime) {
auto Func = []() {
- pthread_t Thread{};
- pthread_join(Thread, nullptr);
+ pthread_t thread{};
+ pthread_join(thread, nullptr);
};
ExpectRealtimeDeath(Func, "pthread_join");
@@ -312,8 +312,8 @@ TEST(TestRadsanInterceptors, PthreadMutexJoinDiesWhenRealtime) {
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
TEST(TestRadsanInterceptors, OsSpinLockLockDiesWhenRealtime) {
auto Func = []() {
- OSSpinLock SpinLock{};
- OSSpinLockLock(&SpinLock);
+ OSSpinLock spin_lock{};
+ OSSpinLockLock(&spin_lock);
};
ExpectRealtimeDeath(Func, "OSSpinLockLock");
ExpectNonRealtimeSurvival(Func);
@@ -322,8 +322,8 @@ TEST(TestRadsanInterceptors, OsSpinLockLockDiesWhenRealtime) {
TEST(TestRadsanInterceptors, OsUnfairLockLockDiesWhenRealtime) {
auto Func = []() {
- os_unfair_lock_s UnfairLock{};
- os_unfair_lock_lock(&UnfairLock);
+ os_unfair_lock_s unfair_lock{};
+ os_unfair_lock_lock(&unfair_lock);
};
ExpectRealtimeDeath(Func, "os_unfair_lock_lock");
ExpectNonRealtimeSurvival(Func);
@@ -332,9 +332,9 @@ TEST(TestRadsanInterceptors, OsUnfairLockLockDiesWhenRealtime) {
#if SANITIZER_LINUX
TEST(TestRadsanInterceptors, SpinLockLockDiesWhenRealtime) {
- pthread_spinlock_t SpinLock;
- pthread_spin_init(&SpinLock, PTHREAD_PROCESS_SHARED);
- auto Func = [&]() { pthread_spin_lock(&SpinLock); };
+ pthread_spinlock_t spin_lock;
+ pthread_spin_init(&spin_lock, PTHREAD_PROCESS_SHARED);
+ auto Func = [&]() { pthread_spin_lock(&spin_lock); };
ExpectRealtimeDeath(Func, "pthread_spin_lock");
ExpectNonRealtimeSurvival(Func);
}
@@ -342,8 +342,8 @@ TEST(TestRadsanInterceptors, SpinLockLockDiesWhenRealtime) {
TEST(TestRadsanInterceptors, PthreadCondSignalDiesWhenRealtime) {
auto Func = []() {
- pthread_cond_t Cond{};
- pthread_cond_signal(&Cond);
+ pthread_cond_t cond{};
+ pthread_cond_signal(&cond);
};
ExpectRealtimeDeath(Func, "pthread_cond_signal");
ExpectNonRealtimeSurvival(Func);
@@ -351,19 +351,19 @@ TEST(TestRadsanInterceptors, PthreadCondSignalDiesWhenRealtime) {
TEST(TestRadsanInterceptors, PthreadCondBroadcastDiesWhenRealtime) {
auto Func = []() {
- pthread_cond_t Cond;
- pthread_cond_broadcast(&Cond);
+ pthread_cond_t cond;
+ pthread_cond_broadcast(&cond);
};
ExpectRealtimeDeath(Func, "pthread_cond_broadcast");
ExpectNonRealtimeSurvival(Func);
}
TEST(TestRadsanInterceptors, PthreadCondWaitDiesWhenRealtime) {
- pthread_cond_t Cond;
- pthread_mutex_t Mutex;
- ASSERT_EQ(0, pthread_cond_init(&Cond, nullptr));
- ASSERT_EQ(0, pthread_mutex_init(&Mutex, nullptr));
- auto Func = [&]() { pthread_cond_wait(&Cond, &Mutex); };
+ pthread_cond_t cond;
+ pthread_mutex_t mutex;
+ ASSERT_EQ(0, pthread_cond_init(&cond, nullptr));
+ ASSERT_EQ(0, pthread_mutex_init(&mutex, nullptr));
+ auto Func = [&]() { pthread_cond_wait(&cond, &mutex); };
ExpectRealtimeDeath(Func, "pthread_cond_wait");
// It's very difficult to test the success case here without doing some
// sleeping, which is at the mercy of the scheduler. What's really important
@@ -372,8 +372,8 @@ TEST(TestRadsanInterceptors, PthreadCondWaitDiesWhenRealtime) {
TEST(TestRadsanInterceptors, PthreadRwlockRdlockDiesWhenRealtime) {
auto Func = []() {
- pthread_rwlock_t RwLock;
- pthread_rwlock_rdlock(&RwLock);
+ pthread_rwlock_t rw_lock;
+ pthread_rwlock_rdlock(&rw_lock);
};
ExpectRealtimeDeath(Func, "pthread_rwlock_rdlock");
ExpectNonRealtimeSurvival(Func);
@@ -381,8 +381,8 @@ TEST(TestRadsanInterceptors, PthreadRwlockRdlockDiesWhenRealtime) {
TEST(TestRadsanInterceptors, PthreadRwlockUnlockDiesWhenRealtime) {
auto Func = []() {
- pthread_rwlock_t RwLock;
- pthread_rwlock_unlock(&RwLock);
+ pthread_rwlock_t rw_lock;
+ pthread_rwlock_unlock(&rw_lock);
};
ExpectRealtimeDeath(Func, "pthread_rwlock_unlock");
ExpectNonRealtimeSurvival(Func);
@@ -390,8 +390,8 @@ TEST(TestRadsanInterceptors, PthreadRwlockUnlockDiesWhenRealtime) {
TEST(TestRadsanInterceptors, PthreadRwlockWrlockDiesWhenRealtime) {
auto Func = []() {
- pthread_rwlock_t RwLock;
- pthread_rwlock_wrlock(&RwLock);
+ pthread_rwlock_t rw_lock;
+ pthread_rwlock_wrlock(&rw_lock);
};
ExpectRealtimeDeath(Func, "pthread_rwlock_wrlock");
ExpectNonRealtimeSurvival(Func);
@@ -413,16 +413,16 @@ TEST(TestRadsanInterceptors, SendToASocketDiesWhenRealtime) {
}
TEST(TestRadsanInterceptors, SendmsgToASocketDiesWhenRealtime) {
- msghdr Msg{};
- auto Func = [&]() { sendmsg(0, &Msg, 0); };
+ msghdr msg{};
+ auto Func = [&]() { sendmsg(0, &msg, 0); };
ExpectRealtimeDeath(Func, "sendmsg");
ExpectNonRealtimeSurvival(Func);
}
TEST(TestRadsanInterceptors, SendtoToASocketDiesWhenRealtime) {
- sockaddr Addr{};
- socklen_t Len{};
- auto Func = [&]() { sendto(0, nullptr, 0, 0, &Addr, Len); };
+ sockaddr addr{};
+ socklen_t len{};
+ auto Func = [&]() { sendto(0, nullptr, 0, 0, &addr, len); };
ExpectRealtimeDeath(Func, "sendto");
ExpectNonRealtimeSurvival(Func);
}
@@ -434,16 +434,16 @@ TEST(TestRadsanInterceptors, RecvFromASocketDiesWhenRealtime) {
}
TEST(TestRadsanInterceptors, RecvfromOnASocketDiesWhenRealtime) {
- sockaddr Addr{};
- socklen_t Len{};
- auto Func = [&]() { recvfrom(0, nullptr, 0, 0, &Addr, &Len); };
+ sockaddr addr{};
+ socklen_t len{};
+ auto Func = [&]() { recvfrom(0, nullptr, 0, 0, &addr, &len); };
ExpectRealtimeDeath(Func, "recvfrom");
ExpectNonRealtimeSurvival(Func);
}
TEST(TestRadsanInterceptors, RecvmsgOnASocketDiesWhenRealtime) {
- msghdr Msg{};
- auto Func = [&]() { recvmsg(0, &Msg, 0); };
+ msghdr msg{};
+ auto Func = [&]() { recvmsg(0, &msg, 0); };
ExpectRealtimeDeath(Func, "recvmsg");
ExpectNonRealtimeSurvival(Func);
}
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h b/compiler-rt/lib/radsan/tests/radsan_test_utilities.h
index 950c018aff304..1d1c404a1373b 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h
+++ b/compiler-rt/lib/radsan/tests/radsan_test_utilities.h
@@ -29,7 +29,7 @@ void ExpectRealtimeDeath(Function &&Func,
using namespace testing;
- auto ExpectedErrorSubstring = [&]() -> std::string {
+ auto GetExpectedErrorSubstring = [&]() -> std::string {
return intercepted_method_name != nullptr
? "Real-time violation: intercepted call to real-time unsafe "
"function `" +
@@ -38,7 +38,7 @@ void ExpectRealtimeDeath(Function &&Func,
};
EXPECT_EXIT(RealtimeInvoke(std::forward<Function>(Func)),
- ExitedWithCode(EXIT_FAILURE), ExpectedErrorSubstring());
+ ExitedWithCode(EXIT_FAILURE), GetExpectedErrorSubstring());
}
template <typename Function> void ExpectNonRealtimeSurvival(Function &&Func) {
>From 0e5ea5415ae3451f8c15dfb53bc06c3087d6febc Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Mon, 20 May 2024 09:08:50 -0700
Subject: [PATCH 24/33] PR: Fix style nit
---
clang/lib/Driver/ToolChains/CommonArgs.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 7f5ab360f2458..d8cd21a9df4df 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1382,9 +1382,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
StaticRuntimes.push_back("asan_cxx");
}
- if (!SanArgs.needsSharedRt() && SanArgs.needsRadsanRt()) {
+ if (!SanArgs.needsSharedRt() && SanArgs.needsRadsanRt())
StaticRuntimes.push_back("radsan");
- }
if (!SanArgs.needsSharedRt() && SanArgs.needsMemProfRt()) {
StaticRuntimes.push_back("memprof");
>From 21836c08cf67f0bd2fb91eac29544991fbf7262e Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Mon, 20 May 2024 09:10:17 -0700
Subject: [PATCH 25/33] PR: Fix small style fallout
---
clang/lib/Driver/ToolChains/CommonArgs.cpp | 2 +-
compiler-rt/lib/radsan/radsan_interceptors.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index d8cd21a9df4df..8c22e0f2b6eeb 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1382,7 +1382,7 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
StaticRuntimes.push_back("asan_cxx");
}
- if (!SanArgs.needsSharedRt() && SanArgs.needsRadsanRt())
+ if (!SanArgs.needsSharedRt() && SanArgs.needsRadsanRt())
StaticRuntimes.push_back("radsan");
if (!SanArgs.needsSharedRt() && SanArgs.needsMemProfRt()) {
diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/radsan/radsan_interceptors.cpp
index b157b9d25bdb1..87b16aa47bd3d 100644
--- a/compiler-rt/lib/radsan/radsan_interceptors.cpp
+++ b/compiler-rt/lib/radsan/radsan_interceptors.cpp
@@ -125,7 +125,7 @@ INTERCEPTOR(int, puts, const char *s) {
return REAL(puts)(s);
}
- // Concurrency
+// Concurrency
#if SANITIZER_APPLE
#pragma clang diagnostic push
// OSSpinLockLock is deprecated, but still in use in libc++
>From 8a1a7a8ecbd1a39c37214d52fef12e1caae72989 Mon Sep 17 00:00:00 2001
From: David Trevelyan <david.trevelyan at gmail.com>
Date: Tue, 21 May 2024 09:22:04 +0100
Subject: [PATCH 26/33] Update comment and TU-local function style
---
compiler-rt/lib/radsan/radsan.h | 36 ++++++++-------------
compiler-rt/lib/radsan/radsan_context.cpp | 39 +++++++++--------------
compiler-rt/lib/radsan/radsan_stack.cpp | 5 +--
3 files changed, 29 insertions(+), 51 deletions(-)
diff --git a/compiler-rt/lib/radsan/radsan.h b/compiler-rt/lib/radsan/radsan.h
index 3f2df5ef05dff..e4a897e831d76 100644
--- a/compiler-rt/lib/radsan/radsan.h
+++ b/compiler-rt/lib/radsan/radsan.h
@@ -14,37 +14,27 @@
extern "C" {
-/** Initialise radsan interceptors.
-
- A call to this method is added to the preinit array on Linux systems.
-*/
+// Initialise radsan interceptors.
+// A call to this method is added to the preinit array on Linux systems.
SANITIZER_INTERFACE_ATTRIBUTE void __radsan_init();
-/** Enter real-time context.
-
- When in a real-time context, RADSan interceptors will error if realtime
- violations are detected. Calls to this method are injected at the code
- generation stage when RADSan is enabled.
-*/
+// Enter real-time context.
+// When in a real-time context, RADSan interceptors will error if realtime
+// violations are detected. Calls to this method are injected at the code
+// generation stage when RADSan is enabled.
SANITIZER_INTERFACE_ATTRIBUTE void __radsan_realtime_enter();
-/** Exit the real-time context.
-
- When not in a real-time context, RADSan interceptors will simply forward
- intercepted method calls to the real methods.
-*/
+// Exit the real-time context.
+// When not in a real-time context, RADSan interceptors will simply forward
+// intercepted method calls to the real methods.
SANITIZER_INTERFACE_ATTRIBUTE void __radsan_realtime_exit();
-/** Disable all RADSan error reporting.
-
- Injected into the code if "nosanitize(realtime)" is on a function.
-*/
+// Disable all RADSan error reporting.
+// Injected into the code if "nosanitize(realtime)" is on a function.
SANITIZER_INTERFACE_ATTRIBUTE void __radsan_off();
-/** Re-enable all RADSan error reporting.
-
- The counterpart to `__radsan_off`.
-*/
+// Re-enable all RADSan error reporting.
+// The counterpart to `__radsan_off`.
SANITIZER_INTERFACE_ATTRIBUTE void __radsan_on();
} // extern "C"
diff --git a/compiler-rt/lib/radsan/radsan_context.cpp b/compiler-rt/lib/radsan/radsan_context.cpp
index 344dfb6bdcdd1..2d43061c15bfe 100644
--- a/compiler-rt/lib/radsan/radsan_context.cpp
+++ b/compiler-rt/lib/radsan/radsan_context.cpp
@@ -20,29 +20,24 @@
#include <stdio.h>
#include <stdlib.h>
-using namespace __sanitizer;
-
-namespace detail {
-
-static pthread_key_t key;
+static pthread_key_t context_key;
static pthread_once_t key_once = PTHREAD_ONCE_INIT;
-void internalFree(void *ptr) { __sanitizer::InternalFree(ptr); }
-using __radsan::Context;
+static void internalFree(void *ptr) { __sanitizer::InternalFree(ptr); }
-Context &GetContextForThisThreadImpl() {
- auto make_tls_key = []() {
- CHECK_EQ(pthread_key_create(&detail::key, detail::internalFree), 0);
+static __radsan::Context &GetContextForThisThreadImpl() {
+ auto make_thread_local_context_key = []() {
+ CHECK_EQ(pthread_key_create(&context_key, internalFree), 0);
};
- pthread_once(&detail::key_once, make_tls_key);
- Context *current_thread_context =
- static_cast<Context *>(pthread_getspecific(detail::key));
+ pthread_once(&key_once, make_thread_local_context_key);
+ __radsan::Context *current_thread_context =
+ static_cast<__radsan::Context *>(pthread_getspecific(context_key));
if (current_thread_context == nullptr) {
- current_thread_context =
- static_cast<Context *>(InternalAlloc(sizeof(Context)));
- new (current_thread_context) Context();
- pthread_setspecific(detail::key, current_thread_context);
+ current_thread_context = static_cast<__radsan::Context *>(
+ __sanitizer::InternalAlloc(sizeof(__radsan::Context)));
+ new (current_thread_context) __radsan::Context();
+ pthread_setspecific(context_key, current_thread_context);
}
return *current_thread_context;
@@ -62,9 +57,7 @@ Context &GetContextForThisThreadImpl() {
Until then, and to keep the first PRs small, only the exit mode
is available.
*/
-void InvokeViolationDetectedAction() { exit(EXIT_FAILURE); }
-
-} // namespace detail
+static void InvokeViolationDetectedAction() { exit(EXIT_FAILURE); }
namespace __radsan {
@@ -82,7 +75,7 @@ void Context::ExpectNotRealtime(const char *intercepted_function_name) {
if (InRealtimeContext() && !IsBypassed()) {
BypassPush();
PrintDiagnostics(intercepted_function_name);
- detail::InvokeViolationDetectedAction();
+ InvokeViolationDetectedAction();
BypassPop();
}
}
@@ -99,8 +92,6 @@ void Context::PrintDiagnostics(const char *intercepted_function_name) {
__radsan::PrintStackTrace();
}
-Context &GetContextForThisThread() {
- return detail::GetContextForThisThreadImpl();
-}
+Context &GetContextForThisThread() { return GetContextForThisThreadImpl(); }
} // namespace __radsan
diff --git a/compiler-rt/lib/radsan/radsan_stack.cpp b/compiler-rt/lib/radsan/radsan_stack.cpp
index 1ba56a7068343..d00db6068132f 100644
--- a/compiler-rt/lib/radsan/radsan_stack.cpp
+++ b/compiler-rt/lib/radsan/radsan_stack.cpp
@@ -17,7 +17,6 @@ using namespace __sanitizer;
// We must define our own implementation of this method for our runtime.
// This one is just copied from UBSan.
-
namespace __sanitizer {
void BufferedStackTrace::UnwindImpl(uptr pc, uptr bp, void *context,
bool request_fast, u32 max_depth) {
@@ -29,8 +28,7 @@ void BufferedStackTrace::UnwindImpl(uptr pc, uptr bp, void *context,
}
} // namespace __sanitizer
-namespace __radsan {
-void SetGlobalStackTraceFormat() {
+static void SetGlobalStackTraceFormat() {
SetCommonFlagsDefaults();
CommonFlags cf;
cf.CopyFrom(*common_flags());
@@ -38,7 +36,6 @@ void SetGlobalStackTraceFormat() {
cf.external_symbolizer_path = GetEnv("RADSAN_SYMBOLIZER_PATH");
OverrideCommonFlags(cf);
}
-} // namespace __radsan
using namespace __radsan;
void __radsan::PrintStackTrace() {
>From 64df9c51f23e8cb97cfdbe0ad66acfef6ac1af66 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Tue, 21 May 2024 13:46:02 -0700
Subject: [PATCH 27/33] PR: Remove too early inclusion of sanitizer common lit
tests
---
compiler-rt/test/sanitizer_common/CMakeLists.txt | 2 +-
compiler-rt/test/sanitizer_common/lit.common.cfg.py | 3 ---
2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/compiler-rt/test/sanitizer_common/CMakeLists.txt b/compiler-rt/test/sanitizer_common/CMakeLists.txt
index bdf839b348e25..f2df8cec3549b 100644
--- a/compiler-rt/test/sanitizer_common/CMakeLists.txt
+++ b/compiler-rt/test/sanitizer_common/CMakeLists.txt
@@ -7,7 +7,7 @@ set(SANITIZER_COMMON_TESTSUITES)
# FIXME(dliew): We should switch to COMPILER_RT_SANITIZERS_TO_BUILD instead of
# the hard coded `SUPPORTED_TOOLS_INIT` list once we know that the other
# sanitizers work.
-set(SUPPORTED_TOOLS_INIT asan lsan hwasan msan radsan tsan ubsan)
+set(SUPPORTED_TOOLS_INIT asan lsan hwasan msan tsan ubsan)
set(SUPPORTED_TOOLS)
foreach(SANITIZER_TOOL ${SUPPORTED_TOOLS_INIT})
string(TOUPPER ${SANITIZER_TOOL} SANITIZER_TOOL_UPPER)
diff --git a/compiler-rt/test/sanitizer_common/lit.common.cfg.py b/compiler-rt/test/sanitizer_common/lit.common.cfg.py
index 80c7372372f44..04af4816eb6e7 100644
--- a/compiler-rt/test/sanitizer_common/lit.common.cfg.py
+++ b/compiler-rt/test/sanitizer_common/lit.common.cfg.py
@@ -18,9 +18,6 @@
tool_options = "HWASAN_OPTIONS"
if not config.has_lld:
config.unsupported = True
-elif config.tool_name == "radsan":
- tool_cflags = ["-fsanitize=realtime"]
- tool_options = "RADSAN_OPTIONS"
elif config.tool_name == "tsan":
tool_cflags = ["-fsanitize=thread"]
tool_options = "TSAN_OPTIONS"
>From 167349a2f6461970b6b4056234ec0b089778cc9b Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Thu, 30 May 2024 09:46:19 -0700
Subject: [PATCH 28/33] Test failure: fix initialization of pthread_cond_t
---
compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
index 182cdef071a30..52f3381be226b 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
@@ -350,12 +350,16 @@ TEST(TestRadsanInterceptors, PthreadCondSignalDiesWhenRealtime) {
}
TEST(TestRadsanInterceptors, PthreadCondBroadcastDiesWhenRealtime) {
+ pthread_cond_t cond;
+ pthread_cond_init(&cond, NULL);
auto Func = []() {
pthread_cond_t cond;
pthread_cond_broadcast(&cond);
};
ExpectRealtimeDeath(Func, "pthread_cond_broadcast");
ExpectNonRealtimeSurvival(Func);
+
+ pthread_cond_destroy(&cond);
}
TEST(TestRadsanInterceptors, PthreadCondWaitDiesWhenRealtime) {
>From 0b60190c838a1fb0fb098ab3795731fcc38ddfe9 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Thu, 30 May 2024 12:01:58 -0700
Subject: [PATCH 29/33] Test failure: Try again with initialization of
pthread_cond_t
---
compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
index 52f3381be226b..5d88c3a99f2bd 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
@@ -350,10 +350,9 @@ TEST(TestRadsanInterceptors, PthreadCondSignalDiesWhenRealtime) {
}
TEST(TestRadsanInterceptors, PthreadCondBroadcastDiesWhenRealtime) {
- pthread_cond_t cond;
+ pthread_cond_t cond{};
pthread_cond_init(&cond, NULL);
- auto Func = []() {
- pthread_cond_t cond;
+ auto Func = [&cond]() {
pthread_cond_broadcast(&cond);
};
ExpectRealtimeDeath(Func, "pthread_cond_broadcast");
>From 615b65f85a16f57c300b094d27fc0c4dc24e4638 Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Thu, 30 May 2024 15:26:16 -0700
Subject: [PATCH 30/33] Fix code formatting on unit test
---
compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
index 5d88c3a99f2bd..7c11a66adb680 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
@@ -352,9 +352,7 @@ TEST(TestRadsanInterceptors, PthreadCondSignalDiesWhenRealtime) {
TEST(TestRadsanInterceptors, PthreadCondBroadcastDiesWhenRealtime) {
pthread_cond_t cond{};
pthread_cond_init(&cond, NULL);
- auto Func = [&cond]() {
- pthread_cond_broadcast(&cond);
- };
+ auto Func = [&cond]() { pthread_cond_broadcast(&cond); };
ExpectRealtimeDeath(Func, "pthread_cond_broadcast");
ExpectNonRealtimeSurvival(Func);
>From e2a4bafcf27350253dfb222088f1bb6437838e7b Mon Sep 17 00:00:00 2001
From: Chris Apple <14171107+cjappl at users.noreply.github.com>
Date: Thu, 30 May 2024 16:36:50 -0700
Subject: [PATCH 31/33] Ensure all pthread_cond_t are initialized in unit tests
---
.../lib/radsan/tests/radsan_test_interceptors.cpp | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
index 7c11a66adb680..0841cf95e6540 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
@@ -341,17 +341,20 @@ TEST(TestRadsanInterceptors, SpinLockLockDiesWhenRealtime) {
#endif
TEST(TestRadsanInterceptors, PthreadCondSignalDiesWhenRealtime) {
- auto Func = []() {
- pthread_cond_t cond{};
- pthread_cond_signal(&cond);
- };
+ pthread_cond_t cond{};
+ pthread_cond_init(&cond, NULL);
+
+ auto Func = [&cond]() { pthread_cond_signal(&cond); };
ExpectRealtimeDeath(Func, "pthread_cond_signal");
ExpectNonRealtimeSurvival(Func);
+
+ pthread_cond_destroy(&cond);
}
TEST(TestRadsanInterceptors, PthreadCondBroadcastDiesWhenRealtime) {
pthread_cond_t cond{};
pthread_cond_init(&cond, NULL);
+
auto Func = [&cond]() { pthread_cond_broadcast(&cond); };
ExpectRealtimeDeath(Func, "pthread_cond_broadcast");
ExpectNonRealtimeSurvival(Func);
@@ -364,11 +367,15 @@ TEST(TestRadsanInterceptors, PthreadCondWaitDiesWhenRealtime) {
pthread_mutex_t mutex;
ASSERT_EQ(0, pthread_cond_init(&cond, nullptr));
ASSERT_EQ(0, pthread_mutex_init(&mutex, nullptr));
+
auto Func = [&]() { pthread_cond_wait(&cond, &mutex); };
ExpectRealtimeDeath(Func, "pthread_cond_wait");
// It's very difficult to test the success case here without doing some
// sleeping, which is at the mercy of the scheduler. What's really important
// here is the interception - so we're only testing that for now.
+
+ pthread_cond_destroy(&cond);
+ pthread_mutex_destroy(&mutex);
}
TEST(TestRadsanInterceptors, PthreadRwlockRdlockDiesWhenRealtime) {
>From 6fa7e25a8d32117cf997560d21a420fc287219f5 Mon Sep 17 00:00:00 2001
From: Chris Apple <cja-private at pm.me>
Date: Fri, 31 May 2024 06:34:56 -0700
Subject: [PATCH 32/33] Fix issue where CREAT flag was not properly passing
mode (#23)
* Pass on CREAT mode propertly in open interceptors
* Add unit tests
* Remove two unneccessary bits
* Fix fcntl
---
.../lib/radsan/radsan_interceptors.cpp | 16 ++++++--
.../radsan/tests/radsan_test_interceptors.cpp | 38 +++++++++++++++++++
2 files changed, 50 insertions(+), 4 deletions(-)
diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/radsan/radsan_interceptors.cpp
index 87b16aa47bd3d..53305c0393f0a 100644
--- a/compiler-rt/lib/radsan/radsan_interceptors.cpp
+++ b/compiler-rt/lib/radsan/radsan_interceptors.cpp
@@ -52,10 +52,13 @@ INTERCEPTOR(int, open, const char *path, int oflag, ...) {
// TODO Establish whether we should intercept here if the flag contains
// O_NONBLOCK
__radsan::ExpectNotRealtime("open");
+
va_list args;
va_start(args, oflag);
- const int result = REAL(open)(path, oflag, args);
+ const mode_t mode = va_arg(args, int);
va_end(args);
+
+ const int result = REAL(open)(path, oflag, mode);
return result;
}
@@ -63,10 +66,13 @@ INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) {
// TODO Establish whether we should intercept here if the flag contains
// O_NONBLOCK
__radsan::ExpectNotRealtime("openat");
+
va_list args;
va_start(args, oflag);
- const int result = REAL(openat)(fd, path, oflag, args);
+ mode_t mode = va_arg(args, int);
va_end(args);
+
+ const int result = REAL(openat)(fd, path, oflag, mode);
return result;
}
@@ -80,11 +86,13 @@ INTERCEPTOR(int, creat, const char *path, mode_t mode) {
INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) {
__radsan::ExpectNotRealtime("fcntl");
+
va_list args;
va_start(args, cmd);
- const int result = REAL(fcntl)(filedes, cmd, args);
+ void *arg = va_arg(args, void *);
va_end(args);
- return result;
+
+ return fcntl(filedes, cmd, arg);
}
INTERCEPTOR(int, close, int filedes) {
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
index 0841cf95e6540..fa74e85ad95bc 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
@@ -182,6 +182,22 @@ TEST(TestRadsanInterceptors, OpenatDiesWhenRealtime) {
std::remove(TemporaryFilePath());
}
+TEST(TestRadsanInterceptors, openCreatesFileWithProperMode) {
+ const int mode = S_IRGRP | S_IROTH | S_IRUSR | S_IWUSR;
+
+ const int fd = open(TemporaryFilePath(), O_CREAT | O_WRONLY, mode);
+ ASSERT_THAT(fd, Ne(-1));
+ close(fd);
+
+ struct stat st;
+ ASSERT_THAT(stat(TemporaryFilePath(), &st), Eq(0));
+
+ // Mask st_mode to get permission bits only
+ ASSERT_THAT(st.st_mode & 0777, Eq(mode));
+
+ std::remove(TemporaryFilePath());
+}
+
TEST(TestRadsanInterceptors, CreatDiesWhenRealtime) {
auto Func = []() { creat(TemporaryFilePath(), S_IWOTH | S_IROTH); };
ExpectRealtimeDeath(Func, "creat");
@@ -195,6 +211,28 @@ TEST(TestRadsanInterceptors, FcntlDiesWhenRealtime) {
ExpectNonRealtimeSurvival(Func);
}
+TEST(TestRadsanInterceptors, FcntlFlockDiesWhenRealtime) {
+ int fd = creat(TemporaryFilePath(), S_IRUSR | S_IWUSR);
+ ASSERT_THAT(fd, Ne(-1));
+
+ auto func = [fd]() {
+ struct flock lock {};
+ lock.l_type = F_RDLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = 0;
+ lock.l_len = 0;
+ lock.l_pid = ::getpid();
+
+ ASSERT_THAT(fcntl(fd, F_GETLK, &lock), Eq(0));
+ ASSERT_THAT(lock.l_type, F_UNLCK);
+ };
+ ExpectRealtimeDeath(func, "fcntl");
+ ExpectNonRealtimeSurvival(func);
+
+ close(fd);
+ std::remove(TemporaryFilePath());
+}
+
TEST(TestRadsanInterceptors, CloseDiesWhenRealtime) {
auto Func = []() { close(0); };
ExpectRealtimeDeath(Func, "close");
>From 66c56c162be77dded9810c565f366a28825b4533 Mon Sep 17 00:00:00 2001
From: Chris Apple <cja-private at pm.me>
Date: Fri, 31 May 2024 14:15:51 -0700
Subject: [PATCH 33/33] Fix issue where fcntl was not using last arg correctly
(#24)
* Fix issue where fcntl was not using last arg correctly
* Comment update
---
.../lib/radsan/radsan_interceptors.cpp | 14 ++++++++++--
.../radsan/tests/radsan_test_interceptors.cpp | 22 +++++++++++++++++++
2 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/radsan/radsan_interceptors.cpp
index 53305c0393f0a..dfde4d5d175f8 100644
--- a/compiler-rt/lib/radsan/radsan_interceptors.cpp
+++ b/compiler-rt/lib/radsan/radsan_interceptors.cpp
@@ -89,10 +89,20 @@ INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) {
va_list args;
va_start(args, cmd);
- void *arg = va_arg(args, void *);
+
+ // Following precedent here. The linux source (fcntl.c, do_fcntl) accepts the
+ // final argument in a variable that will hold the largest of the possible
+ // argument types (pointers and ints are typical in fcntl) It is then assumed
+ // that the implementation of fcntl will cast it properly depending on cmd.
+ //
+ // This is also similar to what is done in
+ // sanitizer_common/sanitizer_common_syscalls.inc
+ const unsigned long arg = va_arg(args, unsigned long);
+ int result = REAL(fcntl)(filedes, cmd, arg);
+
va_end(args);
- return fcntl(filedes, cmd, arg);
+ return result;
}
INTERCEPTOR(int, close, int filedes) {
diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
index fa74e85ad95bc..c8819405494f3 100644
--- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
+++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp
@@ -239,6 +239,28 @@ TEST(TestRadsanInterceptors, CloseDiesWhenRealtime) {
ExpectNonRealtimeSurvival(Func);
}
+TEST(TestRadsanInterceptors, fcntlSetFdDiesWhenRealtime) {
+ int fd = creat(TemporaryFilePath(), S_IRUSR | S_IWUSR);
+ ASSERT_THAT(fd, Ne(-1));
+
+ auto func = [fd]() {
+ int old_flags = fcntl(fd, F_GETFD);
+ ASSERT_THAT(fcntl(fd, F_SETFD, FD_CLOEXEC), Eq(0));
+
+ int flags = fcntl(fd, F_GETFD);
+ ASSERT_THAT(flags, Ne(-1));
+ ASSERT_THAT(flags & FD_CLOEXEC, Eq(FD_CLOEXEC));
+
+ ASSERT_THAT(fcntl(fd, F_SETFD, old_flags), Eq(0));
+ ASSERT_THAT(fcntl(fd, F_GETFD), Eq(old_flags));
+ };
+
+ ExpectRealtimeDeath(func, "fcntl");
+ ExpectNonRealtimeSurvival(func);
+
+ close(fd);
+}
+
TEST(TestRadsanInterceptors, FopenDiesWhenRealtime) {
auto Func = []() {
FILE *fd = fopen(TemporaryFilePath(), "w");
More information about the cfe-commits
mailing list