summaryrefslogtreecommitdiffstats
path: root/base/debug_util_posix.cc
diff options
context:
space:
mode:
authorevan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-14 03:01:44 +0000
committerevan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-14 03:01:44 +0000
commit79b6fa6123a8877eb25a600a01a8a0fd3de7560e (patch)
tree3e9d16818541dbbf8c0a40764549498d4a6d9913 /base/debug_util_posix.cc
parent63596301ddb6f3f6192dce7e81cf5722312c1433 (diff)
downloadchromium_src-79b6fa6123a8877eb25a600a01a8a0fd3de7560e.zip
chromium_src-79b6fa6123a8877eb25a600a01a8a0fd3de7560e.tar.gz
chromium_src-79b6fa6123a8877eb25a600a01a8a0fd3de7560e.tar.bz2
Demangle C++ symbols in stack traces for Linux.
My first Chromium linux build greeted me with a backtrace of mangled symbols (FWIW, my /dev/shm permission was wrong). That made me write this patch. BEFORE: ../sconsbuild/Debug/base_unittests(_ZN10StackTraceC1Ev+0x20) [0x817795e] ../sconsbuild/Debug/base_unittests(_ZN30StackTrace_OutputToStream_Test8TestBodyEv+0x18) [0x805fc98] ../sconsbuild/Debug/base_unittests(_ZN7testing4Test3RunEv+0x7e) [0x82005ea] AFTER: ../sconsbuild/Debug/base_unittests(StackTrace::StackTrace()+0x20) [0x817778c] ../sconsbuild/Debug/base_unittests(StackTrace_OutputToStream_Test::TestBody()+0x18) [0x805fc98] ../sconsbuild/Debug/base_unittests(testing::Test::Run()+0x7e) [0x8200786] BUG=none TEST=manually tested. also ran base_unittests Review URL: http://codereview.chromium.org/267074 Patch from Satoru Takabayashi <satorux@gmail.com>. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@28940 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/debug_util_posix.cc')
-rw-r--r--base/debug_util_posix.cc67
1 files changed, 66 insertions, 1 deletions
diff --git a/base/debug_util_posix.cc b/base/debug_util_posix.cc
index 4b79d73..20916a0 100644
--- a/base/debug_util_posix.cc
+++ b/base/debug_util_posix.cc
@@ -13,6 +13,12 @@
#include <sys/types.h>
#include <unistd.h>
+#if defined(__GLIBCXX__)
+#include <cxxabi.h>
+#endif
+
+#include <string>
+
#if defined(OS_MACOSX)
#include <AvailabilityMacros.h>
#endif
@@ -25,6 +31,63 @@
#include "base/scoped_ptr.h"
#include "base/string_piece.h"
+namespace {
+// The prefix used for mangled symbols, per the Itanium C++ ABI:
+// http://www.codesourcery.com/cxx-abi/abi.html#mangling
+const char kMangledSymbolPrefix[] = "_Z";
+
+// Characters that can be used for symbols, generated by Ruby:
+// (('a'..'z').to_a+('A'..'Z').to_a+('0'..'9').to_a + ['_']).join
+const char kSymbolCharacters[] =
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
+
+// Demangles C++ symbols in the given text. Example:
+//
+// "sconsbuild/Debug/base_unittests(_ZN10StackTraceC1Ev+0x20) [0x817778c]"
+// =>
+// "sconsbuild/Debug/base_unittests(StackTrace::StackTrace()+0x20) [0x817778c]"
+void DemangleSymbols(std::string* text) {
+#if defined(__GLIBCXX__)
+
+ std::string::size_type search_from = 0;
+ while (search_from < text->size()) {
+ // Look for the start of a mangled symbol, from search_from.
+ std::string::size_type mangled_start =
+ text->find(kMangledSymbolPrefix, search_from);
+ if (mangled_start == std::string::npos) {
+ break; // Mangled symbol not found.
+ }
+
+ // Look for the end of the mangled symbol.
+ std::string::size_type mangled_end =
+ text->find_first_not_of(kSymbolCharacters, mangled_start);
+ if (mangled_end == std::string::npos) {
+ mangled_end = text->size();
+ }
+ std::string mangled_symbol =
+ text->substr(mangled_start, mangled_end - mangled_start);
+
+ // Try to demangle the mangled symbol candidate.
+ int status = 0;
+ scoped_ptr_malloc<char> demangled_symbol(
+ abi::__cxa_demangle(mangled_symbol.c_str(), NULL, 0, &status));
+ if (status == 0) { // Demangling is successful.
+ // Remove the mangled symbol.
+ text->erase(mangled_start, mangled_end - mangled_start);
+ // Insert the demangled symbol.
+ text->insert(mangled_start, demangled_symbol.get());
+ // Next time, we'll start right after the demangled symbol we inserted.
+ search_from = mangled_start + strlen(demangled_symbol.get());
+ } else {
+ // Failed to demangle. Retry after the "_Z" we just found.
+ search_from = mangled_start + 2;
+ }
+ }
+
+#endif // defined(__GLIBCXX__)
+}
+} // namespace
+
// static
bool DebugUtil::SpawnDebuggerOnProcess(unsigned /* process_id */) {
NOTIMPLEMENTED();
@@ -159,7 +222,9 @@ void StackTrace::OutputToStream(std::ostream* os) {
} else {
(*os) << "Backtrace:\n";
for (int i = 0; i < count_; ++i) {
- (*os) << "\t" << trace_symbols.get()[i] << "\n";
+ std::string trace_symbol(trace_symbols.get()[i]);
+ DemangleSymbols(&trace_symbol);
+ (*os) << "\t" << trace_symbol << "\n";
}
}
}