blob: 1461528a31d745967f93df97f0e6f45ed3ad09aa [file] [log] [blame]
Elliott Hughesffe67362011-07-17 12:09:27 -07001// Copyright 2011 Google Inc. All Rights Reserved.
Elliott Hughesffe67362011-07-17 12:09:27 -07002
3#include "runtime.h"
4
Elliott Hughes82870722011-08-29 19:04:51 -07005#include <cxxabi.h>
Elliott Hughesffe67362011-07-17 12:09:27 -07006#include <execinfo.h>
7
8#include "logging.h"
Elliott Hughesffe67362011-07-17 12:09:27 -07009#include "stringprintf.h"
10
11namespace art {
12
Elliott Hughes82870722011-08-29 19:04:51 -070013std::string Demangle(const std::string& mangled_name) {
14 if (mangled_name.empty()) {
15 return "??";
16 }
17
18 // http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html
19 int status;
Elliott Hughes34023802011-08-30 12:06:17 -070020 char* name(abi::__cxa_demangle(mangled_name.c_str(), NULL, NULL, &status));
21 if (name != NULL) {
22 std::string result(name);
23 free(name);
24 return result;
Elliott Hughes82870722011-08-29 19:04:51 -070025 }
26
27 return mangled_name + "()";
28}
29
Elliott Hughesffe67362011-07-17 12:09:27 -070030void Runtime::PlatformAbort(const char* file, int line) {
31 // On the host, we don't have debuggerd to dump a stack for us.
32
33 // Get the raw stack frames.
34 size_t MAX_STACK_FRAMES = 64;
35 void* frames[MAX_STACK_FRAMES];
36 size_t frame_count = backtrace(frames, MAX_STACK_FRAMES);
37
38 // Turn them into something human-readable with symbols.
Elliott Hughes34023802011-08-30 12:06:17 -070039 char** symbols = backtrace_symbols(frames, frame_count);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070040 if (symbols == NULL) {
Elliott Hughesffe67362011-07-17 12:09:27 -070041 PLOG(ERROR) << "backtrace_symbols failed";
42 return;
43 }
44
Elliott Hughes82870722011-08-29 19:04:51 -070045 // backtrace_symbols(3) gives us lines like this:
46 // "/usr/local/google/home/enh/a1/out/host/linux-x86/bin/../lib/libartd.so(_ZN3art7Runtime13PlatformAbortEPKci+0x15b) [0xf76c5af3]"
Elliott Hughesa0957642011-09-02 14:27:33 -070047 // "[0xf7b62057]"
Elliott Hughes82870722011-08-29 19:04:51 -070048
49 // We extract the pieces and demangle, so we can produce output like this:
50 // libartd.so:-1] #00 art::Runtime::PlatformAbort(char const*, int) +0x15b [0xf770dd51]
51
Elliott Hughesffe67362011-07-17 12:09:27 -070052 for (size_t i = 0; i < frame_count; ++i) {
Elliott Hughes34023802011-08-30 12:06:17 -070053 std::string text(symbols[i]);
Elliott Hughesa0957642011-09-02 14:27:33 -070054 std::string filename("??");
55 std::string function_name;
Elliott Hughes82870722011-08-29 19:04:51 -070056
57 size_t index = text.find('(');
Elliott Hughesa0957642011-09-02 14:27:33 -070058 if (index != std::string::npos) {
59 filename = text.substr(0, index);
60 text.erase(0, index + 1);
Elliott Hughes82870722011-08-29 19:04:51 -070061
Elliott Hughesa0957642011-09-02 14:27:33 -070062 index = text.find_first_of("+)");
63 function_name = Demangle(text.substr(0, index));
64 text.erase(0, index);
65 index = text.find(')');
66 text.erase(index, 1);
67 }
Elliott Hughes82870722011-08-29 19:04:51 -070068 std::string log_line(StringPrintf("\t#%02d ", i) + function_name + text);
69 LogMessage(filename.c_str(), -1, ERROR, -1).stream() << log_line;
Elliott Hughesffe67362011-07-17 12:09:27 -070070 }
Elliott Hughes34023802011-08-30 12:06:17 -070071
72 free(symbols);
Elliott Hughesffe67362011-07-17 12:09:27 -070073}
74
75} // namespace art