https://github.com/llvmbot created 
https://github.com/llvm/llvm-project/pull/150481

Backport d750c6de8a75cbe2bc16c136764195471be8f0b7

Requested by: @ldionne

>From ef25cd0673f918cb5ca422e58cf4e9af0c2325f6 Mon Sep 17 00:00:00 2001
From: Konstantin Varlamov <varcons...@gmail.com>
Date: Thu, 24 Jul 2025 10:39:48 -0700
Subject: [PATCH] [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.

(cherry picked from commit d750c6de8a75cbe2bc16c136764195471be8f0b7)
---
 libcxx/include/CMakeLists.txt                 |  1 +
 libcxx/include/__config                       |  1 +
 libcxx/include/__log_hardening_failure        | 42 +++++++++++++++++++
 libcxx/include/module.modulemap.in            |  3 ++
 libcxx/src/CMakeLists.txt                     |  1 +
 .../experimental/log_hardening_failure.cpp    | 31 ++++++++++++++
 .../assertions/log_hardening_failure.pass.cpp | 26 ++++++++++++
 .../fexperimental-library.compile.pass.cpp    |  4 ++
 libcxx/utils/libcxx/test/params.py            |  1 +
 9 files changed, 110 insertions(+)
 create mode 100644 libcxx/include/__log_hardening_failure
 create mode 100644 libcxx/src/experimental/log_hardening_failure.cpp
 create mode 100644 libcxx/test/libcxx/assertions/log_hardening_failure.pass.cpp

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 4f2a8dddad92c..85758c671e1e0 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 8f215bbe47928..7bb5d9ac77ea4 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 61ba1c381b2b3..53f10ab8a92a5 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -2353,6 +2353,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 difficult 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.

_______________________________________________
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to