1//===------------------------- abort_message.cpp --------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include <stdlib.h>
11#include <stdio.h>
12#include <stdarg.h>
13#include "abort_message.h"
14
15#ifdef __BIONIC__
16#include <android/set_abort_message.h>
17#include <syslog.h>
18#endif
19
20#pragma GCC visibility push(hidden)
21
22#if __APPLE__
23#   if defined(__has_include) && __has_include(<CrashReporterClient.h>)
24#       define HAVE_CRASHREPORTERCLIENT_H 1
25#       include <CrashReporterClient.h>
26#   endif
27#endif
28
29#ifdef BARRELFISH
30// XXX: do not want to include <barrelfish/domain.h> <barrelfish/dispatch.h>
31// and <barrelfish/threads.h> here, so we give the plain declarations for the
32// functions we need to get Barrelfish styling in the abort message.
33// -SG, 2015-02-18
34#define DISP_NAME_LEN   16
35extern "C" {
36#include <barrelfish_kpi/types.h>
37extern const char *disp_name(void);
38extern coreid_t disp_get_core_id(void);
39extern uintptr_t thread_id(void);
40}
41#endif
42
43__attribute__((visibility("hidden"), noreturn))
44void abort_message(const char* format, ...)
45{
46    // write message to stderr
47#if __APPLE__
48    fprintf(stderr, "libc++abi.dylib: ");
49#endif
50
51#ifdef BARRELFISH
52    // use Barrelfish debug_printf style to get info about dispatcher and
53    // thread.
54    fprintf(stderr, "\033[34m%.*s.\033[31m%u.%lu\033[0m: ", DISP_NAME_LEN,
55            disp_name(), disp_get_core_id(), thread_id());
56#endif
57    va_list list;
58    va_start(list, format);
59    vfprintf(stderr, format, list);
60    va_end(list);
61    fprintf(stderr, "\n");
62
63#if __APPLE__ && HAVE_CRASHREPORTERCLIENT_H
64    // record message in crash report
65    char* buffer;
66    va_list list2;
67    va_start(list2, format);
68    vasprintf(&buffer, format, list2);
69    va_end(list2);
70    CRSetCrashLogMessage(buffer);
71#elif __BIONIC__
72    char* buffer;
73    va_list list2;
74    va_start(list2, format);
75    vasprintf(&buffer, format, list2);
76    va_end(list2);
77
78    // Show error in tombstone.
79    android_set_abort_message(buffer);
80
81    // Show error in logcat.
82    openlog("libc++abi", 0, 0);
83    syslog(LOG_CRIT, "%s", buffer);
84    closelog();
85#endif
86
87    abort();
88}
89
90#pragma GCC visibility pop
91