Chromium Code Reviews| 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"; |
| } |
| } |