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