[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