blob: c87825cca4f8f854523fac0f21cd89840edea034 [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]"
47
48 // We extract the pieces and demangle, so we can produce output like this:
49 // libartd.so:-1] #00 art::Runtime::PlatformAbort(char const*, int) +0x15b [0xf770dd51]
50
Elliott Hughesffe67362011-07-17 12:09:27 -070051 for (size_t i = 0; i < frame_count; ++i) {
Elliott Hughes34023802011-08-30 12:06:17 -070052 std::string text(symbols[i]);
Elliott Hughes82870722011-08-29 19:04:51 -070053
54 size_t index = text.find('(');
55 std::string filename(text.substr(0, index));
56 text.erase(0, index + 1);
57
58 index = text.find_first_of("+)");
59 std::string function_name(Demangle(text.substr(0, index)));
60 text.erase(0, index);
61 index = text.find(')');
62 text.erase(index, 1);
63
64 std::string log_line(StringPrintf("\t#%02d ", i) + function_name + text);
65 LogMessage(filename.c_str(), -1, ERROR, -1).stream() << log_line;
Elliott Hughesffe67362011-07-17 12:09:27 -070066 }
Elliott Hughes34023802011-08-30 12:06:17 -070067
68 free(symbols);
Elliott Hughesffe67362011-07-17 12:09:27 -070069}
70
71} // namespace art