blob: 9b9cc07ccd449d7eb0eff096bc35434d5cac0634 [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"
9#include "scoped_ptr.h"
10#include "stringprintf.h"
11
12namespace art {
13
Elliott Hughes82870722011-08-29 19:04:51 -070014std::string Demangle(const std::string& mangled_name) {
15 if (mangled_name.empty()) {
16 return "??";
17 }
18
19 // http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html
20 int status;
21 scoped_ptr_malloc<char> result(abi::__cxa_demangle(mangled_name.c_str(), NULL, NULL, &status));
22 if (result != NULL) {
23 return result.get();
24 }
25
26 return mangled_name + "()";
27}
28
Elliott Hughesffe67362011-07-17 12:09:27 -070029void Runtime::PlatformAbort(const char* file, int line) {
30 // On the host, we don't have debuggerd to dump a stack for us.
31
32 // Get the raw stack frames.
33 size_t MAX_STACK_FRAMES = 64;
34 void* frames[MAX_STACK_FRAMES];
35 size_t frame_count = backtrace(frames, MAX_STACK_FRAMES);
36
37 // Turn them into something human-readable with symbols.
Carl Shapiro2ed144c2011-07-26 16:52:08 -070038 scoped_ptr_malloc<char*> symbols(backtrace_symbols(frames, frame_count));
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070039 if (symbols == NULL) {
Elliott Hughesffe67362011-07-17 12:09:27 -070040 PLOG(ERROR) << "backtrace_symbols failed";
41 return;
42 }
43
Elliott Hughes82870722011-08-29 19:04:51 -070044 // backtrace_symbols(3) gives us lines like this:
45 // "/usr/local/google/home/enh/a1/out/host/linux-x86/bin/../lib/libartd.so(_ZN3art7Runtime13PlatformAbortEPKci+0x15b) [0xf76c5af3]"
46
47 // We extract the pieces and demangle, so we can produce output like this:
48 // libartd.so:-1] #00 art::Runtime::PlatformAbort(char const*, int) +0x15b [0xf770dd51]
49
Elliott Hughesffe67362011-07-17 12:09:27 -070050 for (size_t i = 0; i < frame_count; ++i) {
Elliott Hughes82870722011-08-29 19:04:51 -070051 std::string text(symbols.get()[i]);
52
53 size_t index = text.find('(');
54 std::string filename(text.substr(0, index));
55 text.erase(0, index + 1);
56
57 index = text.find_first_of("+)");
58 std::string function_name(Demangle(text.substr(0, index)));
59 text.erase(0, index);
60 index = text.find(')');
61 text.erase(index, 1);
62
63 std::string log_line(StringPrintf("\t#%02d ", i) + function_name + text);
64 LogMessage(filename.c_str(), -1, ERROR, -1).stream() << log_line;
Elliott Hughesffe67362011-07-17 12:09:27 -070065 }
66}
67
68} // namespace art