From: Wolfgang Bangerth
Date: Tue, 14 Mar 2006 18:20:58 +0000 (+0000)
Subject: Demangle stacktraces whenever possible
X-Git-Tag: v8.0.0~12113
X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e31fdc2350fbb73be0e66e9a0fdbb06468bd4746;p=dealii.git
Demangle stacktraces whenever possible
git-svn-id: https://svn.dealii.org/trunk@12582 0785d39b-7218-0410-832d-ea1e28bc413d
---
diff --git a/deal.II/base/source/exceptions.cc b/deal.II/base/source/exceptions.cc
index 192c390953..fe688670f1 100644
--- a/deal.II/base/source/exceptions.cc
+++ b/deal.II/base/source/exceptions.cc
@@ -22,6 +22,10 @@
# include
#endif
+#ifdef HAVE_LIBSTDCXX_DEMANGLER
+# include
+#endif
+
namespace deal_II_exceptions
{
@@ -154,10 +158,67 @@ void ExceptionBase::print_stack_trace (std::ostream &out) const
// output the rest
const unsigned int first_significant_frame = frame;
for (; frame < n_stacktrace_frames; ++frame)
- out << '#' << frame - first_significant_frame
- << " "
- << stacktrace[frame]
- << std::endl;
+ {
+ out << '#' << frame - first_significant_frame
+ << " ";
+
+ // the stacktrace frame is
+ // actually of the format
+ // "filename(functionname+offset)
+ // [address]". let's try to
+ // get the mangled
+ // functionname out:
+ std::string stacktrace_entry (stacktrace[frame]);
+ const unsigned int pos_start = stacktrace_entry.find('('),
+ pos_end = stacktrace_entry.find('+');
+ std::string functionname = stacktrace_entry.substr (pos_start+1,
+ pos_end-pos_start-1);
+
+ // demangle, and if successful
+ // replace old mangled string
+ // by unmangled one (skipping
+ // address and offset). treat
+ // "main" differently, since
+ // it is apparently demangled
+ // as "unsigned int" for
+ // unknown reasons :-)
+ // if we can, demangle the
+ // function name
+#ifdef HAVE_LIBSTDCXX_DEMANGLER
+ int status;
+ char *realname;
+
+ realname = abi::__cxa_demangle(functionname.c_str(), 0, 0, &status);
+ if ((status == 0) && (functionname != "main"))
+ stacktrace_entry = stacktrace_entry.substr(0, pos_start)
+ +
+ ": "
+ +
+ realname;
+ else
+ stacktrace_entry = stacktrace_entry.substr(0, pos_start)
+ +
+ ": "
+ +
+ functionname;
+
+ // free memory allocated by
+ // the demangler
+ free (realname);
+
+#else
+
+ stacktrace_entry = stacktrace_entry.substr(0, pos_start)
+ +
+ ": "
+ +
+ functionname;
+#endif
+
+ // then output what we have
+ out << stacktrace_entry
+ << std::endl;
+ }
}
diff --git a/deal.II/doc/news/changes.html b/deal.II/doc/news/changes.html
index bdccf3f67c..8eb0ad7a3f 100644
--- a/deal.II/doc/news/changes.html
+++ b/deal.II/doc/news/changes.html
@@ -259,12 +259,18 @@ inconvenience this causes.
+ -
Improved: If the C++ runtime environment allows it, we now
+ demangle stacktraces generated whenever an exception is thrown.
+
+ (WB 2006/03/14)
+
+
-
Improved: The function Subscriptor
::list_subscribers
logs all current subscribers of an
- object to deallog.
-
- (GK 2006/03/08)
-
+ class="member">list_subscribers logs all current subscribers of an
+ object to deallog.
+
+ (GK 2006/03/08)
+
Fixed: Writing a denormal "NaN" through LogStream
objects such as