From: Wolfgang Bangerth Date: Thu, 30 Jun 2005 20:56:31 +0000 (+0000) Subject: Record the stacktrace at the same time and place where we also record X-Git-Tag: v8.0.0~13539 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1e08d0a3a965c7abb2168f5fd3acd572a2b88681;p=dealii.git Record the stacktrace at the same time and place where we also record all the other information, i.e. when called from the place where the exception (through Assert or AssertThrow) is generated, not where it is caught. git-svn-id: https://svn.dealii.org/trunk@11017 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/base/include/base/exceptions.h b/deal.II/base/include/base/exceptions.h index 31b1e31262..312407fad2 100644 --- a/deal.II/base/include/base/exceptions.h +++ b/deal.II/base/include/base/exceptions.h @@ -365,12 +365,6 @@ class ExceptionBase : public std::exception */ 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 @@ -386,13 +380,24 @@ class ExceptionBase : public std::exception * exception occured as well as user * information. * - * This function is mainly used when using - * exceptions declared by the - * DeclException* macros with the throw - * mechanism or the AssertThrow macro. + * This function is mainly used + * when using exceptions + * declared by the + * DeclException* + * macros with the + * throw mechanism or + * the AssertThrow + * 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. @@ -418,6 +423,22 @@ class ExceptionBase : public std::exception * 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; }; diff --git a/deal.II/base/source/exceptions.cc b/deal.II/base/source/exceptions.cc index 36095e85d3..88e2e02c88 100644 --- a/deal.II/base/source/exceptions.cc +++ b/deal.II/base/source/exceptions.cc @@ -31,7 +31,9 @@ ExceptionBase::ExceptionBase () : - file(""), line(0), function(""), cond(""), exc("") + file(""), line(0), function(""), cond(""), exc(""), + stacktrace (0), + n_stacktrace_frames (0) {} @@ -39,13 +41,18 @@ ExceptionBase::ExceptionBase () 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); +} @@ -60,35 +67,21 @@ void ExceptionBase::set_fields (const char* f, 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 @@ -98,20 +91,32 @@ void ExceptionBase::print_stack_trace (std::ostream &out) const // 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; } @@ -161,6 +166,8 @@ const char * ExceptionBase::what () const throw () // put in exception specific data print_info (converter); + print_stack_trace (converter); + converter << "--------------------------------------------------------" << std::endl; #ifndef HAVE_STD_STRINGSTREAM