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