1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include <__config> 10 #include <__verbose_abort> 11 #include <cstdarg> 12 #include <cstdio> 13 #include <cstdlib> 14 15 #ifdef __BIONIC__ 16 # include <syslog.h> 17 extern "C" void android_set_abort_message(const char* msg); 18 #endif // __BIONIC__ 19 20 #if defined(__APPLE__) && __has_include(<CrashReporterClient.h>) 21 # include <CrashReporterClient.h> 22 #endif 23 24 _LIBCPP_BEGIN_NAMESPACE_STD 25 26 _LIBCPP_WEAK void __libcpp_verbose_abort(char const* format, ...) _LIBCPP_VERBOSE_ABORT_NOEXCEPT { 27 // Write message to stderr. We do this before formatting into a 28 // buffer so that we still get some information out if that fails. 29 { 30 va_list list; 31 va_start(list, format); 32 std::vfprintf(stderr, format, list); 33 va_end(list); 34 } 35 36 // Format the arguments into an allocated buffer for CrashReport & friends. 37 // We leak the buffer on purpose, since we're about to abort() anyway. 38 char* buffer; 39 (void)buffer; 40 va_list list; 41 va_start(list, format); 42 43 #if defined(__APPLE__) && __has_include(<CrashReporterClient.h>) 44 // Note that we should technically synchronize accesses here (by e.g. taking a lock), 45 // however concretely we're only setting a pointer, so the likelihood of a race here 46 // is low. 47 vasprintf(&buffer, format, list); 48 CRSetCrashLogMessage(buffer); 49 #elif defined(__BIONIC__) 50 vasprintf(&buffer, format, list); 51 52 // Show error in tombstone. 53 android_set_abort_message(buffer); 54 55 // Show error in logcat. 56 openlog("libc++", 0, 0); 57 syslog(LOG_CRIT, "%s", buffer); 58 closelog(); 59 #endif 60 va_end(list); 61 62 std::abort(); 63 } 64 65 _LIBCPP_END_NAMESPACE_STD 66