Actual source code: petscerror.h
1: /*
2: Contains all error handling interfaces for PETSc.
3: */
9: /*
10: Defines the directory where the compiled source is located; used
11: in printing error messages. Each makefile has an entry
12: LOCDIR = thedirectory
13: and bmake/common_variables includes in CCPPFLAGS -D__SDIR__=${LOCDIR}
14: which is a flag passed to the C/C++ compilers. This declaration below
15: is only needed if some code is compiled without the -D__SDIR__
16: */
19: #endif
21: /*
22: Defines the function where the compiled source is located; used
23: in printing error messages. This is defined here in case the user
24: does not declare it.
25: */
28: #endif
30: /*
31: These are the generic error codes. These error codes are used
32: many different places in the PETSc source code. The string versions are
33: at src/sys/error/err.c any changes here must also be made there
34: These are also define in include/finclude/petscerror.h any CHANGES here
35: must be also made there.
37: */
38: #define PETSC_ERR_MIN_VALUE 54 /* should always be one less then the smallest value */
40: #define PETSC_ERR_MEM 55 /* unable to allocate requested memory */
41: #define PETSC_ERR_SUP 56 /* no support for requested operation */
42: #define PETSC_ERR_SUP_SYS 57 /* no support for requested operation on this computer system */
43: #define PETSC_ERR_ORDER 58 /* operation done in wrong order */
44: #define PETSC_ERR_SIG 59 /* signal received */
45: #define PETSC_ERR_FP 72 /* floating point exception */
46: #define PETSC_ERR_COR 74 /* corrupted PETSc object */
47: #define PETSC_ERR_LIB 76 /* error in library called by PETSc */
48: #define PETSC_ERR_PLIB 77 /* PETSc library generated inconsistent data */
49: #define PETSC_ERR_MEMC 78 /* memory corruption */
50: #define PETSC_ERR_CONV_FAILED 82 /* iterative method (KSP or SNES) failed */
51: #define PETSC_ERR_USER 83 /* user has not provided needed function */
52: #define PETSC_ERR_SYS 88 /* error in system call */
54: #define PETSC_ERR_ARG_SIZ 60 /* nonconforming object sizes used in operation */
55: #define PETSC_ERR_ARG_IDN 61 /* two arguments not allowed to be the same */
56: #define PETSC_ERR_ARG_WRONG 62 /* wrong argument (but object probably ok) */
57: #define PETSC_ERR_ARG_CORRUPT 64 /* null or corrupted PETSc object as argument */
58: #define PETSC_ERR_ARG_OUTOFRANGE 63 /* input argument, out of range */
59: #define PETSC_ERR_ARG_BADPTR 68 /* invalid pointer argument */
60: #define PETSC_ERR_ARG_NOTSAMETYPE 69 /* two args must be same object type */
61: #define PETSC_ERR_ARG_NOTSAMECOMM 80 /* two args must be same communicators */
62: #define PETSC_ERR_ARG_WRONGSTATE 73 /* object in argument is in wrong state, e.g. unassembled mat */
63: #define PETSC_ERR_ARG_TYPENOTSET 89 /* the type of the object has not yet been set */
64: #define PETSC_ERR_ARG_INCOMP 75 /* two arguments are incompatible */
65: #define PETSC_ERR_ARG_NULL 85 /* argument is null that should not be */
66: #define PETSC_ERR_ARG_UNKNOWN_TYPE 86 /* type name doesn't match any registered type */
68: #define PETSC_ERR_FILE_OPEN 65 /* unable to open file */
69: #define PETSC_ERR_FILE_READ 66 /* unable to read from file */
70: #define PETSC_ERR_FILE_WRITE 67 /* unable to write to file */
71: #define PETSC_ERR_FILE_UNEXPECTED 79 /* unexpected data in file */
73: #define PETSC_ERR_MAT_LU_ZRPVT 71 /* detected a zero pivot during LU factorization */
74: #define PETSC_ERR_MAT_CH_ZRPVT 81 /* detected a zero pivot during Cholesky factorization */
76: #define PETSC_ERR_FLOP_COUNT 90
77: #define PETSC_ERR_MAX_VALUE 91 /* this is always the one more than the largest error code */
79: #if defined(PETSC_USE_ERRORCHECKING)
81: #define PetscStringizeArg(a) #a
82: #define PetscStringize(a) PetscStringizeArg(a)
85: /*MC
86: SETERRQ - Macro that is called when an error has been detected,
88: Not Collective
90: Synopsis:
91: PetscErrorCode SETERRQ(PetscErrorCode errorcode,char *message)
94: Input Parameters:
95: + errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
96: - message - error message
98: Level: beginner
100: Notes:
101: Once the error handler is called the calling function is then returned from with the given error code.
103: See SETERRQ1(), SETERRQ2(), SETERRQ3() for versions that take arguments
105: In Fortran MPI_Abort() is always called
107: Experienced users can set the error handler with PetscPushErrorHandler().
109: Concepts: error^setting condition
111: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ3()
112: M*/
113: #define SETERRQ(n,s) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s);}
115: /*MC
116: SETERRQ1 - Macro that is called when an error has been detected,
118: Not Collective
120: Synopsis:
121: PetscErrorCode SETERRQ1(PetscErrorCode errorcode,char *formatmessage,arg)
124: Input Parameters:
125: + errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
126: . message - error message in the printf format
127: - arg - argument (for example an integer, string or double)
129: Level: beginner
131: Notes:
132: Once the error handler is called the calling function is then returned from with the given error code.
134: Experienced users can set the error handler with PetscPushErrorHandler().
136: Concepts: error^setting condition
138: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ, SETERRQ(), SETERRQ2(), SETERRQ3()
139: M*/
140: #define SETERRQ1(n,s,a1) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1);}
142: /*MC
143: SETERRQ2 - Macro that is called when an error has been detected,
145: Not Collective
147: Synopsis:
148: PetscErrorCode SETERRQ2(PetscErrorCode errorcode,char *formatmessage,arg1,arg2)
151: Input Parameters:
152: + errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
153: . message - error message in the printf format
154: . arg1 - argument (for example an integer, string or double)
155: - arg2 - argument (for example an integer, string or double)
157: Level: beginner
159: Notes:
160: Once the error handler is called the calling function is then returned from with the given error code.
162: Experienced users can set the error handler with PetscPushErrorHandler().
164: Concepts: error^setting condition
166: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ3()
167: M*/
168: #define SETERRQ2(n,s,a1,a2) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2);}
170: /*MC
171: SETERRQ3 - Macro that is called when an error has been detected,
173: Not Collective
175: Synopsis:
176: PetscErrorCode SETERRQ3(PetscErrorCode errorcode,char *formatmessage,arg1,arg2,arg3)
179: Input Parameters:
180: + errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
181: . message - error message in the printf format
182: . arg1 - argument (for example an integer, string or double)
183: . arg2 - argument (for example an integer, string or double)
184: - arg3 - argument (for example an integer, string or double)
186: Level: beginner
188: Notes:
189: Once the error handler is called the calling function is then returned from with the given error code.
191: There are also versions for 4, 5, 6 and 7 arguments.
193: Experienced users can set the error handler with PetscPushErrorHandler().
195: Concepts: error^setting condition
197: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2()
198: M*/
199: #define SETERRQ3(n,s,a1,a2,a3) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2,a3);}
201: #define SETERRQ4(n,s,a1,a2,a3,a4) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2,a3,a4);}
202: #define SETERRQ5(n,s,a1,a2,a3,a4,a5) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2,a3,a4,a5);}
203: #define SETERRQ6(n,s,a1,a2,a3,a4,a5,a6) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2,a3,a4,a5,a6);}
204: #define SETERRQ7(n,s,a1,a2,a3,a4,a5,a6,a7) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2,a3,a4,a5,a6,a7);}
205: #define SETERRABORT(comm,n,s) {PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s);MPI_Abort(comm,n);}
207: /*MC
208: CHKERRQ - Checks error code, if non-zero it calls the error handler and then returns
210: Not Collective
212: Synopsis:
213: PetscErrorCode CHKERRQ(PetscErrorCode errorcode)
216: Input Parameters:
217: . errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
219: Level: beginner
221: Notes:
222: Once the error handler is called the calling function is then returned from with the given error code.
224: Experienced users can set the error handler with PetscPushErrorHandler().
226: CHKERRQ(n) is fundamentally a macro replacement for
227: if (n) return(PetscError(...,n,...));
229: Although typical usage resembles "void CHKERRQ(PetscErrorCode)" as described above, for certain uses it is
230: highly inappropriate to use it in this manner as it invokes return(PetscErrorCode). In particular,
231: it cannot be used in functions which return(void) or any other datatype. In these types of functions,
232: you can use CHKERRV() which returns without an error code (bad idea since the error is ignored or
233: if (n) {PetscError(....); return(YourReturnType);}
234: where you may pass back a PETSC_NULL to indicate an error. You can also call CHKERRABORT(comm,n) to have
235: MPI_Abort() returned immediately.
237: In Fortran MPI_Abort() is always called
239: Concepts: error^setting condition
241: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ2()
242: M*/
243: #define CHKERRQ(n) if (PetscUnlikely(n)) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,0," ");}
245: #define CHKERRV(n) if (PetscUnlikely(n)) {n = PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,0," ");return;}
246: #define CHKERRABORT(comm,n) if (PetscUnlikely(n)) {PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,0," ");MPI_Abort(comm,n);}
247: #define CHKERRCONTINUE(n) if (PetscUnlikely(n)) {PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,0," ");}
249: #ifdef PETSC_CLANGUAGE_CXX
251: /*MC
252: CHKERRXX - Checks error code, if non-zero it calls the C++ error handler which throws an exception
254: Not Collective
256: Synopsis:
257: void CHKERRXX(PetscErrorCode errorcode)
260: Input Parameters:
261: . errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
263: Level: beginner
265: Notes:
266: Once the error handler throws a ??? exception.
268: You can use CHKERRV() which returns without an error code (bad idea since the error is ignored)
269: or CHKERRABORT(comm,n) to have MPI_Abort() returned immediately.
271: Concepts: error^setting condition
273: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKERRQ(), CHKMEMQ
274: M*/
275: #define CHKERRXX(n) if (PetscUnlikely(n)) {PetscErrorCxx(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,0);}
277: #endif
279: /*MC
280: CHKMEMQ - Checks the memory for corruption, calls error handler if any is detected
282: Not Collective
284: Synopsis:
285: CHKMEMQ;
287: Level: beginner
289: Notes:
290: Must run with the option -malloc_debug to enable this option
292: Once the error handler is called the calling function is then returned from with the given error code.
294: By defaults prints location where memory that is corrupted was allocated.
296: Use CHKMEMA for functions that return void
298: Concepts: memory corruption
300: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ3(),
301: PetscMallocValidate()
302: M*/
303: #define CHKMEMQ {PetscErrorCode _7_PetscMallocValidate(__LINE__,__FUNCT__,__FILE__,__SDIR__);CHKERRQ(_7_ierr);}
305: #define CHKMEMA {PetscMallocValidate(__LINE__,__FUNCT__,__FILE__,__SDIR__);}
307: #if defined(PETSC_UNDERSCORE_CHKERR)
309: #define _ __g
311: #endif
313: #define PETSC_EXCEPTIONS_MAX 256
319: EXTERN PetscErrorCode PetscExceptionPush(PetscErrorCode);
320: EXTERN PetscErrorCode PetscExceptionPop(PetscErrorCode);
322: EXTERN PetscErrorCode PetscErrorSetCatchable(PetscErrorCode,PetscTruth);
323: EXTERN PetscTruth PetscErrorIsCatchable(PetscErrorCode);
324: /*MC
325: PetscExceptionCaught - Indicates if a specific exception zierr was caught.
327: Not Collective
329: Synopsis:
330: PetscTruth PetscExceptionCaught(PetscErrorCode xierr,PetscErrorCode zierr);
332: Input Parameters:
333: + xierr - error code returned from PetscExceptionTry1() or other PETSc routine
334: - zierr - error code you want it to be
336: Level: advanced
338: Notes:
339: PETSc must not be configured using the option --with-errorchecking=0 for this to work
341: Use PetscExceptionValue() to see if an error code is being "tried"
343: Concepts: exceptions, exception handling
345: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ3(),
346: CHKERRQ(), PetscExceptionTry1(), PetscExceptionValue()
347: M*/
348: PETSC_STATIC_INLINE PetscTruth PetscExceptionCaught(PetscErrorCode xierr,PetscErrorCode zierr)
349: {
350: PetscInt i;
351: if (xierr != zierr) return PETSC_FALSE;
352: for (i=0; i<PetscErrorUncatchableCount; i++) {
353: if (PetscErrorUncatchable[i] == zierr) {
354: return PETSC_FALSE;
355: }
356: }
357: return PETSC_TRUE;
358: }
360: /*MC
361: PetscExceptionValue - Indicates if the error code is one that is currently being tried
363: Not Collective
365: Synopsis:
366: PetscTruth PetscExceptionValue(PetscErrorCode xierr);
368: Input Parameters:
369: . xierr - error code
371: Level: developer
373: Notes:
374: PETSc must not be configured using the option --with-errorchecking=0 for this to work
376: Use PetscExceptionCaught() to see if the current error code is EXACTLY the one you want
378: Concepts: exceptions, exception hanlding
380: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ3(),
381: CHKERRQ(), PetscExceptionTry1(), PetscExceptionCaught()
382: M*/
383: PETSC_STATIC_INLINE PetscTruth PetscExceptionValue(PetscErrorCode zierr)
384: {
385: PetscInt i;
386: for (i=0; i<PetscExceptionsCount; i++) {
387: if (PetscExceptions[i] == zierr) {
388: return PETSC_TRUE;
389: }
390: }
391: return PETSC_FALSE;
392: }
394: /*MC
395: PetscExceptionTry1 - Runs the routine, causing a particular error code to be treated as an exception,
396: rather than an error. That is if that error code is treated the program returns to this level,
397: but does not call the error handlers
399: Not Collective
401: Synopsis:
402: PetscErrorCode PetscExceptionTry1(PetscErrorCode routine(....),PetscErrorCode);
404: Level: advanced
406: No Fortran Equivalent (see PetscExceptionPush() for Fortran)
408: Notes:
409: PETSc must not be configured using the option --with-errorchecking=0 for this to work
411: Note: In general, the outer most try on an exception is the one that will be caught (that is trys down in
412: PETSc code will not usually handle an exception that was issued above). See SNESSolve() for an example
413: of how the local try is ignored if a higher (in the stack) one is also in effect.
415: Concepts: exceptions, exception hanlding
417: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ3(),
418: CHKERRQ(), PetscExceptionCaught(), PetscExceptionPush(), PetscExceptionPop()
419: M*/
421: #define PetscExceptionTry1(a,b) (PetscExceptionTmp1 = PetscExceptionPush(b)) ? PetscExceptionTmp1 : (PetscExceptionTmp1 = a, (PetscExceptionTmp = PetscExceptionPop(b)) ? PetscExceptionTmp : PetscExceptionTmp1)
423: /*
424: Used by PetscExceptionTrySync(). Returns zierr on ALL processes in comm iff xierr is zierr on at least one process and zero on all others.
425: */
426: PETSC_STATIC_INLINE PetscErrorCode PetscExceptionTrySync_Private(MPI_Comm comm,PetscErrorCode xierr,PetscErrorCode zierr)
427: {
428: PetscReal in[2],out[2];
431: if (xierr != zierr) return xierr;
433: in[0] = xierr;
434: in[1] = 0.0; /* dummy value */
436: MPI_Allreduce(in,out,2,MPIU_REAL,0,comm); if (ierr) {;}
437: return xierr;
438: }
440: /*MC
441: PetscExceptionTrySyncNorm - Runs the routine, causing a particular error code to be treated as an exception,
442: rather than an error. That is if that error code is treated the program returns to this level,
443: but does not call the error handlers
445: Collective on Comm
447: Synopsis:
448: PetscExceptionTrySyncNorm(MPI_Comm comm,PetscErrorCode routine(....),PetscErrorCode);
450: Level: advanced
452: Notes: This synchronizes the error code across all processes in the communicator IF the code matches PetscErrorCode. The next
453: call with an MPI_Reduce()/MPI_Allreduce() MUST be VecNorm() [We can added VecDot() and maybe others as needed].
455: PETSc must not be configured using the option --with-errorchecking=0 for this to work
457: Note: In general, the outer most try on an exception is the one that will be caught (that is trys down in
458: PETSc code will not usually handle an exception that was issued above). See SNESSolve() for an example
459: of how the local try is ignored if a higher (in the stack) one is also in effect.
461: Concepts: exceptions, exception hanlding
463: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ3(),
464: CHKERRQ(), PetscExceptionCaught(), PetscExceptionPush(), PetscExceptionPop(), PetscExceptionTry1()
465: M*/
466: #define PetscExceptionTrySyncNorm(comm,a,b) (PetscExceptionTmp = PetscExceptionPush(b)) ? PetscExceptionTmp : \
467: (PetscExceptionTmp = a , PetscExceptionPop(b),PetscExceptionTrySyncNorm_Private(comm,PetscExceptionTmp,b))
469: #else
471: /*
472: These are defined to be empty for when error checking is turned off, with config/configure.py --with-errorchecking=0
473: */
475: #define SETERRQ(n,s) ;
476: #define SETERRQ1(n,s,a1) ;
477: #define SETERRQ2(n,s,a1,a2) ;
478: #define SETERRQ3(n,s,a1,a2,a3) ;
479: #define SETERRQ4(n,s,a1,a2,a3,a4) ;
480: #define SETERRQ5(n,s,a1,a2,a3,a4,a5) ;
481: #define SETERRQ6(n,s,a1,a2,a3,a4,a5,a6) ;
482: #define SETERRABORT(comm,n,s) ;
484: #define CHKERRQ(n) ;
485: #define CHKERRABORT(comm,n) ;
486: #define CHKERRCONTINUE(n) ;
487: #define CHKMEMQ ;
489: #if !defined(PETSC_SKIP_UNDERSCORE_CHKERR)
490: #define _
492: #endif
494: #define PetscExceptionPush(a) 0
495: #define PetscExceptionPop(a) 0
496: #define PetscErrorSetCatchable(a,b) 0
497: #define PetscErrorIsCatchable(a) PETSC_FALSE
499: #define PetscExceptionCaught(a,b) PETSC_FALSE
500: #define PetscExceptionValue(a) PETSC_FALSE
501: #define PetscExceptionTry1(a,b) a
502: #define PetscExceptionTrySyncNorm(comm,a,b) a
504: #endif
506: EXTERN PetscErrorCode PetscErrorPrintfInitialize(void);
507: EXTERN PetscErrorCode PetscErrorMessage(int,const char*[],char **);
508: EXTERN PetscErrorCode PetscTraceBackErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
510: #include <sstream>
511: EXTERN void PetscTraceBackErrorHandlerCxx(int,const char *,const char *,const char *,PetscErrorCode,int, std::ostringstream&);
512: #endif
513: EXTERN PetscErrorCode PetscIgnoreErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
514: EXTERN PetscErrorCode PetscEmacsClientErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
515: EXTERN PetscErrorCode PetscMPIAbortErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
516: EXTERN PetscErrorCode PetscAbortErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
517: EXTERN PetscErrorCode PetscAttachDebuggerErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
518: EXTERN PetscErrorCode PetscReturnErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
519: EXTERN PetscErrorCode PetscError(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,...) PETSC_PRINTF_FORMAT_CHECK(7,8);
520: EXTERN void PetscErrorCxx(int,const char*,const char*,const char*,PetscErrorCode,int);
521: EXTERN PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*),void*);
522: EXTERN PetscErrorCode PetscPopErrorHandler(void);
523: EXTERN PetscErrorCode PetscDefaultSignalHandler(int,void*);
524: EXTERN PetscErrorCode PetscPushSignalHandler(PetscErrorCode (*)(int,void *),void*);
525: EXTERN PetscErrorCode PetscPopSignalHandler(void);
527: typedef enum {PETSC_FP_TRAP_OFF=0,PETSC_FP_TRAP_ON=1} PetscFPTrap;
528: EXTERN PetscErrorCode PetscSetFPTrap(PetscFPTrap);
530: /*
531: Allows the code to build a stack frame as it runs
532: */
533: #if defined(PETSC_USE_DEBUG)
535: #define PETSCSTACKSIZE 15
537: typedef struct {
538: const char *function[PETSCSTACKSIZE];
539: const char *file[PETSCSTACKSIZE];
540: const char *directory[PETSCSTACKSIZE];
541: int line[PETSCSTACKSIZE];
542: int currentsize;
543: } PetscStack;
546: EXTERN PetscErrorCode PetscStackCopy(PetscStack*,PetscStack*);
547: EXTERN PetscErrorCode PetscStackPrint(PetscStack*,FILE* fp);
549: #define PetscStackActive (petscstack != 0)
552: /*MC
554: used for error handling.
556: Synopsis:
559: Usage:
560: .vb
561: int something;
564: .ve
566: Notes:
567: Not available in Fortran
569: Level: developer
571: .seealso: PetscFunctionReturn()
573: .keywords: traceback, error handling
574: M*/
576: {\
577: if (petscstack && (petscstack->currentsize < PETSCSTACKSIZE)) { \
578: petscstack->function[petscstack->currentsize] = __FUNCT__; \
579: petscstack->file[petscstack->currentsize] = __FILE__; \
580: petscstack->directory[petscstack->currentsize] = __SDIR__; \
581: petscstack->line[petscstack->currentsize] = __LINE__; \
582: petscstack->currentsize++; \
583: }}
585: #define PetscStackPush(n) \
586: {if (petscstack && (petscstack->currentsize < PETSCSTACKSIZE)) { \
587: petscstack->function[petscstack->currentsize] = n; \
588: petscstack->file[petscstack->currentsize] = "unknown"; \
589: petscstack->directory[petscstack->currentsize] = "unknown"; \
590: petscstack->line[petscstack->currentsize] = 0; \
591: petscstack->currentsize++; \
592: }}
594: #define PetscStackPop \
595: {if (petscstack && petscstack->currentsize > 0) { \
596: petscstack->currentsize--; \
597: petscstack->function[petscstack->currentsize] = 0; \
598: petscstack->file[petscstack->currentsize] = 0; \
599: petscstack->directory[petscstack->currentsize] = 0; \
600: petscstack->line[petscstack->currentsize] = 0; \
601: }};
603: /*MC
604: PetscFunctionReturn - Last executable line of each PETSc function
605: used for error handling. Replaces return()
607: Synopsis:
608: void return(0);
610: Usage:
611: .vb
612: ....
613: return(0);
614: }
615: .ve
617: Notes:
618: Not available in Fortran
620: Level: developer
624: .keywords: traceback, error handling
625: M*/
626: #define PetscFunctionReturn(a) \
627: {\
628: PetscStackPop; \
629: return(a);}
631: #define PetscFunctionReturnVoid() \
632: {\
633: PetscStackPop; \
634: return;}
637: #else
640: #define PetscFunctionReturn(a) return(a)
641: #define PetscFunctionReturnVoid() return
642: #define PetscStackPop
643: #define PetscStackPush(f)
644: #define PetscStackActive 0
646: #endif
648: EXTERN PetscErrorCode PetscStackCreate(void);
649: EXTERN PetscErrorCode PetscStackView(PetscViewer);
650: EXTERN PetscErrorCode PetscStackDestroy(void);
651: EXTERN PetscErrorCode PetscStackPublish(void);
652: EXTERN PetscErrorCode PetscStackDepublish(void);
656: #endif