From e31fdc2350fbb73be0e66e9a0fdbb06468bd4746 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Tue, 14 Mar 2006 18:20:58 +0000 Subject: [PATCH] Demangle stacktraces whenever possible git-svn-id: https://svn.dealii.org/trunk@12582 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/base/source/exceptions.cc | 69 +++++++++++++++++++++++++++++-- deal.II/doc/news/changes.html | 16 ++++--- 2 files changed, 76 insertions(+), 9 deletions(-) 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.
    +
  1. Improved: If the C++ runtime environment allows it, we now + demangle stacktraces generated whenever an exception is thrown. +
    + (WB 2006/03/14) +

    +
  2. 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) +

  3. Fixed: Writing a denormal "NaN" through LogStream objects such as -- 2.39.5