*/
void print_exc_data (std::ostream &out) const;
- /**
- * Print out the stacktrace (if available)
- * at the time the exception is created
- */
- void print_stack_trace (std::ostream &out) const;
-
/**
* Print more specific information about the
* exception which occured. Overload this
* exception occured as well as user
* information.
*
- * This function is mainly used when using
- * exceptions declared by the
- * <tt>DeclException*</tt> macros with the <tt>throw</tt>
- * mechanism or the <tt>AssertThrow</tt> macro.
+ * This function is mainly used
+ * when using exceptions
+ * declared by the
+ * <tt>DeclException*</tt>
+ * macros with the
+ * <tt>throw</tt> mechanism or
+ * the <tt>AssertThrow</tt>
+ * macro.
*/
virtual const char * what () const throw ();
+ /**
+ * Print a stacktrace, if one has
+ * been recorded previously, to
+ * the given stream.
+ */
+ void print_stack_trace (std::ostream &out) const;
+
protected:
/**
* Name of the file this exception happen in.
* Name of the exception and call sequence.
*/
const char *exc;
+
+ /**
+ * A backtrace to the position
+ * where the problem happened, if
+ * the system supports this.
+ */
+ char ** stacktrace;
+
+ /**
+ * The number of stacktrace
+ * frames that are stored in the
+ * previous variable. Zero if the
+ * system does not support stack
+ * traces.
+ */
+ int n_stacktrace_frames;
};
ExceptionBase::ExceptionBase ()
:
- file(""), line(0), function(""), cond(""), exc("")
+ file(""), line(0), function(""), cond(""), exc(""),
+ stacktrace (0),
+ n_stacktrace_frames (0)
{}
ExceptionBase::ExceptionBase (const char* f, const int l, const char *func,
const char* c, const char *e)
:
- file(f), line(l), function(func), cond(c), exc(e)
+ file(f), line(l), function(func), cond(c), exc(e),
+ stacktrace (0),
+ n_stacktrace_frames (0)
{}
ExceptionBase::~ExceptionBase () throw ()
-{}
+{
+ if (backtrace != 0)
+ free (stacktrace);
+}
function = func;
cond = c;
exc = e;
-}
-
-
-void ExceptionBase::print_exc_data (std::ostream &out) const
-{
- out << "An error occurred in line <" << line
- << "> of file <" << file
- << "> in function" << std::endl
- << " " << function << std::endl
- << "The violated condition was: "<< std::endl
- << " " << cond << std::endl
- << "The name and call sequence of the exception was:" << std::endl
- << " " << exc << std::endl
- << "Additional Information: " << std::endl;
+ // if the system supports this, get
+ // a stacktrace how we got here
+#ifdef HAVE_GLIBC_STACKTRACE
+ void * array[25];
+ n_stacktrace_frames = backtrace(array, 25);
+ stacktrace = backtrace_symbols(array, n_stacktrace_frames);
+#endif
}
void ExceptionBase::print_stack_trace (std::ostream &out) const
{
-#ifdef HAVE_GLIBC_STACKTRACE
- out << "Stacktrace:" << std::endl;
-
- void * array[25];
- const int n_frames = backtrace(array, 25);
- char ** symbols = backtrace_symbols(array, n_frames);
-
- // print the stacktraces. first
+ // print the stacktrace. first
// omit all those frames that have
// ExceptionBase or
// deal_II_exceptions in their
// place where the exception was
// triggered
int frame = 0;
- while ((frame < n_frames)
+ while ((frame < n_stacktrace_frames)
&&
- ((std::string(symbols[frame]).find ("ExceptionBase") != std::string::npos)
+ ((std::string(stacktrace[frame]).find ("ExceptionBase") != std::string::npos)
||
- (std::string(symbols[frame]).find ("deal_II_exceptions") != std::string::npos)))
+ (std::string(stacktrace[frame]).find ("deal_II_exceptions") != std::string::npos)))
++frame;
// output the rest
- for (; frame < n_frames; ++frame)
- out << symbols[frame]
+ for (; frame < n_stacktrace_frames; ++frame)
+ out << stacktrace[frame]
<< std::endl;
+}
- free(symbols);
-#endif
+
+
+void ExceptionBase::print_exc_data (std::ostream &out) const
+{
+ out << "An error occurred in line <" << line
+ << "> of file <" << file
+ << "> in function" << std::endl
+ << " " << function << std::endl
+ << "The violated condition was: "<< std::endl
+ << " " << cond << std::endl
+ << "The name and call sequence of the exception was:" << std::endl
+ << " " << exc << std::endl
+ << "Additional Information: " << std::endl;
}
// put in exception specific data
print_info (converter);
+ print_stack_trace (converter);
+
converter << "--------------------------------------------------------"
<< std::endl;
#ifndef HAVE_STD_STRINGSTREAM