[libcxx-commits] [libcxx] 7de5aca - [libc++] Generalize the customizeable assertion handler
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jul 26 04:43:08 PDT 2022
Author: Louis Dionne
Date: 2022-07-26T07:42:38-04:00
New Revision: 7de5aca84c541edd9f11b9316cb61c5f350ee724
URL: https://github.com/llvm/llvm-project/commit/7de5aca84c541edd9f11b9316cb61c5f350ee724
DIFF: https://github.com/llvm/llvm-project/commit/7de5aca84c541edd9f11b9316cb61c5f350ee724.diff
LOG: [libc++] Generalize the customizeable assertion handler
Instead of taking a fixed set of arguments, use variadics so that
we can pass arbitrary arguments to the handler. This is the first
step towards using the handler to handle other non-assertion-related
failures, like std::unreachable and an exception being thrown in
-fno-exceptions mode, which would improve user experience by including
additional information in crashes (right now, we call abort() without
additional information).
Differential Revision: https://reviews.llvm.org/D130507
Added:
Modified:
libcxx/docs/UsingLibcxx.rst
libcxx/include/__assert
libcxx/lib/abi/CHANGELOG.TXT
libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
libcxx/src/assert.cpp
libcxx/test/libcxx/assertions/customize_handler.backdeployment.pass.cpp
libcxx/test/libcxx/assertions/customize_handler.pass.cpp
libcxx/test/libcxx/assertions/debug_mode_compatibility.pass.cpp
libcxx/test/support/check_assertion.h
Removed:
################################################################################
diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst
index aa581207cf079..40a8d9a36838a 100644
--- a/libcxx/docs/UsingLibcxx.rst
+++ b/libcxx/docs/UsingLibcxx.rst
@@ -163,7 +163,7 @@ Replacing the default assertion handler is done by defining the following functi
.. code-block:: cpp
- void __libcpp_assertion_handler(char const* file, int line, char const* expression, char const* message)
+ void __libcpp_assertion_handler(char const* format, ...)
This mechanism is similar to how one can replace the default definition of ``operator new``
and ``operator delete``. For example:
@@ -173,8 +173,12 @@ and ``operator delete``. For example:
// In HelloWorldHandler.cpp
#include <version> // must include any libc++ header before defining the handler (C compatibility headers excluded)
- void std::__libcpp_assertion_handler(char const* file, int line, char const* expression, char const* message) {
- std::printf("Assertion %s failed at %s:%d, more info: %s", expression, file, line, message);
+ void std::__libcpp_assertion_handler(char const* format, ...) {
+ va_list list;
+ va_start(list, format);
+ std::vfprintf(stderr, format, list);
+ va_end(list);
+
std::abort();
}
diff --git a/libcxx/include/__assert b/libcxx/include/__assert
index 84ddcd25b0b51..82db2cf052b5e 100644
--- a/libcxx/include/__assert
+++ b/libcxx/include/__assert
@@ -45,7 +45,7 @@
# define _LIBCPP_ASSERT(expression, message) \
(__builtin_expect(static_cast<bool>(expression), 1) ? \
(void)0 : \
- ::std::__libcpp_assertion_handler(__FILE__, __LINE__, #expression, message))
+ ::std::__libcpp_assertion_handler("%s:%d: assertion %s failed: %s", __FILE__, __LINE__, #expression, message))
#elif !defined(_LIBCPP_ASSERTIONS_DISABLE_ASSUME) && __has_builtin(__builtin_assume)
# define _LIBCPP_ASSERT(expression, message) \
(_LIBCPP_DIAGNOSTIC_PUSH \
@@ -58,8 +58,8 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_ASSERTION_HANDLER
-void __libcpp_assertion_handler(char const* __file, int __line, char const* __expression, char const* __message);
+_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_ASSERTION_HANDLER _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2)
+void __libcpp_assertion_handler(const char *__format, ...);
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/lib/abi/CHANGELOG.TXT b/libcxx/lib/abi/CHANGELOG.TXT
index 034f2e47d7232..877ba8d991604 100644
--- a/libcxx/lib/abi/CHANGELOG.TXT
+++ b/libcxx/lib/abi/CHANGELOG.TXT
@@ -64,7 +64,7 @@ Version 15.0
Symbol removed: _ZTSNSt3__18__c_nodeE
Symbol removed: _ZTVNSt3__18__c_nodeE
-* b0fd9497af6d - [libc++] Add a lightweight overridable assertion handler
+* b0fd9497af6d and XXXXXXX - [libc++] Add a lightweight overridable assertion handler
This patch adds a lightweight assertion handler mechanism that can be
overriden at link-time in a fashion similar to `operator new`. A default
@@ -73,7 +73,7 @@ Version 15.0
All platforms
-------------
- Symbol added: _ZNSt3__126__libcpp_assertion_handlerEPKciS1_S1_
+ Symbol added: _ZNSt3__126__libcpp_assertion_handlerEPKcz
------------
Version 14.0
diff --git a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
index f1cb3c7a1a14b..dd2438dfcb436 100644
--- a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1534,7 +1534,7 @@
{'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__126__libcpp_assertion_handlerEPKciS1_S1_', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__126__libcpp_assertion_handlerEPKcz', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIaaEEPaEEbT0_S5_T_', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIccEEPcEEbT0_S5_T_', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIddEEPdEEbT0_S5_T_', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index 69d1f7ece861f..c662644418d49 100644
--- a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1678,7 +1678,7 @@
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
-{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__126__libcpp_assertion_handlerEPKciS1_S1_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__126__libcpp_assertion_handlerEPKcz', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIaaEEPaEEbT0_S5_T_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIccEEPcEEbT0_S5_T_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIddEEPdEEbT0_S5_T_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index b17b3bbe99300..d730eaeb776e2 100644
--- a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1678,7 +1678,7 @@
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
-{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__126__libcpp_assertion_handlerEPKciS1_S1_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__126__libcpp_assertion_handlerEPKcz', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIaaEEPaEEbT0_S5_T_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIccEEPcEEbT0_S5_T_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIddEEPdEEbT0_S5_T_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
index 5abc715dac499..bc81e61c55e2c 100644
--- a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1534,7 +1534,7 @@
{'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__126__libcpp_assertion_handlerEPKciS1_S1_', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__126__libcpp_assertion_handlerEPKcz', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIaaEEPaEEbT0_S5_T_', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIccEEPcEEbT0_S5_T_', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIddEEPdEEbT0_S5_T_', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
index 9fb4b7f471f0f..1437c1cc4b731 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1225,7 +1225,7 @@
{'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__126__libcpp_assertion_handlerEPKciS1_S1_', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__126__libcpp_assertion_handlerEPKcz', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIaaEEPaEEbT0_S5_T_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIccEEPcEEbT0_S5_T_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIddEEPdEEbT0_S5_T_', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
index de08e523f7bf0..1348fc6ca3034 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
@@ -1197,7 +1197,7 @@
{'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__126__libcpp_assertion_handlerEPKciS1_S1_', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__126__libcpp_assertion_handlerEPKcz', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIaaEEPaEEbT0_S5_T_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIccEEPcEEbT0_S5_T_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIddEEPdEEbT0_S5_T_', 'type': 'FUNC'}
diff --git a/libcxx/src/assert.cpp b/libcxx/src/assert.cpp
index 54459800728b1..c218645f17712 100644
--- a/libcxx/src/assert.cpp
+++ b/libcxx/src/assert.cpp
@@ -8,14 +8,57 @@
#include <__assert>
#include <__config>
+#include <cstdarg>
#include <cstdio>
#include <cstdlib>
+#ifdef __BIONIC__
+# include <android/api-level.h>
+# include <syslog.h>
+extern "C" void android_set_abort_message(const char* msg);
+#endif
+
+#if defined(__APPLE__) && __has_include(<CrashReporterClient.h>)
+# include <CrashReporterClient.h>
+#endif
+
_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_WEAK
-void __libcpp_assertion_handler(char const* __file, int __line, char const* __expression, char const* __message) {
- std::fprintf(stderr, "%s:%d: libc++ assertion '%s' failed. %s\n", __file, __line, __expression, __message);
+void __libcpp_assertion_handler(char const* format, ...) {
+ // Write message to stderr. We do this before formatting into a
+ // buffer so that we still get some information out if that fails.
+ {
+ va_list list;
+ va_start(list, format);
+ std::vfprintf(stderr, format, list);
+ va_end(list);
+ }
+
+ // Format the arguments into an allocated buffer for CrashReport & friends.
+ // We leak the buffer on purpose, since we're about to abort() anyway.
+ char* buffer; (void)buffer;
+ va_list list;
+ va_start(list, format);
+
+#if defined(__APPLE__) && __has_include(<CrashReporterClient.h>)
+ // Note that we should technically synchronize accesses here (by e.g. taking a lock),
+ // however concretely we're only setting a pointer, so the likelihood of a race here
+ // is low.
+ vasprintf(&buffer, format, list);
+ CRSetCrashLogMessage(buffer);
+#elif defined(__BIONIC__)
+ // Show error in tombstone.
+ vasprintf(&buffer, format, list);
+ android_set_abort_message(buffer);
+
+ // Show error in logcat.
+ openlog("libc++", 0, 0);
+ syslog(LOG_CRIT, "%s", buffer);
+ closelog();
+#endif
+ va_end(list);
+
std::abort();
}
diff --git a/libcxx/test/libcxx/assertions/customize_handler.backdeployment.pass.cpp b/libcxx/test/libcxx/assertions/customize_handler.backdeployment.pass.cpp
index fda41a595bb27..b1b5e0c8b1b6c 100644
--- a/libcxx/test/libcxx/assertions/customize_handler.backdeployment.pass.cpp
+++ b/libcxx/test/libcxx/assertions/customize_handler.backdeployment.pass.cpp
@@ -17,7 +17,7 @@
#include <cassert>
bool handler_called = false;
-void std::__libcpp_assertion_handler(char const*, int, char const*, char const*) {
+void std::__libcpp_assertion_handler(char const*, ...) {
handler_called = true;
}
diff --git a/libcxx/test/libcxx/assertions/customize_handler.pass.cpp b/libcxx/test/libcxx/assertions/customize_handler.pass.cpp
index 54c0d16be22fc..e6faf1b914b9a 100644
--- a/libcxx/test/libcxx/assertions/customize_handler.pass.cpp
+++ b/libcxx/test/libcxx/assertions/customize_handler.pass.cpp
@@ -17,7 +17,7 @@
#include <cassert>
bool handler_called = false;
-void std::__libcpp_assertion_handler(char const*, int, char const*, char const*) {
+void std::__libcpp_assertion_handler(char const*, ...) {
handler_called = true;
}
diff --git a/libcxx/test/libcxx/assertions/debug_mode_compatibility.pass.cpp b/libcxx/test/libcxx/assertions/debug_mode_compatibility.pass.cpp
index a4c61a6d25684..6cee46ae7a6f0 100644
--- a/libcxx/test/libcxx/assertions/debug_mode_compatibility.pass.cpp
+++ b/libcxx/test/libcxx/assertions/debug_mode_compatibility.pass.cpp
@@ -19,7 +19,7 @@
#include <cassert>
bool handler_called = false;
-void std::__libcpp_assertion_handler(char const*, int, char const*, char const*) {
+void std::__libcpp_assertion_handler(char const*, ...) {
handler_called = true;
}
diff --git a/libcxx/test/support/check_assertion.h b/libcxx/test/support/check_assertion.h
index 30067b4030bf1..789823a6746a3 100644
--- a/libcxx/test/support/check_assertion.h
+++ b/libcxx/test/support/check_assertion.h
@@ -10,6 +10,7 @@
#define TEST_SUPPORT_CHECK_ASSERTION_H
#include <cassert>
+#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
@@ -235,8 +236,19 @@ struct DeathTest {
std::string stderr_from_child_;
};
-void std::__libcpp_assertion_handler(char const* file, int line, char const* /*expression*/, char const* message) {
+void std::__libcpp_assertion_handler(char const* format, ...) {
assert(!GlobalMatcher().empty());
+
+ // Extract information from the error message. This has to stay synchronized with
+ // how we format assertions in the library.
+ va_list list;
+ va_start(list, format);
+ char const* file = va_arg(list, char const*);
+ int line = va_arg(list, int);
+ char const* expression = va_arg(list, char const*); (void)expression;
+ char const* message = va_arg(list, char const*);
+ va_end(list);
+
if (GlobalMatcher().Matches(file, line, message)) {
std::exit(DeathTest::RK_MatchFound);
}
More information about the libcxx-commits
mailing list