xref: /petsc/include/petscerror.h (revision a58c3bc3391eee32bc3fd94ac7edeea38fe57aae)
1 /*
2     Contains all error handling interfaces for PETSc.
3 */
4 #if !defined(__PETSCERROR_H)
5 #define __PETSCERROR_H
6 #include "petsc.h"
7 PETSC_EXTERN_CXX_BEGIN
8 
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 */
17 #if !defined(__SDIR__)
18 #define __SDIR__ "unknowndirectory/"
19 #endif
20 
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 */
26 #if !defined(__FUNCT__)
27 #define __FUNCT__ "User provided function"
28 #endif
29 
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.
36 
37 */
38 #define PETSC_ERR_MIN_VALUE        54   /* should always be one less then the smallest value */
39 
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 
53 #define PETSC_ERR_ARG_SIZ          60   /* nonconforming object sizes used in operation */
54 #define PETSC_ERR_ARG_IDN          61   /* two arguments not allowed to be the same */
55 #define PETSC_ERR_ARG_WRONG        62   /* wrong argument (but object probably ok) */
56 #define PETSC_ERR_ARG_CORRUPT      64   /* null or corrupted PETSc object as argument */
57 #define PETSC_ERR_ARG_OUTOFRANGE   63   /* input argument, out of range */
58 #define PETSC_ERR_ARG_BADPTR       68   /* invalid pointer argument */
59 #define PETSC_ERR_ARG_NOTSAMETYPE  69   /* two args must be same object type */
60 #define PETSC_ERR_ARG_NOTSAMECOMM  80   /* two args must be same communicators */
61 #define PETSC_ERR_ARG_WRONGSTATE   73   /* object in argument is in wrong state, e.g. unassembled mat */
62 #define PETSC_ERR_ARG_INCOMP       75   /* two arguments are incompatible */
63 #define PETSC_ERR_ARG_NULL         85   /* argument is null that should not be */
64 #define PETSC_ERR_ARG_UNKNOWN_TYPE 86   /* type name doesn't match any registered type */
65 #define PETSC_ERR_ARG_DOMAIN       87   /* argument is not in domain of function */
66 
67 #define PETSC_ERR_FILE_OPEN        65   /* unable to open file */
68 #define PETSC_ERR_FILE_READ        66   /* unable to read from file */
69 #define PETSC_ERR_FILE_WRITE       67   /* unable to write to file */
70 #define PETSC_ERR_FILE_UNEXPECTED  79   /* unexpected data in file */
71 
72 #define PETSC_ERR_MAT_LU_ZRPVT     71   /* detected a zero pivot during LU factorization */
73 #define PETSC_ERR_MAT_CH_ZRPVT     81   /* detected a zero pivot during Cholesky factorization */
74 
75 #define PETSC_ERR_MAX_VALUE        88   /* this is always the one more than the largest error code */
76 
77 #if defined(PETSC_USE_ERRORCHECKING)
78 
79 /*MC
80    SETERRQ - Macro that is called when an error has been detected,
81 
82    Not Collective
83 
84    Synopsis:
85    void SETERRQ(PetscErrorCode errorcode,char *message)
86 
87 
88    Input Parameters:
89 +  errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
90 -  message - error message
91 
92   Level: beginner
93 
94    Notes:
95     Once the error handler is called the calling function is then returned from with the given error code.
96 
97     See SETERRQ1(), SETERRQ2(), SETERRQ3() for versions that take arguments
98 
99 
100    Experienced users can set the error handler with PetscPushErrorHandler().
101 
102    Concepts: error^setting condition
103 
104 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ3()
105 M*/
106 #define SETERRQ(n,s)              {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s);}
107 
108 /*MC
109    SETERRQ1 - Macro that is called when an error has been detected,
110 
111    Not Collective
112 
113    Synopsis:
114    void SETERRQ1(PetscErrorCode errorcode,char *formatmessage,arg)
115 
116 
117    Input Parameters:
118 +  errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
119 .  message - error message in the printf format
120 -  arg - argument (for example an integer, string or double)
121 
122   Level: beginner
123 
124    Notes:
125     Once the error handler is called the calling function is then returned from with the given error code.
126 
127    Experienced users can set the error handler with PetscPushErrorHandler().
128 
129    Concepts: error^setting condition
130 
131 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ, SETERRQ(), SETERRQ2(), SETERRQ3()
132 M*/
133 #define SETERRQ1(n,s,a1)          {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1);}
134 
135 /*MC
136    SETERRQ2 - Macro that is called when an error has been detected,
137 
138    Not Collective
139 
140    Synopsis:
141    void SETERRQ2(PetscErrorCode errorcode,char *formatmessage,arg1,arg2)
142 
143 
144    Input Parameters:
145 +  errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
146 .  message - error message in the printf format
147 .  arg1 - argument (for example an integer, string or double)
148 -  arg2 - argument (for example an integer, string or double)
149 
150   Level: beginner
151 
152    Notes:
153     Once the error handler is called the calling function is then returned from with the given error code.
154 
155    Experienced users can set the error handler with PetscPushErrorHandler().
156 
157    Concepts: error^setting condition
158 
159 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ3()
160 M*/
161 #define SETERRQ2(n,s,a1,a2)       {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2);}
162 
163 /*MC
164    SETERRQ3 - Macro that is called when an error has been detected,
165 
166    Not Collective
167 
168    Synopsis:
169    void SETERRQ3(PetscErrorCode errorcode,char *formatmessage,arg1,arg2,arg3)
170 
171 
172    Input Parameters:
173 +  errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
174 .  message - error message in the printf format
175 .  arg1 - argument (for example an integer, string or double)
176 .  arg2 - argument (for example an integer, string or double)
177 -  arg3 - argument (for example an integer, string or double)
178 
179   Level: beginner
180 
181    Notes:
182     Once the error handler is called the calling function is then returned from with the given error code.
183 
184     There are also versions for 4, 5, 6 and 7 arguments.
185 
186    Experienced users can set the error handler with PetscPushErrorHandler().
187 
188    Concepts: error^setting condition
189 
190 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2()
191 M*/
192 #define SETERRQ3(n,s,a1,a2,a3)    {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2,a3);}
193 
194 #define SETERRQ4(n,s,a1,a2,a3,a4) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2,a3,a4);}
195 #define SETERRQ5(n,s,a1,a2,a3,a4,a5)       {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2,a3,a4,a5);}
196 #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);}
197 #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);}
198 #define SETERRABORT(comm,n,s)     {PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s);MPI_Abort(comm,n);}
199 
200 /*MC
201    CHKERRQ - Checks error code, if non-zero it calls the error handler and then returns
202 
203    Not Collective
204 
205    Synopsis:
206    void CHKERRQ(PetscErrorCode errorcode)
207 
208 
209    Input Parameters:
210 .  errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
211 
212   Level: beginner
213 
214    Notes:
215     Once the error handler is called the calling function is then returned from with the given error code.
216 
217     Experienced users can set the error handler with PetscPushErrorHandler().
218 
219     CHKERRQ(n) is fundamentally a macro replacement for
220          if (n) return(PetscError(...,n,...));
221 
222     Although typical usage resembles "void CHKERRQ(PetscErrorCode)" as described above, for certain uses it is
223     highly inappropriate to use it in this manner as it invokes return(PetscErrorCode). In particular,
224     it cannot be used in functions which return(void) or any other datatype.  In these types of functions,
225     a more appropriate construct for using PETSc Error Handling would be
226          if (n) {PetscError(....); return(YourReturnType);}
227 
228    Concepts: error^setting condition
229 
230 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ2()
231 M*/
232 #define CHKERRQ(n)             if (n) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,0," ");}
233 
234 #define CHKERRV(n)             if (n) {n = PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,0," ");return;}
235 #define CHKERRABORT(comm,n)    if (n) {PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,0," ");MPI_Abort(comm,n);}
236 #define CHKERRCONTINUE(n)      if (n) {PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,0," ");}
237 
238 #define CHKFPQ(f) if (f != f) {SETERRQ(PETSC_ERR_FP, "Invalid value: NaN");}
239 
240 /*MC
241    CHKMEMQ - Checks the memory for corruption, calls error handler if any is detected
242 
243    Not Collective
244 
245    Synopsis:
246    CHKMEMQ;
247 
248   Level: beginner
249 
250    Notes:
251     Must run with the option -malloc_debug to enable this option
252 
253     Once the error handler is called the calling function is then returned from with the given error code.
254 
255     By defaults prints location where memory that is corrupted was allocated.
256 
257     Use CHKMEMA for functions that return void
258 
259    Concepts: memory corruption
260 
261 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ3(),
262           PetscMallocValidate()
263 M*/
264 #define CHKMEMQ {PetscErrorCode _7_ierr = PetscMallocValidate(__LINE__,__FUNCT__,__FILE__,__SDIR__);CHKERRQ(_7_ierr);}
265 
266 #define CHKMEMA {PetscMallocValidate(__LINE__,__FUNCT__,__FILE__,__SDIR__);}
267 
268 #if defined(PETSC_UNDERSCORE_CHKERR)
269 extern  PetscErrorCode __gierr;
270 #define _   __gierr =
271 #define ___  CHKERRQ(__gierr);
272 #endif
273 
274 #define               PETSC_EXCEPTIONS_MAX  256
275 extern PetscErrorCode PetscErrorUncatchable[PETSC_EXCEPTIONS_MAX];
276 extern PetscInt       PetscErrorUncatchableCount;
277 extern PetscErrorCode PetscExceptions[PETSC_EXCEPTIONS_MAX];
278 extern PetscInt       PetscExceptionsCount;
279 
280 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscExceptionPush(PetscErrorCode);
281 EXTERN void PETSC_DLLEXPORT PetscExceptionPop(PetscErrorCode);
282 
283 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscErrorSetCatchable(PetscErrorCode,PetscTruth);
284 EXTERN PetscTruth PETSC_DLLEXPORT PetscErrorIsCatchable(PetscErrorCode);
285 /*MC
286    PetscExceptionCaught - Indicates if a specific exception zierr was caught.
287 
288    Not Collective
289 
290    Synopsis:
291      PetscTruth PetscExceptionCaught(PetscErrorCode xierr,PetscErrorCode zierr);
292 
293   Input Parameters:
294   + xierr - error code returned from PetscExceptionTry1()
295   - zierr - error code you want it to be
296 
297   Level: advanced
298 
299    Notes:
300     PETSc must not be configured using the option --with-errorchecking=0 for this to work
301 
302     Use PetscExceptionValue() to see if the current error code is one that has been "tried"
303 
304   Concepts: exceptions, exception hanlding
305 
306 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ3(),
307           CHKERRQ(), PetscExceptionTry1(), PetscExceptionValue()
308 M*/
309 PETSC_STATIC_INLINE PetscTruth PetscExceptionCaught(PetscErrorCode xierr,PetscErrorCode zierr) {
310   PetscInt i;
311   if (xierr != zierr) return PETSC_FALSE;
312   for (i=0; i<PetscErrorUncatchableCount; i++) {
313     if (PetscErrorUncatchable[i] == zierr) {
314       return PETSC_FALSE;
315     }
316   }
317   return PETSC_TRUE;
318 }
319 
320 /*MC
321    PetscExceptionValue - Indicates if the error code is one that is currently being tried
322 
323    Not Collective
324 
325    Synopsis:
326      PetscTruth PetscExceptionValue(PetscErrorCode xierr);
327 
328   Input Parameters:
329   . xierr - error code
330 
331   Level: developer
332 
333    Notes:
334     PETSc must not be configured using the option --with-errorchecking=0 for this to work
335 
336     Use PetscExceptionCaught() to see if the current error code is EXACTLY the one you want
337 
338   Concepts: exceptions, exception hanlding
339 
340 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ3(),
341           CHKERRQ(), PetscExceptionTry1(), PetscExceptionCaught()
342 M*/
343 PETSC_STATIC_INLINE PetscTruth PetscExceptionValue(PetscErrorCode zierr) {
344   PetscInt i;
345   for (i=0; i<PetscExceptionsCount; i++) {
346     if (PetscExceptions[i] == zierr) {
347       return PETSC_TRUE;
348     }
349   }
350   return PETSC_FALSE;
351 }
352 
353 /*MC
354    PetscExceptionTry1 - Runs the routine, causing a particular error code to be treated as an exception,
355          rather than an error. That is if that error code is treated the program returns to this level,
356          but does not call the error handlers
357 
358    Not Collective
359 
360    Synopsis:
361      PetscExceptionTry1(PetscErrorCode routine(....),PetscErrorCode);
362 
363   Level: advanced
364 
365    Notes:
366     PETSc must not be configured using the option --with-errorchecking=0 for this to work
367 
368   Note: In general, the outer most try on an exception is the one that will be caught (that is trys down in
369         PETSc code will not usually handle an exception that was issued above). See SNESSolve() for an example
370         of how the local try is ignored if a higher (in the stack) one is also in effect.
371 
372   Concepts: exceptions, exception hanlding
373 
374 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ3(),
375           CHKERRQ(), PetscExceptionCaught(), PetscExceptionPush(), PetscExceptionPop()
376 M*/
377 extern PetscErrorCode PetscExceptionTmp;
378 #define PetscExceptionTry1(a,b) (PetscExceptionTmp = PetscExceptionPush(b)) ? PetscExceptionTmp : (PetscExceptionTmp = a , PetscExceptionPop(b),PetscExceptionTmp)
379 
380 #else
381 
382 /*
383     These are defined to be empty for when error checking is turned off, with config/configure.py --with-errorchecking=0
384 */
385 
386 #define SETERRQ(n,s) ;
387 #define SETERRQ1(n,s,a1) ;
388 #define SETERRQ2(n,s,a1,a2) ;
389 #define SETERRQ3(n,s,a1,a2,a3) ;
390 #define SETERRQ4(n,s,a1,a2,a3,a4) ;
391 #define SETERRQ5(n,s,a1,a2,a3,a4,a5) ;
392 #define SETERRQ6(n,s,a1,a2,a3,a4,a5,a6) ;
393 #define SETERRABORT(comm,n,s) ;
394 
395 #define CHKERRQ(n)     ;
396 #define CHKERRABORT(comm,n) ;
397 #define CHKERRCONTINUE(n) ;
398 
399 #define CHKMEMQ        ;
400 
401 #if !defined(PETSC_SKIP_UNDERSCORE_CHKERR)
402 #define _
403 #define ___
404 #endif
405 
406 #define PetscErrorSetCatchable(a,b) 0
407 #define PetscExceptionCaught(a,b)   PETSC_FALSE
408 #define PetscExceptionValue(a)      PETSC_FALSE
409 #define PetscExceptionTry1(a,b)     a
410 #endif
411 
412 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscErrorPrintfInitialize(void);
413 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscErrorMessage(int,const char*[],char **);
414 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscTraceBackErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
415 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscIgnoreErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
416 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscEmacsClientErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
417 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscMPIAbortErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
418 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscAbortErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
419 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscAttachDebuggerErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
420 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscReturnErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
421 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscError(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,...) PETSC_PRINTF_FORMAT_CHECK(7,8);
422 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscPushErrorHandler(PetscErrorCode (*handler)(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*),void*);
423 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscPopErrorHandler(void);
424 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscDefaultSignalHandler(int,void*);
425 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscPushSignalHandler(PetscErrorCode (*)(int,void *),void*);
426 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscPopSignalHandler(void);
427 
428 typedef enum {PETSC_FP_TRAP_OFF=0,PETSC_FP_TRAP_ON=1} PetscFPTrap;
429 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscSetFPTrap(PetscFPTrap);
430 
431 /*
432       Allows the code to build a stack frame as it runs
433 */
434 #if defined(PETSC_USE_DEBUG)
435 
436 #define PETSCSTACKSIZE 15
437 
438 typedef struct  {
439   const char *function[PETSCSTACKSIZE];
440   const char *file[PETSCSTACKSIZE];
441   const char *directory[PETSCSTACKSIZE];
442         int  line[PETSCSTACKSIZE];
443         int currentsize;
444 } PetscStack;
445 
446 extern PETSC_DLLEXPORT PetscStack *petscstack;
447 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscStackCopy(PetscStack*,PetscStack*);
448 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscStackPrint(PetscStack*,FILE* fp);
449 
450 #define PetscStackActive (petscstack != 0)
451 
452 
453 /*MC
454    PetscFunctionBegin - First executable line of each PETSc function
455         used for error handling.
456 
457    Synopsis:
458    void PetscFunctionBegin;
459 
460    Usage:
461 .vb
462      int something;
463 
464      PetscFunctionBegin;
465 .ve
466 
467    Notes:
468      Not available in Fortran
469 
470    Level: developer
471 
472 .seealso: PetscFunctionReturn()
473 
474 .keywords: traceback, error handling
475 M*/
476 #define PetscFunctionBegin \
477   {\
478    if (petscstack && (petscstack->currentsize < PETSCSTACKSIZE)) {    \
479     petscstack->function[petscstack->currentsize]  = __FUNCT__; \
480     petscstack->file[petscstack->currentsize]      = __FILE__; \
481     petscstack->directory[petscstack->currentsize] = __SDIR__; \
482     petscstack->line[petscstack->currentsize]      = __LINE__; \
483     petscstack->currentsize++; \
484   }}
485 
486 #define PetscStackPush(n) \
487   {if (petscstack && (petscstack->currentsize < PETSCSTACKSIZE)) {    \
488     petscstack->function[petscstack->currentsize]  = n; \
489     petscstack->file[petscstack->currentsize]      = "unknown"; \
490     petscstack->directory[petscstack->currentsize] = "unknown"; \
491     petscstack->line[petscstack->currentsize]      = 0; \
492     petscstack->currentsize++; \
493   }}
494 
495 #define PetscStackPop \
496   {if (petscstack && petscstack->currentsize > 0) {     \
497     petscstack->currentsize--; \
498     petscstack->function[petscstack->currentsize]  = 0; \
499     petscstack->file[petscstack->currentsize]      = 0; \
500     petscstack->directory[petscstack->currentsize] = 0; \
501     petscstack->line[petscstack->currentsize]      = 0; \
502   }};
503 
504 /*MC
505    PetscFunctionReturn - Last executable line of each PETSc function
506         used for error handling. Replaces return()
507 
508    Synopsis:
509    void PetscFunctionReturn(0);
510 
511    Usage:
512 .vb
513     ....
514      PetscFunctionReturn(0);
515    }
516 .ve
517 
518    Notes:
519      Not available in Fortran
520 
521    Level: developer
522 
523 .seealso: PetscFunctionBegin()
524 
525 .keywords: traceback, error handling
526 M*/
527 #define PetscFunctionReturn(a) \
528   {\
529   PetscStackPop; \
530   return(a);}
531 
532 #define PetscFunctionReturnVoid() \
533   {\
534   PetscStackPop; \
535   return;}
536 
537 
538 #else
539 
540 #define PetscFunctionBegin
541 #define PetscFunctionReturn(a)  return(a)
542 #define PetscFunctionReturnVoid() return
543 #define PetscStackPop
544 #define PetscStackPush(f)
545 #define PetscStackActive        0
546 
547 #endif
548 
549 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscStackCreate(void);
550 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscStackView(PetscViewer);
551 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscStackDestroy(void);
552 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscStackPublish(void);
553 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscStackDepublish(void);
554 
555 
556 PETSC_EXTERN_CXX_END
557 #endif
558