blob: a60481966770fcab1e49983a06214b4684bb2bc0 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Elliott Hughesffe67362011-07-17 12:09:27 -070016
17#include "runtime.h"
18
Elliott Hughes82870722011-08-29 19:04:51 -070019#include <cxxabi.h>
Elliott Hughesffe67362011-07-17 12:09:27 -070020#include <execinfo.h>
21
22#include "logging.h"
Elliott Hughesffe67362011-07-17 12:09:27 -070023#include "stringprintf.h"
24
25namespace art {
26
Elliott Hughes82870722011-08-29 19:04:51 -070027std::string Demangle(const std::string& mangled_name) {
28 if (mangled_name.empty()) {
29 return "??";
30 }
31
32 // http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html
33 int status;
Elliott Hughes34023802011-08-30 12:06:17 -070034 char* name(abi::__cxa_demangle(mangled_name.c_str(), NULL, NULL, &status));
35 if (name != NULL) {
36 std::string result(name);
37 free(name);
38 return result;
Elliott Hughes82870722011-08-29 19:04:51 -070039 }
40
41 return mangled_name + "()";
42}
43
Elliott Hughes1bac54f2012-03-16 12:48:31 -070044void Runtime::PlatformAbort(const char* /*file*/, int /*line_number*/) {
Elliott Hughesffe67362011-07-17 12:09:27 -070045 // On the host, we don't have debuggerd to dump a stack for us.
46
47 // Get the raw stack frames.
48 size_t MAX_STACK_FRAMES = 64;
49 void* frames[MAX_STACK_FRAMES];
50 size_t frame_count = backtrace(frames, MAX_STACK_FRAMES);
51
52 // Turn them into something human-readable with symbols.
Elliott Hughes34023802011-08-30 12:06:17 -070053 char** symbols = backtrace_symbols(frames, frame_count);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070054 if (symbols == NULL) {
Elliott Hughesffe67362011-07-17 12:09:27 -070055 PLOG(ERROR) << "backtrace_symbols failed";
56 return;
57 }
58
Elliott Hughes82870722011-08-29 19:04:51 -070059 // backtrace_symbols(3) gives us lines like this:
60 // "/usr/local/google/home/enh/a1/out/host/linux-x86/bin/../lib/libartd.so(_ZN3art7Runtime13PlatformAbortEPKci+0x15b) [0xf76c5af3]"
Elliott Hughesa0957642011-09-02 14:27:33 -070061 // "[0xf7b62057]"
Elliott Hughes82870722011-08-29 19:04:51 -070062
63 // We extract the pieces and demangle, so we can produce output like this:
Elliott Hughes362f9bc2011-10-17 18:56:41 -070064 // libartd.so:-1] #00 art::Runtime::PlatformAbort(char const*, int) +0x15b [0xf770dd51]
Elliott Hughes82870722011-08-29 19:04:51 -070065
Elliott Hughesffe67362011-07-17 12:09:27 -070066 for (size_t i = 0; i < frame_count; ++i) {
Elliott Hughes34023802011-08-30 12:06:17 -070067 std::string text(symbols[i]);
Elliott Hughesa0957642011-09-02 14:27:33 -070068 std::string filename("??");
69 std::string function_name;
Elliott Hughes82870722011-08-29 19:04:51 -070070
71 size_t index = text.find('(');
Elliott Hughesa0957642011-09-02 14:27:33 -070072 if (index != std::string::npos) {
73 filename = text.substr(0, index);
74 text.erase(0, index + 1);
Elliott Hughes82870722011-08-29 19:04:51 -070075
Elliott Hughesa0957642011-09-02 14:27:33 -070076 index = text.find_first_of("+)");
77 function_name = Demangle(text.substr(0, index));
78 text.erase(0, index);
79 index = text.find(')');
80 text.erase(index, 1);
81 }
Elliott Hughesad6c9c32012-01-19 17:39:12 -080082 std::string log_line(StringPrintf("\t#%02zd ", i) + function_name + text);
Elliott Hughes9ee5f9c2012-02-03 18:33:16 -080083 LogMessage(filename.c_str(), -1, INTERNAL_FATAL, -1).stream() << log_line;
Elliott Hughesffe67362011-07-17 12:09:27 -070084 }
Elliott Hughes34023802011-08-30 12:06:17 -070085
86 free(symbols);
Elliott Hughesffe67362011-07-17 12:09:27 -070087}
88
89} // namespace art