master
 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>
17extern "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, ...) 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