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