[libcxx-commits] [libcxx] d750c6d - [libc++][hardening] Add an experimental function to log hardening errors (#149452)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jul 24 10:39:52 PDT 2025
Author: Konstantin Varlamov
Date: 2025-07-24T13:39:48-04:00
New Revision: d750c6de8a75cbe2bc16c136764195471be8f0b7
URL: https://github.com/llvm/llvm-project/commit/d750c6de8a75cbe2bc16c136764195471be8f0b7
DIFF: https://github.com/llvm/llvm-project/commit/d750c6de8a75cbe2bc16c136764195471be8f0b7.diff
LOG: [libc++][hardening] Add an experimental function to log hardening errors (#149452)
Unlike `verbose_abort`, this function merely logs the error but does not
terminate execution. It is intended to make it possible to implement the
`observe` semantic for Hardening.
Added:
libcxx/include/__log_hardening_failure
libcxx/src/experimental/log_hardening_failure.cpp
libcxx/test/libcxx/assertions/log_hardening_failure.pass.cpp
Modified:
libcxx/include/CMakeLists.txt
libcxx/include/__config
libcxx/include/module.modulemap.in
libcxx/src/CMakeLists.txt
libcxx/test/libcxx/experimental/fexperimental-library.compile.pass.cpp
libcxx/utils/libcxx/test/params.py
Removed:
################################################################################
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index cd6583cb62c24..ed5475141b50a 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -535,6 +535,7 @@ set(files
__locale_dir/time.h
__locale_dir/wbuffer_convert.h
__locale_dir/wstring_convert.h
+ __log_hardening_failure
__math/abs.h
__math/copysign.h
__math/error_functions.h
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 19398dd276a17..3fe377aac4816 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -207,6 +207,7 @@ _LIBCPP_HARDENING_MODE_DEBUG
# define _LIBCPP_HAS_EXPERIMENTAL_PSTL _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
# define _LIBCPP_HAS_EXPERIMENTAL_TZDB _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
# define _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
+# define _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
# if defined(__MVS__)
# include <features.h> // for __NATIVE_ASCII_F
diff --git a/libcxx/include/__log_hardening_failure b/libcxx/include/__log_hardening_failure
new file mode 100644
index 0000000000000..d1805306f6b6e
--- /dev/null
+++ b/libcxx/include/__log_hardening_failure
@@ -0,0 +1,42 @@
+// -*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___LOG_HARDENING_FAILURE
+#define _LIBCPP___LOG_HARDENING_FAILURE
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+// Hardening logging is not available in the C++03 mode; moreover, it is currently only available in the experimental
+// library.
+#if _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC && !defined(_LIBCPP_CXX03_LANG)
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// This function should never be called directly from the code -- it should only be called through the
+// `_LIBCPP_LOG_HARDENING_FAILURE` macro.
+[[__gnu__::__cold__]] _LIBCPP_EXPORTED_FROM_ABI void __log_hardening_failure(const char* __message) noexcept;
+
+// _LIBCPP_LOG_HARDENING_FAILURE(message)
+//
+// This macro is used to log an error without terminating the program (as is the case for hardening failures if the
+// `observe` assertion semantic is used).
+
+# if !defined(_LIBCPP_LOG_HARDENING_FAILURE)
+# define _LIBCPP_LOG_HARDENING_FAILURE(__message) ::std::__log_hardening_failure(__message)
+# endif // !defined(_LIBCPP_LOG_HARDENING_FAILURE)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC && !defined(_LIBCPP_CXX03_LANG)
+
+#endif // _LIBCPP___LOG_HARDENING_FAILURE
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index ac497208bdce4..117556edb5d20 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -2355,6 +2355,9 @@ module std [system] {
header "__std_mbstate_t.h"
export *
}
+ module log_hardening_failure {
+ header "__log_hardening_failure"
+ }
module verbose_abort {
header "__verbose_abort"
}
diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt
index 97fe57a5f24f8..f59fe0e08fccb 100644
--- a/libcxx/src/CMakeLists.txt
+++ b/libcxx/src/CMakeLists.txt
@@ -309,6 +309,7 @@ add_custom_target(cxx DEPENDS ${LIBCXX_BUILD_TARGETS})
# Build the experimental static library
set(LIBCXX_EXPERIMENTAL_SOURCES
experimental/keep.cpp
+ experimental/log_hardening_failure.cpp
)
if (LIBCXX_PSTL_BACKEND STREQUAL "libdispatch")
diff --git a/libcxx/src/experimental/log_hardening_failure.cpp b/libcxx/src/experimental/log_hardening_failure.cpp
new file mode 100644
index 0000000000000..f836c15452249
--- /dev/null
+++ b/libcxx/src/experimental/log_hardening_failure.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <__config>
+#include <__log_hardening_failure>
+#include <cstdio>
+
+#ifdef __BIONIC__
+# include <syslog.h>
+#endif // __BIONIC__
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+void __log_hardening_failure(const char* message) noexcept {
+ // Always log the message to `stderr` in case the platform-specific system calls fail.
+ std::fputs(message, stderr);
+
+#if defined(__BIONIC__)
+ // Show error in logcat. The latter two arguments are ignored on Android.
+ openlog("libc++", 0, 0);
+ syslog(LOG_CRIT, "%s", message);
+ closelog();
+#endif
+}
+
+_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/test/libcxx/assertions/log_hardening_failure.pass.cpp b/libcxx/test/libcxx/assertions/log_hardening_failure.pass.cpp
new file mode 100644
index 0000000000000..dda071b8d0296
--- /dev/null
+++ b/libcxx/test/libcxx/assertions/log_hardening_failure.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Basic smoke test for `__log_hardening_failure`.
+//
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-has-no-experimental-hardening-observe-semantic
+
+#include <__log_hardening_failure>
+
+#include "test_macros.h"
+
+ASSERT_NOEXCEPT(std::__log_hardening_failure(""));
+
+int main(int, char**) {
+ std::__log_hardening_failure("Some message");
+ // It's
diff icult to properly test platform-specific logging behavior of the function; just make sure it exists and
+ // can be called at runtime.
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx/experimental/fexperimental-library.compile.pass.cpp b/libcxx/test/libcxx/experimental/fexperimental-library.compile.pass.cpp
index 3cf497da233fb..3d97446ffe826 100644
--- a/libcxx/test/libcxx/experimental/fexperimental-library.compile.pass.cpp
+++ b/libcxx/test/libcxx/experimental/fexperimental-library.compile.pass.cpp
@@ -29,3 +29,7 @@
#if !_LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM
# error "-fexperimental-library should enable the syncstream header"
#endif
+
+#if !_LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC
+# error "-fexperimental-library should allow using the Hardening observe semantic"
+#endif
diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py
index adfb2a9f69508..93cf29bcdff0d 100644
--- a/libcxx/utils/libcxx/test/params.py
+++ b/libcxx/utils/libcxx/test/params.py
@@ -361,6 +361,7 @@ def getSuitableClangTidy(cfg):
AddFeature("libcpp-has-no-incomplete-pstl"),
AddFeature("libcpp-has-no-experimental-tzdb"),
AddFeature("libcpp-has-no-experimental-syncstream"),
+ AddFeature("libcpp-has-no-experimental-hardening-observe-semantic"),
],
),
# TODO: This can be improved once we use a version of GoogleBenchmark that supports the dry-run mode.
More information about the libcxx-commits
mailing list