*/
namespace deal_II_exceptions
{
+ /**
+ * Setting this variable to false will disable deal.II's exception mechanism
+ * to abort the problem. The Assert() macro will throw the exception instead
+ * and the AssertNothrow() macro will just print the error message. This
+ * variable should not be changed directly. Use disable_abort_on_exception()
+ * instead.
+ */
+ extern bool allow_abort_on_exception;
+
/**
* Set a string that is printed upon output of the message indicating a
* triggered <tt>Assert</tt> statement. This string, which is printed in
namespace internals
{
/**
- * Conditionally abort the program.
- *
- * Depending on whether deal_II_exceptions::disable_abort_on_exception was
- * called, this function either aborts the program flow by printing the
- * error message provided by @p exc and calling <tt>std::abort()</tt>, or
- * throws @p exc instead.
+ * Abort the program by printing the
+ * error message provided by @p exc and calling <tt>std::abort()</tt>.
*/
[[noreturn]] void
- abort(const ExceptionBase &exc);
+ internal_abort(const ExceptionBase &exc) noexcept;
/**
- * An enum describing how to treat an exception in issue_error.
+ * An enum describing how to treat an exception in issue_error_noreturn.
*/
enum ExceptionHandling
{
* deal_II_exceptions::disable_abort_on_exception has been called: in
* that case the program will throw an exception.
*/
- abort_on_exception,
+ try_abort_on_exception,
/**
* Throw the exception normally.
*/
- throw_on_exception,
- /**
- * Call <code>std::abort</code> as long as
- * deal_II_exceptions::disable_abort_on_exception has not been called:
- * if it has, then just print a description of the exception to deallog.
- */
- abort_nothrow_on_exception
+ throw_on_exception
};
/**
* This routine does the main work for the exception generation mechanism
* used in the <tt>Assert</tt> and <tt>AssertThrow</tt> macros: as the
- * name implies, this function either ends with a call to <tt>abort</tt>
- * or throwing an exception.
+ * name implies, this function either ends throwing an exception (if
+ * @p handling is throw_on_exception, or @p handling is try_abort_exception
+ * and deal_II_exceptions::disable_abort_on_exception is false) or with a
+ * call to <tt>abort</tt> (if @p handling is try_abort_exception and
+ * deal_II_exceptions::disable_abort_on_exception is true).
*
* The actual exception object (the last argument) is typically an unnamed
* object created in place; because we modify it, we can't take it by
switch (handling)
{
- case abort_on_exception:
- dealii::deal_II_exceptions::internals::abort(e);
+ case try_abort_on_exception:
+ {
+ if (dealii::deal_II_exceptions::allow_abort_on_exception)
+ internals::internal_abort(e);
+ else
+ {
+ // We are not allowed to abort, so just throw the error:
+ throw e;
+ }
+ }
case throw_on_exception:
throw e;
// this function should never return (and AssertNothrow can);
// something must have gone wrong in the error handling code for us
// to get this far, so throw an exception.
- case abort_nothrow_on_exception:
default:
throw ::dealii::StandardExceptions::ExcInternalError();
}
*/
template <class ExceptionType>
void
- issue_error_nothrow(ExceptionHandling,
- const char * file,
+ issue_error_nothrow(const char * file,
int line,
const char * function,
const char * cond,
*/
#ifdef DEBUG
# ifdef DEAL_II_HAVE_BUILTIN_EXPECT
-# define Assert(cond, exc) \
- { \
- if (__builtin_expect(!(cond), false)) \
- ::dealii::deal_II_exceptions::internals::issue_error_noreturn( \
- ::dealii::deal_II_exceptions::internals::abort_on_exception, \
- __FILE__, \
- __LINE__, \
- __PRETTY_FUNCTION__, \
- #cond, \
- #exc, \
- exc); \
+# define Assert(cond, exc) \
+ { \
+ if (__builtin_expect(!(cond), false)) \
+ ::dealii::deal_II_exceptions::internals::issue_error_noreturn( \
+ ::dealii::deal_II_exceptions::internals::try_abort_on_exception, \
+ __FILE__, \
+ __LINE__, \
+ __PRETTY_FUNCTION__, \
+ #cond, \
+ #exc, \
+ exc); \
}
# else /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
-# define Assert(cond, exc) \
- { \
- if (!(cond)) \
- ::dealii::deal_II_exceptions::internals::issue_error_noreturn( \
- ::dealii::deal_II_exceptions::internals::abort_on_exception, \
- __FILE__, \
- __LINE__, \
- __PRETTY_FUNCTION__, \
- #cond, \
- #exc, \
- exc); \
+# define Assert(cond, exc) \
+ { \
+ if (!(cond)) \
+ ::dealii::deal_II_exceptions::internals::issue_error_noreturn( \
+ ::dealii::deal_II_exceptions::internals::try_abort_on_exception, \
+ __FILE__, \
+ __LINE__, \
+ __PRETTY_FUNCTION__, \
+ #cond, \
+ #exc, \
+ exc); \
}
# endif /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
#else
{ \
if (__builtin_expect(!(cond), false)) \
::dealii::deal_II_exceptions::internals::issue_error_nothrow( \
- ::dealii::deal_II_exceptions::internals:: \
- abort_nothrow_on_exception, \
- __FILE__, \
- __LINE__, \
- __PRETTY_FUNCTION__, \
- #cond, \
- #exc, \
- exc); \
+ __FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #exc, exc); \
}
# else /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
# define AssertNothrow(cond, exc) \
{ \
if (!(cond)) \
::dealii::deal_II_exceptions::internals::issue_error_nothrow( \
- ::dealii::deal_II_exceptions::internals:: \
- abort_nothrow_on_exception, \
- __FILE__, \
- __LINE__, \
- __PRETTY_FUNCTION__, \
- #cond, \
- #exc, \
- exc); \
+ __FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #exc, exc); \
}
# endif /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
#else
show_stacktrace = false;
}
- bool abort_on_exception = true;
+ bool allow_abort_on_exception = true;
void
disable_abort_on_exception()
{
- abort_on_exception = false;
+ allow_abort_on_exception = false;
}
} // namespace deal_II_exceptions
} // namespace StandardExceptions
#endif // DEAL_II_WITH_MPI
-namespace
+namespace deal_II_exceptions
{
- [[noreturn]] void
- internal_abort(const ExceptionBase &exc) noexcept
+ namespace internals
{
- // first print the error
- std::cerr << exc.what() << std::endl;
-
- // then bail out. if in MPI mode, bring down the entire
- // house by asking the MPI system to do a best-effort
- // operation at also terminating all of the other MPI
- // processes. this is useful because if only one process
- // runs into an assertion, then that may lead to deadlocks
- // if the others don't recognize this, or at the very least
- // delay their termination until they realize that their
- // communication with the job that died times out.
- //
- // Unlike std::abort(), MPI_Abort() unfortunately doesn't break when
- // running inside a debugger like GDB, so only use this strategy if
- // absolutely necessary and inform the user how to use a debugger.
+ [[noreturn]] void
+ internal_abort(const ExceptionBase &exc) noexcept
+ {
+ // first print the error
+ std::cerr << exc.what() << std::endl;
+
+ // then bail out. if in MPI mode, bring down the entire
+ // house by asking the MPI system to do a best-effort
+ // operation at also terminating all of the other MPI
+ // processes. this is useful because if only one process
+ // runs into an assertion, then that may lead to deadlocks
+ // if the others don't recognize this, or at the very least
+ // delay their termination until they realize that their
+ // communication with the job that died times out.
+ //
+ // Unlike std::abort(), MPI_Abort() unfortunately doesn't break when
+ // running inside a debugger like GDB, so only use this strategy if
+ // absolutely necessary and inform the user how to use a debugger.
#ifdef DEAL_II_WITH_MPI
- int is_initialized;
- MPI_Initialized(&is_initialized);
- if (is_initialized)
- {
- // do the same as in Utilities::MPI::n_mpi_processes() here,
- // but without error checking to not throw again.
- const int n_proc = Utilities::MPI::n_mpi_processes(MPI_COMM_WORLD);
- if (n_proc > 1)
- {
- std::cerr
- << "Calling MPI_Abort now.\n"
- << "To break execution in a GDB session, execute 'break MPI_Abort' before "
- << "running. You can also put the following into your ~/.gdbinit:\n"
- << " set breakpoint pending on\n"
- << " break MPI_Abort\n"
- << " set breakpoint pending auto" << std::endl;
-
- MPI_Abort(MPI_COMM_WORLD,
- /* return code = */ 255);
- }
- }
+ int is_initialized;
+ MPI_Initialized(&is_initialized);
+ if (is_initialized)
+ {
+ // do the same as in Utilities::MPI::n_mpi_processes() here,
+ // but without error checking to not throw again.
+ const int n_proc = Utilities::MPI::n_mpi_processes(MPI_COMM_WORLD);
+ if (n_proc > 1)
+ {
+ std::cerr
+ << "Calling MPI_Abort now.\n"
+ << "To break execution in a GDB session, execute 'break MPI_Abort' before "
+ << "running. You can also put the following into your ~/.gdbinit:\n"
+ << " set breakpoint pending on\n"
+ << " break MPI_Abort\n"
+ << " set breakpoint pending auto" << std::endl;
+
+ MPI_Abort(MPI_COMM_WORLD,
+ /* return code = */ 255);
+ }
+ }
#endif
- std::abort();
- }
-} // namespace
+ std::abort();
+ }
+
+
-namespace deal_II_exceptions
-{
- namespace internals
- {
void
do_issue_error_nothrow(const ExceptionBase &exc) noexcept
{
- if (dealii::deal_II_exceptions::abort_on_exception)
+ if (dealii::deal_II_exceptions::allow_abort_on_exception)
internal_abort(exc);
else
{
- [[noreturn]] void
- abort(const ExceptionBase &exc) {
- if (dealii::deal_II_exceptions::abort_on_exception)
- internal_abort(exc);
- else
- {
- // We are not allowed to abort, so just throw the error:
- throw exc;
- }
- }
-
-
-
#ifdef DEAL_II_WITH_CUDA
- std::string get_cusparse_error_string(const cusparseStatus_t error_code)
+ std::string
+ get_cusparse_error_string(const cusparseStatus_t error_code)
{
switch (error_code)
{
The violated condition was:
subsection_path.size() != 0
Additional information:
- (none)
+ You can't leave a subsection if you are already at the top level of the subsection hierarchy.
--------------------------------------------------------
DEAL::
DEAL::* parse_input with missing 'end':
-DEAL::ExcUnbalancedSubsections (filename, paths_message.str())
+DEAL::ExcUnbalancedSubsections(filename, paths_message.str())
There are unequal numbers of 'subsection' and 'end' statements in the parameter file <input string>.
DEAL::
DEAL::Exception
The violated condition was:
subsection_path.size() != 0
Additional information:
- (none)
+ You can't leave a subsection if you are already at the top level of the subsection hierarchy.
--------------------------------------------------------
DEAL::
DEAL::* Check non empty path before parse_input()
DEAL::
DEAL::* Check parse_input() catches messing with path:
-DEAL::ExcUnbalancedSubsections (filename, paths_message.str())
+DEAL::ExcUnbalancedSubsections(filename, paths_message.str())
There are unequal numbers of 'subsection' and 'end' statements in the parameter file <input string>.
Path before loading input:
subsection test
DEAL_II_NAMESPACE_OPEN
namespace deal_II_exceptions
{
- extern bool abort_on_exception;
extern bool show_stacktrace;
} // namespace deal_II_exceptions
DEAL_II_NAMESPACE_CLOSE
std::cerr << "Detailed description: " << comment << std::endl;
// Reenable abort and stacktraces:
- deal_II_exceptions::abort_on_exception = true;
- deal_II_exceptions::show_stacktrace = true;
+ deal_II_exceptions::allow_abort_on_exception = true;
+ deal_II_exceptions::show_stacktrace = true;
// And abort with a deal.II exception:
Assert(false, ExcMessage("TBB Exception, see above"));