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 186 if (p == PETSC_ERROR_INITIAL) { 187 PetscErrorPrintfHilight(); 188 ierr = (*PetscErrorPrintf)("--------------------- Error Message --------------------------------------------------------------\n"); 189 PetscErrorPrintfNormal(); 190 if (cnt > 1) { 191 ierr = (*PetscErrorPrintf)(" It appears a new error in the code was triggered after a previous error was not properly handled\n"); 192 ierr = (*PetscErrorPrintf)(" via (for example) the use of PetscCall(TheFunctionThatErrors());\n"); 193 ierr = (*PetscErrorPrintf)(" ALL ERRORS in the PETSc libraries are fatal, you should add the appropriate error checking to the code\n"); 194 cnt = 1; 195 } 196 } 197 if (cnt == 1) { 198 if (n == PETSC_ERR_MEM) { 199 ierr = (*PetscErrorPrintf)("Out of memory. This could be due to allocating\n"); 200 ierr = (*PetscErrorPrintf)("too large an object or bleeding by not properly\n"); 201 ierr = (*PetscErrorPrintf)("destroying unneeded objects.\n"); 202 ierr = PetscMallocGetCurrentUsage(&mem); 203 ierr = PetscMemoryGetCurrentUsage(&rss); 204 ierr = PetscOptionsGetBool(NULL, NULL, "-malloc_dump", &flg1, NULL); 205 ierr = PetscOptionsGetBool(NULL, NULL, "-malloc_view", &flg2, NULL); 206 ierr = PetscOptionsHasName(NULL, NULL, "-malloc_view_threshold", &flg3); 207 if (flg2 || flg3) ierr = PetscMallocView(stdout); 208 else { 209 ierr = (*PetscErrorPrintf)("Memory allocated %.0f Memory used by process %.0f\n", mem, rss); 210 if (flg1) ierr = PetscMallocDump(stdout); 211 else ierr = (*PetscErrorPrintf)("Try running with -malloc_dump or -malloc_view for info.\n"); 212 } 213 } else { 214 const char *text; 215 ierr = PetscErrorMessage(n, &text, NULL); 216 if (text) ierr = (*PetscErrorPrintf)("%s\n", text); 217 } 218 if (mess) ierr = (*PetscErrorPrintf)("%s\n", mess); 219 ierr = PetscOptionsLeftError(); 220 ierr = (*PetscErrorPrintf)("See https://petsc.org/release/faq/ for trouble shooting.\n"); 221 if (!PetscCIEnabledPortableErrorOutput) { 222 ierr = (*PetscErrorPrintf)("%s\n", version); 223 if (PetscErrorPrintfInitializeCalled) ierr = (*PetscErrorPrintf)("%s on a %s named %s by %s %s\n", pname, arch, hostname, username, date); 224 ierr = (*PetscErrorPrintf)("Configure options %s\n", petscconfigureoptions); 225 } 226 } 227 /* print line of stack trace */ 228 if (fun) ierr = (*PetscErrorPrintf)("#%d %s() at %s:%d\n", cnt++, fun, PetscCIFilename(file), PetscCILinenumber(line)); 229 else if (file) ierr = (*PetscErrorPrintf)("#%d %s:%d\n", cnt++, PetscCIFilename(file), PetscCILinenumber(line)); 230 if (fun) { 231 PetscBool ismain = PETSC_FALSE; 232 233 ierr = PetscStrncmp(fun, "main", 4, &ismain); 234 if (ismain) { 235 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); 236 ierr = PetscOptionsViewError(); 237 PetscErrorPrintfHilight(); 238 ierr = (*PetscErrorPrintf)("----------------End of Error Message -------send entire error message to petsc-maint@mcs.anl.gov----------\n"); 239 PetscErrorPrintfNormal(); 240 } 241 } 242 } else { 243 /* do not print error messages since process 0 will print them, sleep before aborting so will not accidentally kill process 0*/ 244 ierr = PetscSleep(10.0); 245 exit(0); 246 } 247 (void)ierr; 248 return n; 249 } 250