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*/