Index: base/debug_util_posix.cc |
diff --git a/base/debug_util_posix.cc b/base/debug_util_posix.cc |
index 73b756b7387c03cb0071729aba964961b46506bb..a57f10215feb54df942d015693f1341091a9e48d 100644 |
--- a/base/debug_util_posix.cc |
+++ b/base/debug_util_posix.cc |
@@ -17,6 +17,7 @@ |
#include <cxxabi.h> |
#endif |
+#include <iostream> |
#include <string> |
#if defined(OS_MACOSX) |
@@ -30,6 +31,11 @@ |
#include "base/safe_strerror_posix.h" |
#include "base/scoped_ptr.h" |
#include "base/string_piece.h" |
+#include "base/string_util.h" |
+ |
+#if defined(USE_SYMBOLIZE) |
+#include "base/third_party/symbolize/symbolize.h" |
Evan Martin
2010/01/25 18:10:40
It seems this included file then then does
#incl
satorux1
2010/01/25 21:15:50
That's a good question. I don't know the detail of
|
+#endif |
namespace { |
// The prefix used for mangled symbols, per the Itanium C++ ABI: |
@@ -86,6 +92,48 @@ void DemangleSymbols(std::string* text) { |
#endif // defined(__GLIBCXX__) |
} |
+ |
+// Gets the backtrace as a vector of strings. If possible, resolve symbol |
+// names and attach these. Otherwise just use raw addresses. Returns true |
+// if any symbol name is resolved. |
+bool GetBacktraceStrings(void **trace, int size, |
+ std::vector<std::string>* trace_strings) { |
+ bool symbolized = false; |
+ |
+#if defined(USE_SYMBOLIZE) |
+ for (int i = 0; i < size; ++i) { |
+ char symbol[1024]; |
+ // Subtract by one as return address of function may be in the next |
+ // function when a function is annotated as noreturn. |
+ if (google::Symbolize(static_cast<char *>(trace[i]) - 1, |
+ symbol, sizeof(symbol))) { |
+ // Don't call DemangleSymbols() here as the symbol is demangled by |
+ // google::Symbolize(). |
+ trace_strings->push_back(StringPrintf("%s [%p]", symbol, trace[i])); |
+ symbolized = true; |
+ } else { |
+ trace_strings->push_back(StringPrintf("%p", trace[i])); |
+ } |
+ } |
+#else |
+ scoped_ptr_malloc<char*> trace_symbols(backtrace_symbols(trace, size)); |
+ if (trace_symbols.get()) { |
+ for (int i = 0; i < size; ++i) { |
+ std::string trace_symbol = trace_symbols.get()[i]; |
+ DemangleSymbols(&trace_symbol); |
+ trace_strings->push_back(trace_symbol); |
+ } |
+ symbolized = true; |
+ } else { |
+ for (int i = 0; i < size; ++i) { |
+ trace_strings->push_back(StringPrintf("%p", trace[i])); |
+ } |
+ } |
+#endif // defined(USE_SYMBOLIZE) |
+ |
+ return symbolized; |
+} |
+ |
} // namespace |
// static |
@@ -209,7 +257,11 @@ void StackTrace::PrintBacktrace() { |
return; |
#endif |
fflush(stderr); |
- backtrace_symbols_fd(trace_, count_, STDERR_FILENO); |
+ std::vector<std::string> trace_strings; |
+ GetBacktraceStrings(trace_, count_, &trace_strings); |
+ for (size_t i = 0; i < trace_strings.size(); ++i) { |
+ std::cerr << "\t" << trace_strings[i] << "\n"; |
+ } |
} |
void StackTrace::OutputToStream(std::ostream* os) { |
@@ -217,22 +269,15 @@ void StackTrace::OutputToStream(std::ostream* os) { |
if (backtrace_symbols == NULL) |
return; |
#endif |
- scoped_ptr_malloc<char*> trace_symbols(backtrace_symbols(trace_, count_)); |
- |
- // If we can't retrieve the symbols, print an error and just dump the raw |
- // addresses. |
- if (trace_symbols.get() == NULL) { |
+ std::vector<std::string> trace_strings; |
+ if (GetBacktraceStrings(trace_, count_, &trace_strings)) { |
+ (*os) << "Backtrace:\n"; |
+ } else { |
(*os) << "Unable get symbols for backtrace (" << safe_strerror(errno) |
<< "). Dumping raw addresses in trace:\n"; |
- for (int i = 0; i < count_; ++i) { |
- (*os) << "\t" << trace_[i] << "\n"; |
- } |
- } else { |
- (*os) << "Backtrace:\n"; |
- for (int i = 0; i < count_; ++i) { |
- std::string trace_symbol(trace_symbols.get()[i]); |
- DemangleSymbols(&trace_symbol); |
- (*os) << "\t" << trace_symbol << "\n"; |
- } |
+ } |
+ |
+ for (size_t i = 0; i < trace_strings.size(); ++i) { |
+ (*os) << "\t" << trace_strings[i] << "\n"; |
} |
} |