1 2 #include <petscsys.h> /*I "petscsys.h" I*/ 3 #include <petsc/private/petscimpl.h> 4 #include <petscconfiginfo.h> 5 #if defined(PETSC_HAVE_UNISTD_H) 6 #include <unistd.h> 7 #endif 8 9 #undef __FUNCT__ 10 #define __FUNCT__ "PetscIgnoreErrorHandler" 11 /*@C 12 PetscIgnoreErrorHandler - Ignores the error, allows program to continue as if error did not occure 13 14 Not Collective 15 16 Input Parameters: 17 + comm - communicator over which error occurred 18 . line - the line number of the error (indicated by __LINE__) 19 . func - the function where error is detected (indicated by __FUNCT__) 20 . file - the file in which the error was detected (indicated by __FILE__) 21 . mess - an error text string, usually just printed to the screen 22 . n - the generic error number 23 . p - specific error number 24 - ctx - error handler context 25 26 Level: developer 27 28 Notes: 29 Most users need not directly employ this routine and the other error 30 handlers, but can instead use the simplified interface SETERRQ, which has 31 the calling sequence 32 $ SETERRQ(comm,number,p,mess) 33 34 Notes for experienced users: 35 Use PetscPushErrorHandler() to set the desired error handler. The 36 currently available PETSc error handlers include PetscTraceBackErrorHandler(), 37 PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscMPIAbortErrorHandler() 38 39 Concepts: error handler^traceback 40 Concepts: traceback^generating 41 42 .seealso: PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(), 43 PetscAbortErrorHandler(), PetscTraceBackErrorHandler() 44 @*/ 45 PetscErrorCode PetscIgnoreErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode n,PetscErrorType p,const char *mess,void *ctx) 46 { 47 PetscFunctionBegin; 48 PetscFunctionReturn(n); 49 } 50 51 /* ---------------------------------------------------------------------------------------*/ 52 53 static char arch[128],hostname[128],username[128],pname[PETSC_MAX_PATH_LEN],date[128]; 54 static PetscBool PetscErrorPrintfInitializeCalled = PETSC_FALSE; 55 static char version[256]; 56 57 #undef __FUNCT__ 58 #define __FUNCT__ "PetscErrorPrintfInitialize" 59 /* 60 Initializes arch, hostname, username,date so that system calls do NOT need 61 to be made during the error handler. 62 */ 63 PetscErrorCode PetscErrorPrintfInitialize() 64 { 65 PetscErrorCode ierr; 66 PetscBool use_stdout = PETSC_FALSE,use_none = PETSC_FALSE; 67 68 PetscFunctionBegin; 69 ierr = PetscGetArchType(arch,sizeof(arch));CHKERRQ(ierr); 70 ierr = PetscGetHostName(hostname,sizeof(hostname));CHKERRQ(ierr); 71 ierr = PetscGetUserName(username,sizeof(username));CHKERRQ(ierr); 72 ierr = PetscGetProgramName(pname,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 73 ierr = PetscGetDate(date,sizeof(date));CHKERRQ(ierr); 74 ierr = PetscGetVersion(version,sizeof(version));CHKERRQ(ierr); 75 76 ierr = PetscOptionsGetBool(NULL,NULL,"-error_output_stdout",&use_stdout,NULL);CHKERRQ(ierr); 77 if (use_stdout) PETSC_STDERR = PETSC_STDOUT; 78 ierr = PetscOptionsGetBool(NULL,NULL,"-error_output_none",&use_none,NULL);CHKERRQ(ierr); 79 if (use_none) PetscErrorPrintf = PetscErrorPrintfNone; 80 PetscErrorPrintfInitializeCalled = PETSC_TRUE; 81 PetscFunctionReturn(0); 82 } 83 84 #undef __FUNCT__ 85 #define __FUNCT__ "PetscErrorPrintfNone" 86 PetscErrorCode PetscErrorPrintfNone(const char format[],...) 87 { 88 return 0; 89 } 90 91 #undef __FUNCT__ 92 #define __FUNCT__ "PetscErrorPrintfDefault" 93 PetscErrorCode PetscErrorPrintfDefault(const char format[],...) 94 { 95 va_list Argp; 96 static PetscBool PetscErrorPrintfCalled = PETSC_FALSE; 97 98 /* 99 This function does not call PetscFunctionBegin and PetscFunctionReturn() because 100 it may be called by PetscStackView(). 101 102 This function does not do error checking because it is called by the error handlers. 103 */ 104 105 if (!PetscErrorPrintfCalled) { 106 PetscErrorPrintfCalled = PETSC_TRUE; 107 108 /* 109 On the SGI machines and Cray T3E, if errors are generated "simultaneously" by 110 different processors, the messages are printed all jumbled up; to try to 111 prevent this we have each processor wait based on their rank 112 */ 113 #if defined(PETSC_CAN_SLEEP_AFTER_ERROR) 114 { 115 PetscMPIInt rank; 116 if (PetscGlobalRank > 8) rank = 8; 117 else rank = PetscGlobalRank; 118 PetscSleep((PetscReal)rank); 119 } 120 #endif 121 } 122 123 PetscFPrintf(PETSC_COMM_SELF,PETSC_STDERR,"[%d]PETSC ERROR: ",PetscGlobalRank); 124 va_start(Argp,format); 125 (*PetscVFPrintf)(PETSC_STDERR,format,Argp); 126 va_end(Argp); 127 return 0; 128 } 129 130 static void PetscErrorPrintfHilight(void) 131 { 132 #if defined(PETSC_HAVE_UNISTD_H) && defined(PETSC_USE_ISATTY) 133 if (PetscErrorPrintf == PetscErrorPrintfDefault) { 134 if (isatty(fileno(PETSC_STDERR))) fprintf(PETSC_STDERR,"\033[1;31m"); 135 } 136 #endif 137 } 138 139 static void PetscErrorPrintfNormal(void) 140 { 141 #if defined(PETSC_HAVE_UNISTD_H) && defined(PETSC_USE_ISATTY) 142 if (PetscErrorPrintf == PetscErrorPrintfDefault) { 143 if (isatty(fileno(PETSC_STDERR))) fprintf(PETSC_STDERR,"\033[0;39m\033[0;49m"); 144 } 145 #endif 146 } 147 148 extern PetscErrorCode PetscOptionsViewError(void); 149 150 #undef __FUNCT__ 151 #define __FUNCT__ "PetscTraceBackErrorHandler" 152 /*@C 153 154 PetscTraceBackErrorHandler - Default error handler routine that generates 155 a traceback on error detection. 156 157 Not Collective 158 159 Input Parameters: 160 + comm - communicator over which error occurred 161 . line - the line number of the error (indicated by __LINE__) 162 . func - the function where error is detected (indicated by __FUNCT__) 163 . file - the file in which the error was detected (indicated by __FILE__) 164 . mess - an error text string, usually just printed to the screen 165 . n - the generic error number 166 . p - PETSC_ERROR_INITIAL if this is the first call the error handler, otherwise PETSC_ERROR_REPEAT 167 - ctx - error handler context 168 169 Level: developer 170 171 Notes: 172 Most users need not directly employ this routine and the other error 173 handlers, but can instead use the simplified interface SETERRQ, which has 174 the calling sequence 175 $ SETERRQ(comm,number,n,mess) 176 177 Notes for experienced users: 178 Use PetscPushErrorHandler() to set the desired error handler. The 179 currently available PETSc error handlers include PetscTraceBackErrorHandler(), 180 PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscMPIAbortErrorHandler() 181 182 Concepts: error handler^traceback 183 Concepts: traceback^generating 184 185 .seealso: PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(), 186 PetscAbortErrorHandler() 187 @*/ 188 PetscErrorCode PetscTraceBackErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode n,PetscErrorType p,const char *mess,void *ctx) 189 { 190 PetscLogDouble mem,rss; 191 PetscBool flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE; 192 PetscMPIInt rank = 0; 193 194 PetscFunctionBegin; 195 if (comm != PETSC_COMM_SELF) MPI_Comm_rank(comm,&rank); 196 197 if (!rank) { 198 PetscBool ismain,isunknown; 199 static int cnt = 1; 200 201 if (p == PETSC_ERROR_INITIAL) { 202 PetscErrorPrintfHilight(); 203 (*PetscErrorPrintf)("--------------------- Error Message --------------------------------------------------------------\n"); 204 PetscErrorPrintfNormal(); 205 if (n == PETSC_ERR_MEM) { 206 (*PetscErrorPrintf)("Out of memory. This could be due to allocating\n"); 207 (*PetscErrorPrintf)("too large an object or bleeding by not properly\n"); 208 (*PetscErrorPrintf)("destroying unneeded objects.\n"); 209 PetscMallocGetCurrentUsage(&mem); 210 PetscMemoryGetCurrentUsage(&rss); 211 PetscOptionsGetBool(NULL,NULL,"-malloc_dump",&flg1,NULL); 212 PetscOptionsGetBool(NULL,NULL,"-malloc_log",&flg2,NULL); 213 PetscOptionsHasName(NULL,NULL,"-malloc_log_threshold",&flg3); 214 if (flg2 || flg3) PetscMallocDumpLog(stdout); 215 else { 216 (*PetscErrorPrintf)("Memory allocated %.0f Memory used by process %.0f\n",mem,rss); 217 if (flg1) PetscMallocDump(stdout); 218 else (*PetscErrorPrintf)("Try running with -malloc_dump or -malloc_log for info.\n"); 219 } 220 } else { 221 const char *text; 222 PetscErrorMessage(n,&text,NULL); 223 if (text) (*PetscErrorPrintf)("%s\n",text); 224 } 225 if (mess) (*PetscErrorPrintf)("%s\n",mess); 226 (*PetscErrorPrintf)("See http://www.mcs.anl.gov/petsc/documentation/faq.html for trouble shooting.\n"); 227 (*PetscErrorPrintf)("%s\n",version); 228 if (PetscErrorPrintfInitializeCalled) (*PetscErrorPrintf)("%s on a %s named %s by %s %s\n",pname,arch,hostname,username,date); 229 (*PetscErrorPrintf)("Configure options %s\n",petscconfigureoptions); 230 } 231 /* print line of stack trace */ 232 (*PetscErrorPrintf)("#%d %s() line %d in %s\n",cnt++,fun,line,file); 233 PetscStrncmp(fun,"main",4,&ismain); 234 PetscStrncmp(fun,"unknown",7,&isunknown); 235 if (ismain || isunknown) { 236 PetscOptionsViewError(); 237 PetscErrorPrintfHilight(); 238 (*PetscErrorPrintf)("----------------End of Error Message -------send entire error message to petsc-maint@mcs.anl.gov----------\n"); 239 PetscErrorPrintfNormal(); 240 } 241 } else { 242 /* do not print error messages since process 0 will print them, sleep before aborting so will not accidently kill process 0*/ 243 PetscSleep(10.0); 244 abort(); 245 } 246 PetscFunctionReturn(n); 247 } 248 249