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