Errors are handled through the routine PetscError().
This routine
checks a stack of error handlers and calls the one on the top.
If the stack is empty, it selects PetscTraceBackErrorHandler(),
which tries to print a traceback.
A new error handler can be put on the stack with
ierr = PetscPushErrorHandler(int (*HandlerFunction)(int line,char *dir,char *file, char *message,int number,void*),void *HandlerContext)The arguments to HandlerFunction() are the line number where the error occurred, the file in which the error was detected, the corresponding directory, the error message, the error integer, and the HandlerContext. The routine
ierr = PetscPopErrorHandler()removes the last error handler and discards it.
PETSc provides two additional error handlers besides
PetscTraceBackErrorHandler():
PetscAbortErrorHandler() PetscAttachErrorHandler()PetscAbortErrorHandler() calls abort on encountering an error, while PetscAttachErrorHandler() attaches a debugger to the running process if an error is detected. At runtime, these error handlers can be set with the options -on_error_abort or -on_error_attach_debugger [noxterm, dbx, xxgdb, xldb] [-display DISPLAY].
All PETSc calls can be traced (useful for determining where a program is
hanging without running in the debugger) with the option
-log_trace [filename]where filename is optional. By default the traces are printed to the screen. This can also be set with the command PLogTraceBegin(FILE*).
It is also possible to trap signals by using the
command
ierr = PetscPushSignalHandler( int (*Handler)(int,void *),void *ctx);The default handler PetscDefaultSignalHandler() calls PetscError() and then terminates. In general, a signal in PETSc indicates a catastrophic failure. Any error hander that the user provides should try to clean up only before exiting. By default all PETSc programs use the default signal handler, although the user can turn this off at runtime with the option -no_signal_handler .
There is a separate signal handler for floating-point exceptions.
The option -fp_trap turns on the floating-point trap at runtime,
and the routine
ierr = PetscSetFPTrap(int flag);can be used in-line. A flag of PETSC_FP_TRAP_ON indicates that floating-point exceptions should be trapped, while a value of PETSC_FP_TRAP_OFF (the default) indicates that they should be ignored. Note that on certain machines, in particular the IBM RS/6000, trapping is very expensive.
A small set of macros is used to make the error handling lightweight.
These macros are used throughout the PETSc libraries and can be employed
by the application
programmer as well. When an error is first detected,
one should set it by calling
SETERRQ(int flag,int pflag,char *message);The user should check the return codes for all PETSc routines (and possibly user-defined routines as well) with
ierr = PetscRoutine(...); CHKERRQ(int ierr);Likewise, all memory allocations should be checked with
ptr = (double *) PetscMalloc(n*sizeof(double)); CHKPTRQ(void *ptr);If this procedure is followed throughout all of the user's libraries and codes, any error will by default generate a clean traceback of the location of the error. In any main programs, however, the variants SETERRA(), CHKERRA(), and CHKPTRA() should be used instead to cause all processes of program to abort when an error has been detected. Use of the abort variant of the error checking commands is critical in the main program, since they ensure that MPI_Abort() is called before the process ends; otherwise, other MPI processes that did not generate errors may remain unterminated.
Note that the macro __FUNC__ is used to keep track of
routine names during error tracebacks. Users need not worry about this
macro in their application codes; however, users can take advantage of this feature
if desired by setting this macro before each user-defined routine
that may call SETERRQ(), SETERRA(), CHKERRQ(),
or CHKERRA(). A simple example of usage is given below.
#undef __FUNC__ #define __FUNC__ "MyRoutine1" int MyRoutine1() { /* code here */ return 0; }