From: Wolfgang Bangerth Date: Thu, 10 Jan 2002 10:17:54 +0000 (+0000) Subject: Allow printing more information if an assertion is triggered. X-Git-Tag: v8.0.0~18463 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1ab45fa8fa0e1d7a0298d34f79ce1b0b97aed20f;p=dealii.git Allow printing more information if an assertion is triggered. git-svn-id: https://svn.dealii.org/trunk@5372 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/base/include/base/exceptions.h b/deal.II/base/include/base/exceptions.h index 1562f89aa4..24b099fcfd 100644 --- a/deal.II/base/include/base/exceptions.h +++ b/deal.II/base/include/base/exceptions.h @@ -409,13 +409,54 @@ class ExceptionBase : public std::exception /** * In this namespace functions in connection with the Assert and - * AssertThrow mechanism are declared. They are solely for internal - * purposes and are not for use outside the exception handling and - * throwing mechanism. + * AssertThrow mechanism are declared. */ -namespace deal_II_exception_internals +namespace deal_II_exceptions { + /** + * Set a string that is printed + * upon output of the message + * indicating a triggered + * @p{Assert} statement. This + * string, which is printed in + * addition to the usual output may + * indicate information that is + * otherwise not readily available + * unless we are using a + * debugger. For example, with + * distributed programs on cluster + * computers, the output of all + * processes is redirected to the + * same console window. In this + * case, it is convenient to set as + * additional name the name of the + * host on which the program runs, + * so that one can see in which + * instance of the program the + * exception occured. + * + * The string pointed to by the + * argument is copied, so needs not + * be stored after the call to this + * function. + * + * Previously set additional output + * is replaced by the argument + * given to this function. + */ + void set_additional_assert_output (const char * const p); + + +/** + * The functions in this namespace are in connection with the Assert + * and AssertThrow mechanism but are solely for internal purposes and + * are not for use outside the exception handling and throwing + * mechanism. + */ + namespace internals + { + /** * Relay exceptions from the @p{Assert} macro to the * @p{__IssueError_Assert} function. Used to convert the last @@ -426,18 +467,18 @@ namespace deal_II_exception_internals * * @see ExceptionBase */ - template - inline - void issue_error_assert_1 (const char *file, - int line, - const char *function, - const char *cond, - const char *exc_name, - exc e) - { - issue_error_assert (file,line,function,cond,exc_name,e); - }; - + template + inline + void issue_error_assert_1 (const char *file, + int line, + const char *function, + const char *cond, + const char *exc_name, + exc e) + { + issue_error_assert (file,line,function,cond,exc_name,e); + }; + /** @@ -447,12 +488,12 @@ namespace deal_II_exception_internals * * @see ExceptionBase */ - void issue_error_assert (const char *file, - int line, - const char *function, - const char *cond, - const char *exc_name, - ExceptionBase & e); + void issue_error_assert (const char *file, + int line, + const char *function, + const char *cond, + const char *exc_name, + ExceptionBase & e); /** @@ -462,20 +503,20 @@ namespace deal_II_exception_internals * * @see ExceptionBase */ - template - void issue_error_throw (const char *file, - int line, - const char *function, - const char *cond, - const char *exc_name, - exc e) - { - // Fill the fields of the - // exception object - e.SetFields (file, line, function, cond, exc_name); - throw e; - }; - + template + void issue_error_throw (const char *file, + int line, + const char *function, + const char *cond, + const char *exc_name, + exc e) + { + // Fill the fields of the + // exception object + e.SetFields (file, line, function, cond, exc_name); + throw e; + }; + /** * Abort the program. This function is used so that we need not @@ -483,10 +524,14 @@ namespace deal_II_exception_internals * other files of the library and we would like to keep its include * list as short as possible. */ - void abort (); + void abort (); + + }; + }; + #ifdef DEBUG //////////////////////////////////////// /** @@ -502,7 +547,7 @@ namespace deal_II_exception_internals #define Assert(cond, exc) \ { \ if (!(cond)) \ - deal_II_exception_internals:: \ + deal_II_exceptions::internals:: \ issue_error_assert_1 (__FILE__, \ __LINE__, \ __PRETTY_FUNCTION__, #cond, #exc, exc);\ @@ -541,7 +586,7 @@ namespace deal_II_exception_internals #define AssertThrow(cond, exc) \ { \ if (!(cond)) \ - deal_II_exception_internals:: \ + deal_II_exceptions::internals:: \ issue_error_throw (__FILE__, \ __LINE__, \ __PRETTY_FUNCTION__, #cond, #exc, exc); \ @@ -550,7 +595,7 @@ namespace deal_II_exception_internals #define AssertThrow(cond, exc) \ { \ if (!(cond)) \ - deal_II_exception_internals::abort (); \ + deal_II_exceptions::internals::abort (); \ } #endif diff --git a/deal.II/base/source/exceptions.cc b/deal.II/base/source/exceptions.cc index a587895c1b..47d07c242b 100644 --- a/deal.II/base/source/exceptions.cc +++ b/deal.II/base/source/exceptions.cc @@ -122,82 +122,106 @@ const char * ExceptionBase::what () const throw () -namespace deal_II_exception_internals +namespace deal_II_exceptions { - /** - * Number of exceptions dealt - * with so far. Zero at program - * start. Messages are only - * displayed if the value is - * zero. - */ - static unsigned int n_treated_exceptions; - + std::string additional_assert_output; - void issue_error_assert (const char *file, - int line, - const char *function, - const char *cond, - const char *exc_name, - ExceptionBase & e) + void set_additional_assert_output (const char * const p) + { + additional_assert_output = p; + }; + + + + namespace internals { - // fill the fields of the exception object - e.SetFields (file, line, function, cond, exc_name); - // if no other exception has been - // displayed before, show this one - if (n_treated_exceptions == 0) - { - std::cerr << "--------------------------------------------------------" - << std::endl; - // print out general data - e.PrintExcData (std::cerr); - // print out exception specific data - e.PrintInfo (std::cerr); - std::cerr << "--------------------------------------------------------" - << std::endl; - } - else - { - // if this is the first - // follow-up message, display a - // message that further - // exceptions are suppressed - if (n_treated_exceptions == 1) - std::cerr << "******** More assertions fail but messages are suppressed! ********" + /** + * Number of exceptions dealt + * with so far. Zero at program + * start. Messages are only + * displayed if the value is + * zero. + */ + static unsigned int n_treated_exceptions; + + + void issue_error_assert (const char *file, + int line, + const char *function, + const char *cond, + const char *exc_name, + ExceptionBase & e) + { + // fill the fields of the + // exception object + e.SetFields (file, line, function, cond, exc_name); + + // if no other exception has + // been displayed before, show + // this one + if (n_treated_exceptions == 0) + { + std::cerr << "--------------------------------------------------------" << std::endl; - }; - - // increase number of treated - // exceptions by one - n_treated_exceptions++; + // print out general data + e.PrintExcData (std::cerr); + // print out exception + // specific data + e.PrintInfo (std::cerr); + std::cerr << "--------------------------------------------------------" + << std::endl; + + // if there is more to say, + // do so + if (!additional_assert_output.empty()) + std::cerr << additional_assert_output << std::endl; + } + else + { + // if this is the first + // follow-up message, + // display a message that + // further exceptions are + // suppressed + if (n_treated_exceptions == 1) + std::cerr << "******** More assertions fail but messages are suppressed! ********" + << std::endl; + }; + + // increase number of treated + // exceptions by one + n_treated_exceptions++; - // abort the program now since - // something has gone horribly - // wrong. however, there is one - // case where we do not want to do - // that, namely when another - // exception, possibly thrown by - // AssertThrow is active, since in - // that case we will not come to - // see the original exception. in - // that case indicate that the - // program is not aborted due to - // this reason. - if (std::uncaught_exception() == true) - std::cerr << "******** Program is not aborted since another exception is active! ********" - << std::endl; - else - std::abort (); - }; + // abort the program now since + // something has gone horribly + // wrong. however, there is one + // case where we do not want to + // do that, namely when another + // exception, possibly thrown + // by AssertThrow is active, + // since in that case we will + // not come to see the original + // exception. in that case + // indicate that the program is + // not aborted due to this + // reason. + if (std::uncaught_exception() == true) + std::cerr << "******** Program is not aborted since another exception is active! ********" + << std::endl; + else + std::abort (); + }; - void abort () - { - std::abort (); + void abort () + { + std::abort (); + }; + }; };