[libcxx-commits] [libcxx] [libc++][hardening] Introduce a dylib function to log hardening errors. (PR #148266)

Konstantin Varlamov via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jul 11 10:51:08 PDT 2025


https://github.com/var-const created https://github.com/llvm/llvm-project/pull/148266

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.


>From 1fcfec368e34964811270b9a10ad969814e3a691 Mon Sep 17 00:00:00 2001
From: Konstantin Varlamov <varconst at apple.com>
Date: Fri, 11 Jul 2025 10:29:10 -0700
Subject: [PATCH] [libc++][hardening] Introduce a dylib function to log
 hardening errors.

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.
---
 libcxx/include/CMakeLists.txt                 |  1 +
 libcxx/include/__configuration/availability.h |  5 ++
 libcxx/include/__log_hardening_failure        | 45 +++++++++++++++++
 libcxx/src/CMakeLists.txt                     |  1 +
 libcxx/src/log_hardening_failure.cpp          | 49 +++++++++++++++++++
 5 files changed, 101 insertions(+)
 create mode 100644 libcxx/include/__log_hardening_failure
 create mode 100644 libcxx/src/log_hardening_failure.cpp

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index c8e6d28584623..2f8be540e73e2 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/__configuration/availability.h b/libcxx/include/__configuration/availability.h
index ae58e36b508b4..cb72e927caa9c 100644
--- a/libcxx/include/__configuration/availability.h
+++ b/libcxx/include/__configuration/availability.h
@@ -304,6 +304,11 @@
 #define _LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT _LIBCPP_INTRODUCED_IN_LLVM_15
 #define _LIBCPP_AVAILABILITY_VERBOSE_ABORT _LIBCPP_INTRODUCED_IN_LLVM_15_ATTRIBUTE
 
+// This controls whether the library provides a function to log hardening failures without terminating the program (for
+// the `observe` assertion semantic).
+#define _LIBCPP_AVAILABILITY_HAS_LOG_HARDENING_FAILURE _LIBCPP_INTRODUCED_IN_LLVM_21
+#define _LIBCPP_AVAILABILITY_LOG_HARDENING_FAILURE _LIBCPP_INTRODUCED_IN_LLVM_21_ATTRIBUTE
+
 // This controls the availability of the C++17 std::pmr library,
 // which is implemented in large part in the built library.
 //
diff --git a/libcxx/include/__log_hardening_failure b/libcxx/include/__log_hardening_failure
new file mode 100644
index 0000000000000..73cff0ac64155
--- /dev/null
+++ b/libcxx/include/__log_hardening_failure
@@ -0,0 +1,45 @@
+// -*- 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
+
+_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.
+_LIBCPP_AVAILABILITY_LOG_HARDENING_FAILURE _LIBCPP_OVERRIDABLE_FUNC_VIS void
+__libcpp_log_hardening_failure(const char* message) _NOEXCEPT;
+
+// _LIBCPP_LOG_HARDENING_FAILURE(message)
+//
+// This macro is used to log a hardening failure without terminating the program (as is the case if the `observe`
+// assertion semantic is used). Where possible, it logs in a way that indicates a fatal error (which might include
+// capturing the stack trace).
+#if !defined(_LIBCPP_LOG_HARDENING_FAILURE)
+
+#  if !_LIBCPP_AVAILABILITY_HAS_LOG_HARDENING_FAILURE
+// The decltype is there to suppress -Wunused warnings in this configuration.
+void __use(const char*);
+#    define _LIBCPP_LOG_HARDENING_FAILURE(message) (decltype(::std::__use(message))())
+#  else
+#    define _LIBCPP_LOG_HARDENING_FAILURE(message) ::std::__libcpp_log_hardening_failure(message)
+#  endif
+
+#endif // !defined(_LIBCPP_LOG_HARDENING_FAILURE)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___LOG_HARDENING_FAILURE
diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt
index 97fe57a5f24f8..926deb3a1c732 100644
--- a/libcxx/src/CMakeLists.txt
+++ b/libcxx/src/CMakeLists.txt
@@ -30,6 +30,7 @@ set(LIBCXX_SOURCES
   include/ryu/ryu.h
   include/to_chars_floating_point.h
   include/from_chars_floating_point.h
+  log_hardening_failure.cpp
   memory.cpp
   memory_resource.cpp
   new_handler.cpp
diff --git a/libcxx/src/log_hardening_failure.cpp b/libcxx/src/log_hardening_failure.cpp
new file mode 100644
index 0000000000000..7e408a6f010b4
--- /dev/null
+++ b/libcxx/src/log_hardening_failure.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// 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>
+extern "C" void android_set_abort_message(const char* msg);
+#endif // __BIONIC__
+
+#if defined(__APPLE__) && __has_include(<os/reason_private.h>)
+#  include <os/reason_private.h>
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+_LIBCPP_WEAK void __libcpp_log_hardening_failure(const char* message) noexcept {
+  // On Apple platforms, use the `os_fault_with_payload` OS function that simulates a crash.
+#if defined(__APPLE__) && __has_include(<os/reason_private.h>)
+  os_fault_with_payload(
+      /*reason_namespace=*/OS_REASON_SECURITY,
+      /*reason_code=*/0,
+      /*payload=*/nullptr,
+      /*payload_size=*/0,
+      /*reason_string=*/message,
+      /*reason_flags=*/0);
+
+#elif defined(__BIONIC__)
+  // Show error in tombstone.
+  android_set_abort_message(message);
+
+  // Show error in logcat.
+  openlog("libc++", 0, 0);
+  syslog(LOG_CRIT, "%s", message);
+  closelog();
+
+#else
+  fprintf(stderr, "%s", message);
+#endif
+}
+
+_LIBCPP_END_NAMESPACE_STD



More information about the libcxx-commits mailing list