Actual source code: err.c
1: /*$Id: err.c,v 1.130 2001/09/07 15:24:29 bsmith Exp $*/
2: /*
3: Code that allows one to set the error handlers
4: */
5: #include petsc.h
6: #include petscsys.h
7: #include <stdarg.h>
8: #if defined(PETSC_HAVE_STDLIB_H)
9: #include <stdlib.h>
10: #endif
12: typedef struct _EH *EH;
13: struct _EH {
14: int cookie;
15: int (*handler)(int,char*,char*,char *,int,int,char*,void *);
16: void *ctx;
17: EH previous;
18: };
20: static EH eh = 0;
22: #undef __FUNCT__
24: /*@C
25: PetscEmacsClientErrorHandler - Error handler that uses the emacsclient program to
26: load the file where the error occured. Then calls the "previous" error handler.
28: Not Collective
30: Input Parameters:
31: + line - the line number of the error (indicated by __LINE__)
32: . func - the function where error is detected (indicated by __FUNCT__)
33: . file - the file in which the error was detected (indicated by __FILE__)
34: . dir - the directory of the file (indicated by __SDIR__)
35: . mess - an error text string, usually just printed to the screen
36: . n - the generic error number
37: . p - specific error number
38: - ctx - error handler context
40: Options Database Key:
41: . -on_error_emacs <machinename>
43: Level: developer
45: Notes:
46: You must put (server-start) in your .emacs file for the emacsclient software to work
48: Most users need not directly employ this routine and the other error
49: handlers, but can instead use the simplified interface SETERRQ, which has
50: the calling sequence
51: $ SETERRQ(number,p,mess)
53: Notes for experienced users:
54: Use PetscPushErrorHandler() to set the desired error handler. The
55: currently available PETSc error handlers include PetscTraceBackErrorHandler(),
56: PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscStopErrorHandler()
58: Concepts: emacs^going to on error
59: Concepts: error handler^going to line in emacs
61: .seealso: PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(),
62: PetscAbortErrorHandler()
63: @*/
64: int PetscEmacsClientErrorHandler(int line,char *fun,char* file,char *dir,int n,int p,char *mess,void *ctx)
65: {
66: int ierr;
67: char command[PETSC_MAX_PATH_LEN],*pdir;
68: FILE *fp;
71: /* Note: don't check error codes since this an error handler :-) */
72: PetscGetPetscDir(&pdir);
73: sprintf(command,"emacsclient +%d %s/%s%sn",line,pdir,dir,file);
74: PetscPOpen(MPI_COMM_WORLD,(char*)ctx,command,"r",&fp);
75: PetscFClose(MPI_COMM_WORLD,fp);
76: PetscPopErrorHandler(); /* remove this handler from the stack of handlers */
77: if (!eh) PetscTraceBackErrorHandler(line,fun,file,dir,n,p,mess,0);
78: else (*eh->handler)(line,fun,file,dir,n,p,mess,eh->ctx);
79: PetscFunctionReturn(ierr);
80: }
82: #undef __FUNCT__
84: /*@C
85: PetscPushErrorHandler - Sets a routine to be called on detection of errors.
87: Not Collective
89: Input Parameters:
90: + handler - error handler routine
91: - ctx - optional handler context that contains information needed by the handler (for
92: example file pointers for error messages etc.)
94: Calling sequence of handler:
95: $ int handler(int line,char *func,char *file,char *dir,int n,int p,char *mess,void *ctx);
97: + func - the function where the error occured (indicated by __FUNCT__)
98: . line - the line number of the error (indicated by __LINE__)
99: . file - the file in which the error was detected (indicated by __FILE__)
100: . dir - the directory of the file (indicated by __SDIR__)
101: . n - the generic error number (see list defined in include/petscerror.h)
102: . p - the specific error number
103: . mess - an error text string, usually just printed to the screen
104: - ctx - the error handler context
106: Options Database Keys:
107: + -on_error_attach_debugger <noxterm,gdb or dbx>
108: - -on_error_abort
110: Level: intermediate
112: Fortran Note:
113: This routine is not supported in Fortran.
115: .seealso: PetscPopErrorHandler(), PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), PetscTraceBackErrorHandler()
117: @*/
118: int PetscPushErrorHandler(int (*handler)(int,char *,char*,char*,int,int,char*,void*),void *ctx)
119: {
120: EH neweh;
124: PetscNew(struct _EH,&neweh);
125: if (eh) {neweh->previous = eh;}
126: else {neweh->previous = 0;}
127: neweh->handler = handler;
128: neweh->ctx = ctx;
129: eh = neweh;
130: return(0);
131: }
133: #undef __FUNCT__
135: /*@C
136: PetscPopErrorHandler - Removes the latest error handler that was
137: pushed with PetscPushErrorHandler().
139: Not Collective
141: Level: intermediate
143: Fortran Note:
144: This routine is not supported in Fortran.
146: Concepts: error handler^setting
148: .seealso: PetscPushErrorHandler()
149: @*/
150: int PetscPopErrorHandler(void)
151: {
152: EH tmp;
156: if (!eh) return(0);
157: tmp = eh;
158: eh = eh->previous;
159: PetscFree(tmp);
161: return(0);
162: }
163:
164: char PetscErrorBaseMessage[1024];
166: #undef __FUNCT__
168: /*@C
169: PetscError - Routine that is called when an error has been detected,
170: usually called through the macro SETERRQ().
172: Not Collective
174: Input Parameters:
175: + line - the line number of the error (indicated by __LINE__)
176: . func - the function where the error occured (indicated by __FUNCT__)
177: . dir - the directory of file (indicated by __SDIR__)
178: . file - the file in which the error was detected (indicated by __FILE__)
179: . mess - an error text string, usually just printed to the screen
180: . n - the generic error number
181: . p - 1 indicates the error was initially detected, 0 indicates this is a traceback from a
182: previously detected error
183: - mess - formatted message string - aka printf
185: Level: intermediate
187: Notes:
188: Most users need not directly use this routine and the error handlers, but
189: can instead use the simplified interface SETERRQ, which has the calling
190: sequence
191: $ SETERRQ(n,mess)
193: Experienced users can set the error handler with PetscPushErrorHandler().
195: Concepts: error^setting condition
197: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), SETERRQ(), CHKERRQ(), CHKMEMQ(), SETERRQ1(), SETERRQ2()
198: @*/
199: int PetscError(int line,char *func,char* file,char *dir,int n,int p,char *mess,...)
200: {
201: va_list Argp;
202: int ierr;
203: char buf[2048],*lbuf = 0;
204: PetscTruth ismain,isunknown;
207: /* Compose the message evaluating the print format */
208: if (mess) {
209: va_start(Argp,mess);
210: #if defined(PETSC_HAVE_VPRINTF_CHAR)
211: vsprintf(buf,mess,(char *)Argp);
212: #else
213: vsprintf(buf,mess,Argp);
214: #endif
215: va_end(Argp);
216: lbuf = buf;
217: if (p == 1) {
218: PetscStrncpy(PetscErrorBaseMessage,lbuf,1023);
219: }
220: }
222: if (!eh) PetscTraceBackErrorHandler(line,func,file,dir,n,p,lbuf,0);
223: else (*eh->handler)(line,func,file,dir,n,p,lbuf,eh->ctx);
225: /*
226: If this is called from the main() routine we call MPI_Abort() instead of
227: return to allow the parallel program to be properly shutdown.
229: Since this is in the error handler we don't check the errors below. Of course,
230: PetscStrncmp() does its own error checking which is problamatic
231: */
232: PetscStrncmp(func,"main",4,&ismain);
233: PetscStrncmp(func,"unknown",7,&isunknown);
234: if (ismain || isunknown) {
235: MPI_Abort(PETSC_COMM_WORLD,ierr);
236: }
237: PetscFunctionReturn(ierr);
238: }
240: /* -------------------------------------------------------------------------*/
242: #undef __FUNCT__
244: /*@C
245: PetscIntView - Prints an array of integers; useful for debugging.
247: Collective on PetscViewer
249: Input Parameters:
250: + N - number of integers in array
251: . idx - array of integers
252: - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0
254: Level: intermediate
256: .seealso: PetscRealView()
257: @*/
258: int PetscIntView(int N,int idx[],PetscViewer viewer)
259: {
260: int j,i,n = N/20,p = N % 20,ierr;
261: PetscTruth isascii,issocket;
262: MPI_Comm comm;
265: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
268: PetscObjectGetComm((PetscObject)viewer,&comm);
270: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
271: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);
272: if (isascii) {
273: for (i=0; i<n; i++) {
274: PetscViewerASCIISynchronizedPrintf(viewer,"%d:",20*i);
275: for (j=0; j<20; j++) {
276: PetscViewerASCIISynchronizedPrintf(viewer," %d",idx[i*20+j]);
277: }
278: PetscViewerASCIISynchronizedPrintf(viewer,"n");
279: }
280: if (p) {
281: PetscViewerASCIISynchronizedPrintf(viewer,"%d:",20*n);
282: for (i=0; i<p; i++) { PetscViewerASCIISynchronizedPrintf(viewer," %d",idx[20*n+i]);}
283: PetscViewerASCIISynchronizedPrintf(viewer,"n");
284: }
285: PetscViewerFlush(viewer);
286: } else if (issocket) {
287: int *array,*sizes,rank,size,Ntotal,*displs;
289: MPI_Comm_rank(comm,&rank);
290: MPI_Comm_size(comm,&size);
292: if (size > 1) {
293: if (rank) {
294: MPI_Gather(&N,1,MPI_INT,0,0,MPI_INT,0,comm);
295: MPI_Gatherv(idx,N,MPI_INT,0,0,0,MPI_INT,0,comm);
296: } else {
297: ierr = PetscMalloc(size*sizeof(int),&sizes);
298: ierr = MPI_Gather(&N,1,MPI_INT,sizes,1,MPI_INT,0,comm);
299: Ntotal = sizes[0];
300: ierr = PetscMalloc(size*sizeof(int),&displs);
301: displs[0] = 0;
302: for (i=1; i<size; i++) {
303: Ntotal += sizes[i];
304: displs[i] = displs[i-1] + sizes[i-1];
305: }
306: PetscMalloc(Ntotal*sizeof(int),&array);
307: MPI_Gatherv(idx,N,MPI_INT,array,sizes,displs,MPI_INT,0,comm);
308: PetscViewerSocketPutInt(viewer,Ntotal,array);
309: PetscFree(sizes);
310: PetscFree(displs);
311: PetscFree(array);
312: }
313: } else {
314: PetscViewerSocketPutInt(viewer,N,idx);
315: }
316: } else {
317: SETERRQ(1,"Cannot handle that PetscViewer");
318: }
319: return(0);
320: }
322: #undef __FUNCT__
324: /*@C
325: PetscRealView - Prints an array of doubles; useful for debugging.
327: Collective on PetscViewer
329: Input Parameters:
330: + N - number of doubles in array
331: . idx - array of doubles
332: - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0
334: Level: intermediate
336: .seealso: PetscIntView()
337: @*/
338: int PetscRealView(int N,PetscReal idx[],PetscViewer viewer)
339: {
340: int j,i,n = N/5,p = N % 5,ierr;
341: PetscTruth isascii,issocket;
342: MPI_Comm comm;
345: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
348: PetscObjectGetComm((PetscObject)viewer,&comm);
350: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
351: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);
352: if (isascii) {
353: for (i=0; i<n; i++) {
354: PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*i);
355: for (j=0; j<5; j++) {
356: PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*5+j]);
357: }
358: PetscViewerASCIISynchronizedPrintf(viewer,"n");
359: }
360: if (p) {
361: PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*n);
362: for (i=0; i<p; i++) { PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[5*n+i]);}
363: PetscViewerASCIISynchronizedPrintf(viewer,"n");
364: }
365: PetscViewerFlush(viewer);
366: } else if (issocket) {
367: int *sizes,rank,size,Ntotal,*displs;
368: PetscReal *array;
370: MPI_Comm_rank(comm,&rank);
371: MPI_Comm_size(comm,&size);
373: if (size > 1) {
374: if (rank) {
375: MPI_Gather(&N,1,MPI_INT,0,0,MPI_INT,0,comm);
376: MPI_Gatherv(idx,N,MPI_DOUBLE,0,0,0,MPI_DOUBLE,0,comm);
377: } else {
378: ierr = PetscMalloc(size*sizeof(int),&sizes);
379: ierr = MPI_Gather(&N,1,MPI_INT,sizes,1,MPI_INT,0,comm);
380: Ntotal = sizes[0];
381: ierr = PetscMalloc(size*sizeof(int),&displs);
382: displs[0] = 0;
383: for (i=1; i<size; i++) {
384: Ntotal += sizes[i];
385: displs[i] = displs[i-1] + sizes[i-1];
386: }
387: PetscMalloc(Ntotal*sizeof(PetscReal),&array);
388: MPI_Gatherv(idx,N,MPI_DOUBLE,array,sizes,displs,MPI_DOUBLE,0,comm);
389: PetscViewerSocketPutReal(viewer,Ntotal,1,array);
390: PetscFree(sizes);
391: PetscFree(displs);
392: PetscFree(array);
393: }
394: } else {
395: PetscViewerSocketPutReal(viewer,N,1,idx);
396: }
397: } else {
398: SETERRQ(1,"Cannot handle that PetscViewer");
399: }
400: return(0);
401: }
403: #undef __FUNCT__
405: /*@C
406: PetscScalarView - Prints an array of scalars; useful for debugging.
408: Collective on PetscViewer
410: Input Parameters:
411: + N - number of scalars in array
412: . idx - array of scalars
413: - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0
415: Level: intermediate
417: .seealso: PetscIntView(), PetscRealView()
418: @*/
419: int PetscScalarView(int N,PetscScalar idx[],PetscViewer viewer)
420: {
421: int j,i,n = N/3,p = N % 3,ierr;
422: PetscTruth isascii,issocket;
423: MPI_Comm comm;
426: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
429: PetscObjectGetComm((PetscObject)viewer,&comm);
431: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
432: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);
433: if (isascii) {
434: for (i=0; i<n; i++) {
435: PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*i);
436: for (j=0; j<3; j++) {
437: #if defined (PETSC_USE_COMPLEX)
438: PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)",
439: PetscRealPart(idx[i*3+j]),PetscImaginaryPart(idx[i*3+j]));
440: #else
441: PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*3+j]);
442: #endif
443: }
444: PetscViewerASCIISynchronizedPrintf(viewer,"n");
445: }
446: if (p) {
447: PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*n);
448: for (i=0; i<p; i++) {
449: #if defined (PETSC_USE_COMPLEX)
450: PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)",
451: PetscRealPart(idx[n*3+i]),PetscImaginaryPart(idx[n*3+i]));
452: #else
453: PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[3*n+i]);
454: #endif
455: }
456: PetscViewerASCIISynchronizedPrintf(viewer,"n");
457: }
458: PetscViewerFlush(viewer);
459: } else if (issocket) {
460: int *sizes,rank,size,Ntotal,*displs;
461: PetscScalar *array;
463: MPI_Comm_rank(comm,&rank);
464: MPI_Comm_size(comm,&size);
466: if (size > 1) {
467: if (rank) {
468: MPI_Gather(&N,1,MPI_INT,0,0,MPI_INT,0,comm);
469: MPI_Gatherv(idx,N,MPIU_SCALAR,0,0,0,MPIU_SCALAR,0,comm);
470: } else {
471: ierr = PetscMalloc(size*sizeof(int),&sizes);
472: ierr = MPI_Gather(&N,1,MPI_INT,sizes,1,MPI_INT,0,comm);
473: Ntotal = sizes[0];
474: ierr = PetscMalloc(size*sizeof(int),&displs);
475: displs[0] = 0;
476: for (i=1; i<size; i++) {
477: Ntotal += sizes[i];
478: displs[i] = displs[i-1] + sizes[i-1];
479: }
480: PetscMalloc(Ntotal*sizeof(PetscScalar),&array);
481: MPI_Gatherv(idx,N,MPIU_SCALAR,array,sizes,displs,MPIU_SCALAR,0,comm);
482: PetscViewerSocketPutScalar(viewer,Ntotal,1,array);
483: PetscFree(sizes);
484: PetscFree(displs);
485: PetscFree(array);
486: }
487: } else {
488: PetscViewerSocketPutScalar(viewer,N,1,idx);
489: }
490: } else {
491: SETERRQ(1,"Cannot handle that PetscViewer");
492: }
493: return(0);
494: }
497: /*MC
498: SETERRQ - Macro that is called when an error has been detected,
500: Not Collective
502: Synopsis:
503: void SETERRQ(int errorcode,char *message)
506: Input Parameters:
507: + errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
508: - message - error message
510: Level: beginner
512: Notes:
513: Once the error handler is called the calling function is then returned from with the given error code.
515: See SETERRQ1(), SETERRQ2(), SETERRQ3() for versions that take arguments
518: Experienced users can set the error handler with PetscPushErrorHandler().
520: Concepts: error^setting condition
522: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ(), SETERRQ1(), SETERRQ2(), SETERRQ3()
523: M*/
525: /*MC
526: SETERRQ1 - Macro that is called when an error has been detected,
528: Not Collective
530: Synopsis:
531: void SETERRQ1(int errorcode,char *formatmessage,arg)
534: Input Parameters:
535: + errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
536: . message - error message in the printf format
537: - arg - argument (for example an integer, string or double)
539: Level: beginner
541: Notes:
542: Once the error handler is called the calling function is then returned from with the given error code.
544: Experienced users can set the error handler with PetscPushErrorHandler().
546: Concepts: error^setting condition
548: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ(), SETERRQ(), SETERRQ2(), SETERRQ3()
549: M*/
552: /*MC
553: SETERRQ2 - Macro that is called when an error has been detected,
555: Not Collective
557: Synopsis:
558: void SETERRQ2(int errorcode,char *formatmessage,arg1,arg2)
561: Input Parameters:
562: + errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
563: . message - error message in the printf format
564: . arg1 - argument (for example an integer, string or double)
565: - arg2 - argument (for example an integer, string or double)
567: Level: beginner
569: Notes:
570: Once the error handler is called the calling function is then returned from with the given error code.
572: Experienced users can set the error handler with PetscPushErrorHandler().
574: Concepts: error^setting condition
576: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ(), SETERRQ1(), SETERRQ2(), SETERRQ3()
577: M*/
579: /*MC
580: SETERRQ3 - Macro that is called when an error has been detected,
582: Not Collective
584: Synopsis:
585: void SETERRQ3(int errorcode,char *formatmessage,arg1,arg2,arg3)
588: Input Parameters:
589: + errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
590: . message - error message in the printf format
591: . arg1 - argument (for example an integer, string or double)
592: . arg2 - argument (for example an integer, string or double)
593: - arg3 - argument (for example an integer, string or double)
595: Level: beginner
597: Notes:
598: Once the error handler is called the calling function is then returned from with the given error code.
600: Experienced users can set the error handler with PetscPushErrorHandler().
602: Concepts: error^setting condition
604: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ(), SETERRQ1(), SETERRQ2(), SETERRQ2()
605: M*/
608: /*MC
609: CHKERRQ - Checks error code, if non-zero it calls the error handler and then returns
611: Not Collective
613: Synopsis:
614: void CHKERRQ(int errorcode)
617: Input Parameters:
618: . errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
620: Level: beginner
622: Notes:
623: Once the error handler is called the calling function is then returned from with the given error code.
625: Experienced users can set the error handler with PetscPushErrorHandler().
627: Concepts: error^setting condition
629: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ(), SETERRQ1(), SETERRQ2(), SETERRQ2()
630: M*/
632: /*MC
633: CHKMEMQ - Checks the memory for corruption, calls error handler if any is detected
635: Not Collective
637: Synopsis:
638: void CHKMEMQ(void)
640: Level: beginner
642: Notes:
643: Must run with the option -trdebug to enable this option
645: Once the error handler is called the calling function is then returned from with the given error code.
647: By defaults prints location where memory that is corrupted was allocated.
649: Concepts: memory corruption
651: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ(), SETERRQ1(), SETERRQ2(), SETERRQ2(),
652: PetscTrValid()
653: M*/