[libcxx-commits] [libcxx] [libcxx] add Android assertion handler (PR #198831)

George Burgess IV via libcxx-commits libcxx-commits at lists.llvm.org
Wed May 20 15:54:47 PDT 2026


https://github.com/gburgessiv updated https://github.com/llvm/llvm-project/pull/198831

>From a383941de83a406f5179e73396126d50c3b37d38 Mon Sep 17 00:00:00 2001
From: George Burgess IV <gbiv at google.com>
Date: Fri, 15 May 2026 11:41:11 -0600
Subject: [PATCH 1/2] [libcxx] add Android assertion handler

We're in the process of increasing the use of libcxx hardening in
Android. The handlers we're using deviate from the defaults in two ways:

- All handlers are `nomerge` for better postmortem crash attribution
- `_LIBCPP_VERBOSE_ABORT` is wrapped by a `NOINLINE` function to reduce
  binary size overhead slightly (on x86_64, the diff is ~9B per call
  to _LIBCPP_VERBOSE_ABORT).
---
 .../android/android_assertion_handler.in      | 58 +++++++++++++++++++
 1 file changed, 58 insertions(+)
 create mode 100644 libcxx/vendor/android/android_assertion_handler.in

diff --git a/libcxx/vendor/android/android_assertion_handler.in b/libcxx/vendor/android/android_assertion_handler.in
new file mode 100644
index 0000000000000..f1d08ff2303c7
--- /dev/null
+++ b/libcxx/vendor/android/android_assertion_handler.in
@@ -0,0 +1,58 @@
+// -*- 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_ANDROID_ASSERTION_HANDLER
+#define __LIBCPP_ANDROID_ASSERTION_HANDLER
+
+#include <__config>
+#include <__log_hardening_failure>
+#include <__verbose_abort>
+#include <__verbose_trap>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_IGNORE
+#  define _LIBCPP_ASSERTION_HANDLER(message) ((void)0)
+
+#elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_OBSERVE
+#  define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_LOG_HARDENING_FAILURE(message)
+
+#elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE
+
+// Require `nomerge` for better crash attribution.
+#  define _LIBCPP_ASSERTION_HANDLER(message) \
+  ({ [[clang::nomerge]] _LIBCPP_VERBOSE_TRAP(message); })
+
+#elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// Calling a `void(const char *)` takes fewer bytes than calling a
+// `void(const char *, ...)`.
+[[__noreturn__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_NOINLINE
+inline void __libcpp_android_verbose_abort(const char *__message) {
+  _LIBCPP_VERBOSE_ABORT("%s", __message);
+}
+_LIBCPP_END_NAMESPACE_STD
+
+#  define _LIBCPP_ASSERTION_HANDLER(message) \
+  ({ [[clang::nomerge]] ::std::__libcpp_android_verbose_abort(message); })
+
+#else
+
+#  error _LIBCPP_ASSERTION_SEMANTIC must be set to one of the following values: \
+_LIBCPP_ASSERTION_SEMANTIC_IGNORE, \
+_LIBCPP_ASSERTION_SEMANTIC_OBSERVE, \
+_LIBCPP_ASSERTION_SEMANTIC_QUICK_ENFORCE, \
+_LIBCPP_ASSERTION_SEMANTIC_ENFORCE
+
+#endif // _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_IGNORE
+
+#endif // __LIBCPP_ANDROID_ASSERTION_HANDLER

>From 81478e361b3798af16b6f6dc0d5c2918ef602654 Mon Sep 17 00:00:00 2001
From: George Burgess IV <gbiv at google.com>
Date: Wed, 20 May 2026 16:51:42 -0600
Subject: [PATCH 2/2] clarify comment

---
 libcxx/vendor/android/android_assertion_handler.in | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/vendor/android/android_assertion_handler.in b/libcxx/vendor/android/android_assertion_handler.in
index f1d08ff2303c7..76e619d08e25b 100644
--- a/libcxx/vendor/android/android_assertion_handler.in
+++ b/libcxx/vendor/android/android_assertion_handler.in
@@ -34,8 +34,8 @@
 #elif _LIBCPP_ASSERTION_SEMANTIC == _LIBCPP_ASSERTION_SEMANTIC_ENFORCE
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-// Calling a `void(const char *)` takes fewer bytes than calling a
-// `void(const char *, ...)`.
+// Calling this saves code size compared to
+// `__libcpp_verbose_abort("%s", "error message")`.
 [[__noreturn__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_NOINLINE
 inline void __libcpp_android_verbose_abort(const char *__message) {
   _LIBCPP_VERBOSE_ABORT("%s", __message);



More information about the libcxx-commits mailing list