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