xref: /openbsd-src/gnu/llvm/libcxxabi/src/abort_message.cpp (revision 8f1d572453a8bab44a2fe956e25efc4124e87e82)
1*8f1d5724Srobert //===----------------------------------------------------------------------===//
279c2e3e6Spatrick //
379c2e3e6Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
479c2e3e6Spatrick // See https://llvm.org/LICENSE.txt for license information.
579c2e3e6Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
679c2e3e6Spatrick //
779c2e3e6Spatrick //===----------------------------------------------------------------------===//
879c2e3e6Spatrick 
979c2e3e6Spatrick #include <stdlib.h>
1079c2e3e6Spatrick #include <stdio.h>
1179c2e3e6Spatrick #include <stdarg.h>
1279c2e3e6Spatrick #include "abort_message.h"
1379c2e3e6Spatrick 
1479c2e3e6Spatrick #ifdef __BIONIC__
1579c2e3e6Spatrick #   include <android/api-level.h>
1679c2e3e6Spatrick #   if __ANDROID_API__ >= 21
1779c2e3e6Spatrick #       include <syslog.h>
1879c2e3e6Spatrick         extern "C" void android_set_abort_message(const char* msg);
1979c2e3e6Spatrick #   else
2079c2e3e6Spatrick #       include <assert.h>
2179c2e3e6Spatrick #   endif // __ANDROID_API__ >= 21
2279c2e3e6Spatrick #endif // __BIONIC__
2379c2e3e6Spatrick 
24fb9c2e6cSpatrick #if defined(__APPLE__) && __has_include(<CrashReporterClient.h>)
2579c2e3e6Spatrick #   include <CrashReporterClient.h>
26fb9c2e6cSpatrick #   define _LIBCXXABI_USE_CRASHREPORTER_CLIENT
2779c2e3e6Spatrick #endif
2879c2e3e6Spatrick 
abort_message(const char * format,...)2979c2e3e6Spatrick void abort_message(const char* format, ...)
3079c2e3e6Spatrick {
31fb9c2e6cSpatrick     // Write message to stderr. We do this before formatting into a
32fb9c2e6cSpatrick     // variable-size buffer so that we still get some information if
33fb9c2e6cSpatrick     // formatting into the variable-sized buffer fails.
3479c2e3e6Spatrick #if !defined(NDEBUG) || !defined(LIBCXXABI_BAREMETAL)
35fb9c2e6cSpatrick     {
36fb9c2e6cSpatrick         fprintf(stderr, "libc++abi: ");
3779c2e3e6Spatrick         va_list list;
3879c2e3e6Spatrick         va_start(list, format);
3979c2e3e6Spatrick         vfprintf(stderr, format, list);
4079c2e3e6Spatrick         va_end(list);
4179c2e3e6Spatrick         fprintf(stderr, "\n");
42fb9c2e6cSpatrick     }
4379c2e3e6Spatrick #endif
4479c2e3e6Spatrick 
45fb9c2e6cSpatrick     // Format the arguments into an allocated buffer. We leak the buffer on
46fb9c2e6cSpatrick     // purpose, since we're about to abort() anyway.
47fb9c2e6cSpatrick #if defined(_LIBCXXABI_USE_CRASHREPORTER_CLIENT)
4879c2e3e6Spatrick     char* buffer;
49fb9c2e6cSpatrick     va_list list;
50fb9c2e6cSpatrick     va_start(list, format);
51fb9c2e6cSpatrick     vasprintf(&buffer, format, list);
52fb9c2e6cSpatrick     va_end(list);
53fb9c2e6cSpatrick 
5479c2e3e6Spatrick     CRSetCrashLogMessage(buffer);
5579c2e3e6Spatrick #elif defined(__BIONIC__)
5679c2e3e6Spatrick     char* buffer;
57fb9c2e6cSpatrick     va_list list;
58fb9c2e6cSpatrick     va_start(list, format);
59fb9c2e6cSpatrick     vasprintf(&buffer, format, list);
60fb9c2e6cSpatrick     va_end(list);
6179c2e3e6Spatrick 
6279c2e3e6Spatrick #   if __ANDROID_API__ >= 21
6379c2e3e6Spatrick     // Show error in tombstone.
6479c2e3e6Spatrick     android_set_abort_message(buffer);
6579c2e3e6Spatrick 
6679c2e3e6Spatrick     // Show error in logcat.
6779c2e3e6Spatrick     openlog("libc++abi", 0, 0);
6879c2e3e6Spatrick     syslog(LOG_CRIT, "%s", buffer);
6979c2e3e6Spatrick     closelog();
7079c2e3e6Spatrick #   else
7179c2e3e6Spatrick     // The good error reporting wasn't available in Android until L. Since we're
7279c2e3e6Spatrick     // about to abort anyway, just call __assert2, which will log _somewhere_
7379c2e3e6Spatrick     // (tombstone and/or logcat) in older releases.
7479c2e3e6Spatrick     __assert2(__FILE__, __LINE__, __func__, buffer);
7579c2e3e6Spatrick #   endif // __ANDROID_API__ >= 21
7679c2e3e6Spatrick #endif // __BIONIC__
7779c2e3e6Spatrick 
7879c2e3e6Spatrick     abort();
7979c2e3e6Spatrick }
80