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 <stdarg.h>
7: #if defined(PETSC_HAVE_STDLIB_H)
8: #include <stdlib.h>
9: #endif
11: typedef struct _EH *EH;
12: struct _EH {
13: int cookie;
14: int (*handler)(int,char*,char*,char *,int,int,char*,void *);
15: void *ctx;
16: EH previous;
17: };
19: static EH eh = 0;
21: /*@C
22: PetscEmacsClientErrorHandler - Error handler that uses the emacsclient program to
23: load the file where the error occured. Then calls the "previous" error handler.
25: Not Collective
27: Input Parameters:
28: + line - the line number of the error (indicated by __LINE__)
29: . file - the file in which the error was detected (indicated by __FILE__)
30: . dir - the directory of the file (indicated by __SDIR__)
31: . mess - an error text string, usually just printed to the screen
32: . n - the generic error number
33: . p - specific error number
34: - ctx - error handler context
36: Options Database:
37: . -on_error_emacs <machinename>
39: Level: developer
41: Notes:
42: You must put (server-start) in your .emacs file for the emacsclient software to work
44: Most users need not directly employ this routine and the other error
45: handlers, but can instead use the simplified interface SETERRQ, which has
46: the calling sequence
47: $ SETERRQ(number,p,mess)
49: Notes for experienced users:
50: Use PetscPushErrorHandler() to set the desired error handler. The
51: currently available PETSc error handlers include PetscTraceBackErrorHandler(),
52: PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscStopErrorHandler()
54: Concepts: emacs^going to on error
55: Concepts: error handler^going to line in emacs
57: .seealso: PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(),
58: PetscAbortErrorHandler()
59: @*/
60: int PetscEmacsClientErrorHandler(int line,char *fun,char* file,char *dir,int n,int p,char *mess,void *ctx)
61: {
62: int ierr;
63: char command[1024],*pdir;
64: FILE *fp;
67: /* Note: don't check error codes since this an error handler :-) */
68: PetscGetPetscDir(&pdir);
69: sprintf(command,"emacsclient +%d %s/%s%sn",line,pdir,dir,file);
70: PetscPOpen(MPI_COMM_WORLD,(char*)ctx,command,"r",&fp);
71: PetscFClose(MPI_COMM_WORLD,fp);
72: PetscPopErrorHandler(); /* remove this handler from the stack of handlers */
73: if (!eh) PetscTraceBackErrorHandler(line,fun,file,dir,n,p,mess,0);
74: else (*eh->handler)(line,fun,file,dir,n,p,mess,eh->ctx);
75: PetscFunctionReturn(ierr);
76: }
78: /*@C
79: PetscPushErrorHandler - Sets a routine to be called on detection of errors.
81: Not Collective
83: Input Parameters:
84: + handler - error handler routine
85: - ctx - optional handler context that contains information needed by the handler (for
86: example file pointers for error messages etc.)
88: Calling sequence of handler:
89: $ int handler(int line,char *func,char *file,char *dir,int n,int p,char *mess,void *ctx);
91: . line - the line number of the error (indicated by __LINE__)
92: . file - the file in which the error was detected (indicated by __FILE__)
93: . dir - the directory of the file (indicated by __SDIR__)
94: . n - the generic error number (see list defined in include/petscerror.h)
95: . p - the specific error number
96: . mess - an error text string, usually just printed to the screen
97: - ctx - the error handler context
99: Options Database Keys:
100: + -on_error_attach_debugger <noxterm,gdb or dbx>
101: - -on_error_abort
103: Level: intermediate
105: Fortran Note:
106: This routine is not supported in Fortran.
108: .seealso: PetscPopErrorHandler(), PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), PetscTraceBackErrorHandler()
110: @*/
111: int PetscPushErrorHandler(int (*handler)(int,char *,char*,char*,int,int,char*,void*),void *ctx)
112: {
113: EH neweh;
117: PetscNew(struct _EH,&neweh);
118: if (eh) {neweh->previous = eh;}
119: else {neweh->previous = 0;}
120: neweh->handler = handler;
121: neweh->ctx = ctx;
122: eh = neweh;
123: return(0);
124: }
126: /*@C
127: PetscPopErrorHandler - Removes the latest error handler that was
128: pushed with PetscPushErrorHandler().
130: Not Collective
132: Level: intermediate
134: Fortran Note:
135: This routine is not supported in Fortran.
137: Concepts: error handler^setting
139: .seealso: PetscPushErrorHandler()
140: @*/
141: int PetscPopErrorHandler(void)
142: {
143: EH tmp;
147: if (!eh) return(0);
148: tmp = eh;
149: eh = eh->previous;
150: PetscFree(tmp);
152: return(0);
153: }
155: char PetscErrorBaseMessage[1024];
157: /*@C
158: PetscError - Routine that is called when an error has been detected,
159: usually called through the macro SETERRQ().
161: Not Collective
163: Input Parameters:
164: + line - the line number of the error (indicated by __LINE__)
165: . dir - the directory of file (indicated by __SDIR__)
166: . file - the file in which the error was detected (indicated by __FILE__)
167: . mess - an error text string, usually just printed to the screen
168: . n - the generic error number
169: . p - 1 indicates the error was initially detected, 0 indicates this is a traceback from a
170: previously detected error
171: - mess - formatted message string - aka printf
173: Level: intermediate
175: Notes:
176: Most users need not directly use this routine and the error handlers, but
177: can instead use the simplified interface SETERRQ, which has the calling
178: sequence
179: $ SETERRQ(n,mess)
181: Experienced users can set the error handler with PetscPushErrorHandler().
183: Concepts: error^setting condition
185: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), SETERRQ(), CHKERRQ(), CHKMEMQ(), SETERRQ1(), SETERRQ2()
186: @*/
187: int PetscError(int line,char *func,char* file,char *dir,int n,int p,char *mess,...)
188: {
189: va_list Argp;
190: int ierr;
191: char buf[2048],*lbuf = 0;
192: PetscTruth ismain,isunknown;
195: /* Compose the message evaluating the print format */
196: if (mess) {
197: va_start(Argp,mess);
198: #if defined(PETSC_HAVE_VPRINTF_CHAR)
199: vsprintf(buf,mess,(char *)Argp);
200: #else
201: vsprintf(buf,mess,Argp);
202: #endif
203: va_end(Argp);
204: lbuf = buf;
205: if (p == 1) {
206: PetscStrncpy(PetscErrorBaseMessage,lbuf,1023);
207: }
208: }
210: if (!eh) PetscTraceBackErrorHandler(line,func,file,dir,n,p,lbuf,0);
211: else (*eh->handler)(line,func,file,dir,n,p,lbuf,eh->ctx);
213: /*
214: If this is called from the main() routine we call MPI_Abort() instead of
215: return to allow the parallel program to be properly shutdown.
217: Since this is in the error handler we don't check the errors below. Of course,
218: PetscStrncmp() does its own error checking which is problamatic
219: */
220: PetscStrncmp(func,"main",4,&ismain);
221: PetscStrncmp(func,"unknown",7,&isunknown);
222: if (ismain || isunknown) {
223: MPI_Abort(PETSC_COMM_WORLD,ierr);
224: }
225: PetscFunctionReturn(ierr);
226: }
228: /* -------------------------------------------------------------------------*/
230: /*@C
231: PetscIntView - Prints an array of integers; useful for debugging.
233: Collective on PetscViewer
235: Input Parameters:
236: + N - number of integers in array
237: . idx - array of integers
238: - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0
240: Level: intermediate
242: .seealso: PetscRealView()
243: @*/
244: int PetscIntView(int N,int idx[],PetscViewer viewer)
245: {
246: int j,i,n = N/20,p = N % 20,ierr;
247: PetscTruth isascii,issocket;
248: MPI_Comm comm;
251: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
254: PetscObjectGetComm((PetscObject)viewer,&comm);
256: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
257: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);
258: if (isascii) {
259: for (i=0; i<n; i++) {
260: PetscViewerASCIISynchronizedPrintf(viewer,"%d:",20*i);
261: for (j=0; j<20; j++) {
262: PetscViewerASCIISynchronizedPrintf(viewer," %d",idx[i*20+j]);
263: }
264: PetscViewerASCIISynchronizedPrintf(viewer,"n");
265: }
266: if (p) {
267: PetscViewerASCIISynchronizedPrintf(viewer,"%d:",20*n);
268: for (i=0; i<p; i++) { PetscViewerASCIISynchronizedPrintf(viewer," %d",idx[20*n+i]);}
269: PetscViewerASCIISynchronizedPrintf(viewer,"n");
270: }
271: PetscViewerFlush(viewer);
272: } else if (issocket) {
273: int *array,*sizes,rank,size,Ntotal,*displs;
275: MPI_Comm_rank(comm,&rank);
276: MPI_Comm_size(comm,&size);
278: if (size > 1) {
279: if (rank) {
280: MPI_Gather(&N,1,MPI_INT,0,0,MPI_INT,0,comm);
281: MPI_Gatherv(idx,N,MPI_INT,0,0,0,MPI_INT,0,comm);
282: } else {
283: ierr = PetscMalloc(size*sizeof(int),&sizes);
284: ierr = MPI_Gather(&N,1,MPI_INT,sizes,1,MPI_INT,0,comm);
285: Ntotal = sizes[0];
286: ierr = PetscMalloc(size*sizeof(int),&displs);
287: displs[0] = 0;
288: for (i=1; i<size; i++) {
289: Ntotal += sizes[i];
290: displs[i] = displs[i-1] + sizes[i-1];
291: }
292: PetscMalloc(Ntotal*sizeof(int),&array);
293: MPI_Gatherv(idx,N,MPI_INT,array,sizes,displs,MPI_INT,0,comm);
294: PetscViewerSocketPutInt(viewer,Ntotal,array);
295: PetscFree(sizes);
296: PetscFree(displs);
297: PetscFree(array);
298: }
299: } else {
300: PetscViewerSocketPutInt(viewer,N,idx);
301: }
302: } else {
303: SETERRQ(1,"Cannot handle that PetscViewer");
304: }
305: return(0);
306: }
308: /*@C
309: PetscRealView - Prints an array of doubles; useful for debugging.
311: Collective on PetscViewer
313: Input Parameters:
314: + N - number of doubles in array
315: . idx - array of doubles
316: - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0
318: Level: intermediate
320: .seealso: PetscIntView()
321: @*/
322: int PetscRealView(int N,PetscReal idx[],PetscViewer viewer)
323: {
324: int j,i,n = N/5,p = N % 5,ierr;
325: PetscTruth isascii,issocket;
326: MPI_Comm comm;
329: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
332: PetscObjectGetComm((PetscObject)viewer,&comm);
334: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
335: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);
336: if (isascii) {
337: for (i=0; i<n; i++) {
338: PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*i);
339: for (j=0; j<5; j++) {
340: PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*5+j]);
341: }
342: PetscViewerASCIISynchronizedPrintf(viewer,"n");
343: }
344: if (p) {
345: PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*n);
346: for (i=0; i<p; i++) { PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[5*n+i]);}
347: PetscViewerASCIISynchronizedPrintf(viewer,"n");
348: }
349: PetscViewerFlush(viewer);
350: } else if (issocket) {
351: int *sizes,rank,size,Ntotal,*displs;
352: PetscReal *array;
354: MPI_Comm_rank(comm,&rank);
355: MPI_Comm_size(comm,&size);
357: if (size > 1) {
358: if (rank) {
359: MPI_Gather(&N,1,MPI_INT,0,0,MPI_INT,0,comm);
360: MPI_Gatherv(idx,N,MPI_DOUBLE,0,0,0,MPI_DOUBLE,0,comm);
361: } else {
362: ierr = PetscMalloc(size*sizeof(int),&sizes);
363: ierr = MPI_Gather(&N,1,MPI_INT,sizes,1,MPI_INT,0,comm);
364: Ntotal = sizes[0];
365: ierr = PetscMalloc(size*sizeof(int),&displs);
366: displs[0] = 0;
367: for (i=1; i<size; i++) {
368: Ntotal += sizes[i];
369: displs[i] = displs[i-1] + sizes[i-1];
370: }
371: PetscMalloc(Ntotal*sizeof(PetscReal),&array);
372: MPI_Gatherv(idx,N,MPI_DOUBLE,array,sizes,displs,MPI_DOUBLE,0,comm);
373: PetscViewerSocketPutReal(viewer,Ntotal,1,array);
374: PetscFree(sizes);
375: PetscFree(displs);
376: PetscFree(array);
377: }
378: } else {
379: PetscViewerSocketPutReal(viewer,N,1,idx);
380: }
381: } else {
382: SETERRQ(1,"Cannot handle that PetscViewer");
383: }
384: return(0);
385: }
387: /*@C
388: PetscScalarView - Prints an array of scalars; useful for debugging.
390: Collective on PetscViewer
392: Input Parameters:
393: + N - number of scalars in array
394: . idx - array of scalars
395: - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0
397: Level: intermediate
399: .seealso: PetscIntView(), PetscRealView()
400: @*/
401: int PetscScalarView(int N,PetscScalar idx[],PetscViewer viewer)
402: {
403: int j,i,n = N/3,p = N % 3,ierr;
404: PetscTruth isascii,issocket;
405: MPI_Comm comm;
408: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
411: PetscObjectGetComm((PetscObject)viewer,&comm);
413: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
414: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);
415: if (isascii) {
416: for (i=0; i<n; i++) {
417: PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*i);
418: for (j=0; j<3; j++) {
419: #if defined (PETSC_USE_COMPLEX)
420: PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)",
421: PetscRealPart(idx[i*3+j]),PetscImaginaryPart(idx[i*3+j]));
422: #else
423: PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*3+j]);
424: #endif
425: }
426: PetscViewerASCIISynchronizedPrintf(viewer,"n");
427: }
428: if (p) {
429: PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*n);
430: for (i=0; i<p; i++) {
431: #if defined (PETSC_USE_COMPLEX)
432: PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)",
433: PetscRealPart(idx[n*3+i]),PetscImaginaryPart(idx[n*3+i]));
434: #else
435: PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[3*n+i]);
436: #endif
437: }
438: PetscViewerASCIISynchronizedPrintf(viewer,"n");
439: }
440: PetscViewerFlush(viewer);
441: } else if (issocket) {
442: int *sizes,rank,size,Ntotal,*displs;
443: PetscScalar *array;
445: MPI_Comm_rank(comm,&rank);
446: MPI_Comm_size(comm,&size);
448: if (size > 1) {
449: if (rank) {
450: MPI_Gather(&N,1,MPI_INT,0,0,MPI_INT,0,comm);
451: MPI_Gatherv(idx,N,MPIU_SCALAR,0,0,0,MPIU_SCALAR,0,comm);
452: } else {
453: ierr = PetscMalloc(size*sizeof(int),&sizes);
454: ierr = MPI_Gather(&N,1,MPI_INT,sizes,1,MPI_INT,0,comm);
455: Ntotal = sizes[0];
456: ierr = PetscMalloc(size*sizeof(int),&displs);
457: displs[0] = 0;
458: for (i=1; i<size; i++) {
459: Ntotal += sizes[i];
460: displs[i] = displs[i-1] + sizes[i-1];
461: }
462: PetscMalloc(Ntotal*sizeof(PetscScalar),&array);
463: MPI_Gatherv(idx,N,MPIU_SCALAR,array,sizes,displs,MPIU_SCALAR,0,comm);
464: PetscViewerSocketPutScalar(viewer,Ntotal,1,array);
465: PetscFree(sizes);
466: PetscFree(displs);
467: PetscFree(array);
468: }
469: } else {
470: PetscViewerSocketPutScalar(viewer,N,1,idx);
471: }
472: } else {
473: SETERRQ(1,"Cannot handle that PetscViewer");
474: }
475: return(0);
476: }
479: /*MC
480: SETERRQ - Macro that is called when an error has been detected,
482: Not Collective
484: Synopsis:
485: void SETERRQ(int errorcode,char *message)
488: Input Parameters:
489: + errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
490: - message - error message
492: Level: beginner
494: Notes:
495: Once the error handler is called the calling function is then returned from with the given error code.
497: See SETERRQ1(), SETERRQ2(), SETERRQ3() for versions that take arguments
500: Experienced users can set the error handler with PetscPushErrorHandler().
502: Concepts: error^setting condition
504: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ(), SETERRQ1(), SETERRQ2(), SETERRQ3()
505: M*/
507: /*MC
508: SETERRQ1 - Macro that is called when an error has been detected,
510: Not Collective
512: Synopsis:
513: void SETERRQ1(int errorcode,char *formatmessage,arg)
516: Input Parameters:
517: + errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
518: . message - error message in the printf format
519: - arg - argument (for example an integer, string or double)
521: Level: beginner
523: Notes:
524: Once the error handler is called the calling function is then returned from with the given error code.
526: Experienced users can set the error handler with PetscPushErrorHandler().
528: Concepts: error^setting condition
530: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ(), SETERRQ(), SETERRQ2(), SETERRQ3()
531: M*/
534: /*MC
535: SETERRQ2 - Macro that is called when an error has been detected,
537: Not Collective
539: Synopsis:
540: void SETERRQ2(int errorcode,char *formatmessage,arg1,arg2)
543: Input Parameters:
544: + errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
545: . message - error message in the printf format
546: . arg1 - argument (for example an integer, string or double)
547: - arg2 - argument (for example an integer, string or double)
549: Level: beginner
551: Notes:
552: Once the error handler is called the calling function is then returned from with the given error code.
554: Experienced users can set the error handler with PetscPushErrorHandler().
556: Concepts: error^setting condition
558: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ(), SETERRQ1(), SETERRQ2(), SETERRQ3()
559: M*/
561: /*MC
562: SETERRQ3 - Macro that is called when an error has been detected,
564: Not Collective
566: Synopsis:
567: void SETERRQ3(int errorcode,char *formatmessage,arg1,arg2,arg3)
570: Input Parameters:
571: + errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
572: . message - error message in the printf format
573: . arg1 - argument (for example an integer, string or double)
574: . arg2 - argument (for example an integer, string or double)
575: - arg3 - argument (for example an integer, string or double)
577: Level: beginner
579: Notes:
580: Once the error handler is called the calling function is then returned from with the given error code.
582: Experienced users can set the error handler with PetscPushErrorHandler().
584: Concepts: error^setting condition
586: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ(), SETERRQ1(), SETERRQ2(), SETERRQ2()
587: M*/
590: /*MC
591: CHKERRQ - Checks error code, if non-zero it calls the error handler and then returns
593: Not Collective
595: Synopsis:
596: void CHKERRQ(int errorcode)
599: Input Parameters:
600: . errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
602: Level: beginner
604: Notes:
605: Once the error handler is called the calling function is then returned from with the given error code.
607: Experienced users can set the error handler with PetscPushErrorHandler().
609: Concepts: error^setting condition
611: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ(), SETERRQ1(), SETERRQ2(), SETERRQ2()
612: M*/
614: /*MC
615: CHKMEMQ - Checks the memory for corruption, calls error handler if any is detected
617: Not Collective
619: Synopsis:
620: void CHKMEMQ(void)
622: Level: beginner
624: Notes:
625: Must run with the option -trdebug to enable this option
627: Once the error handler is called the calling function is then returned from with the given error code.
629: By defaults prints location where memory that is corrupted was allocated.
631: Concepts: memory corruption
633: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ(), SETERRQ1(), SETERRQ2(), SETERRQ2(),
634: PetscTrValid()
635: M*/