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