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 PetscFunctionBegin; 35 PetscFunctionReturn(n); 36 } 37 38 /* ---------------------------------------------------------------------------------------*/ 39 40 static char arch[128], hostname[128], username[128], pname[PETSC_MAX_PATH_LEN], date[128]; 41 static PetscBool PetscErrorPrintfInitializeCalled = PETSC_FALSE; 42 static char version[256]; 43 44 /* 45 Initializes arch, hostname, username, date so that system calls do NOT need 46 to be made during the error handler. 47 */ 48 PetscErrorCode PetscErrorPrintfInitialize(void) { 49 PetscBool use_stdout = PETSC_FALSE, use_none = PETSC_FALSE; 50 51 PetscFunctionBegin; 52 PetscCall(PetscGetArchType(arch, sizeof(arch))); 53 PetscCall(PetscGetHostName(hostname, sizeof(hostname))); 54 PetscCall(PetscGetUserName(username, sizeof(username))); 55 PetscCall(PetscGetProgramName(pname, sizeof(pname))); 56 PetscCall(PetscGetDate(date, sizeof(date))); 57 PetscCall(PetscGetVersion(version, sizeof(version))); 58 59 PetscCall(PetscOptionsGetBool(NULL, NULL, "-error_output_stdout", &use_stdout, NULL)); 60 if (use_stdout) PETSC_STDERR = PETSC_STDOUT; 61 PetscCall(PetscOptionsGetBool(NULL, NULL, "-error_output_none", &use_none, NULL)); 62 if (use_none) PetscErrorPrintf = PetscErrorPrintfNone; 63 PetscErrorPrintfInitializeCalled = PETSC_TRUE; 64 PetscFunctionReturn(0); 65 } 66 67 PetscErrorCode PetscErrorPrintfNone(const char format[], ...) { 68 return 0; 69 } 70 71 PetscErrorCode PetscErrorPrintfDefault(const char format[], ...) { 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 #if defined(PETSC_HAVE_UNISTD_H) && defined(PETSC_USE_ISATTY) 115 if (PetscErrorPrintf == PetscErrorPrintfDefault && PETSC_STDERR != PETSC_STDOUT) { 116 if (isatty(fileno(PETSC_STDERR))) fprintf(PETSC_STDERR, "\033[1;31m"); 117 } 118 #endif 119 } 120 121 static void PetscErrorPrintfNormal(void) { 122 #if defined(PETSC_HAVE_UNISTD_H) && defined(PETSC_USE_ISATTY) 123 if (PetscErrorPrintf == PetscErrorPrintfDefault && PETSC_STDERR != PETSC_STDOUT) { 124 if (isatty(fileno(PETSC_STDERR))) fprintf(PETSC_STDERR, "\033[0;39m\033[0;49m"); 125 } 126 #endif 127 } 128 129 PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void); 130 131 /*@C 132 133 PetscTraceBackErrorHandler - Default error handler routine that generates 134 a traceback on error detection. 135 136 Not Collective 137 138 Input Parameters: 139 + comm - communicator over which error occurred 140 . line - the line number of the error (indicated by __LINE__) 141 . file - the file in which the error was detected (indicated by __FILE__) 142 . mess - an error text string, usually just printed to the screen 143 . n - the generic error number 144 . p - PETSC_ERROR_INITIAL if this is the first call the error handler, otherwise PETSC_ERROR_REPEAT 145 - ctx - error handler context 146 147 Options Database: 148 + -error_output_stdout - output the error messages to stdout instead of the default stderr 149 - -error_output_none - do not output the error messages 150 151 Notes: 152 Most users need not directly employ this routine and the other error 153 handlers, but can instead use the simplified interface SETERRQ, which has 154 the calling sequence 155 $ SETERRQ(comm,number,n,mess) 156 157 Notes for experienced users: 158 Use PetscPushErrorHandler() to set the desired error handler. 159 160 Level: developer 161 162 .seealso: `PetscError()`, `PetscPushErrorHandler()`, `PetscPopErrorHandler()`, `PetscAttachDebuggerErrorHandler()`, 163 `PetscAbortErrorHandler()`, `PetscMPIAbortErrorHandler()`, `PetscReturnErrorHandler()`, `PetscEmacsClientErrorHandler()` 164 @*/ 165 PetscErrorCode PetscTraceBackErrorHandler(MPI_Comm comm, int line, const char *fun, const char *file, PetscErrorCode n, PetscErrorType p, const char *mess, void *ctx) { 166 PetscLogDouble mem, rss; 167 PetscBool flg1 = PETSC_FALSE, flg2 = PETSC_FALSE, flg3 = PETSC_FALSE; 168 PetscMPIInt rank = 0; 169 170 if (comm != PETSC_COMM_SELF) MPI_Comm_rank(comm, &rank); 171 172 if (rank == 0 && (!PetscCIEnabledPortableErrorOutput || PetscGlobalRank == 0)) { 173 PetscBool ismain; 174 static int cnt = 1; 175 176 if (cnt == 1) { 177 PetscErrorPrintfHilight(); 178 (*PetscErrorPrintf)("--------------------- Error Message --------------------------------------------------------------\n"); 179 PetscErrorPrintfNormal(); 180 if (n == PETSC_ERR_MEM) { 181 (*PetscErrorPrintf)("Out of memory. This could be due to allocating\n"); 182 (*PetscErrorPrintf)("too large an object or bleeding by not properly\n"); 183 (*PetscErrorPrintf)("destroying unneeded objects.\n"); 184 PetscMallocGetCurrentUsage(&mem); 185 PetscMemoryGetCurrentUsage(&rss); 186 PetscOptionsGetBool(NULL, NULL, "-malloc_dump", &flg1, NULL); 187 PetscOptionsGetBool(NULL, NULL, "-malloc_view", &flg2, NULL); 188 PetscOptionsHasName(NULL, NULL, "-malloc_view_threshold", &flg3); 189 if (flg2 || flg3) PetscMallocView(stdout); 190 else { 191 (*PetscErrorPrintf)("Memory allocated %.0f Memory used by process %.0f\n", mem, rss); 192 if (flg1) PetscMallocDump(stdout); 193 else (*PetscErrorPrintf)("Try running with -malloc_dump or -malloc_view for info.\n"); 194 } 195 } else { 196 const char *text; 197 PetscErrorMessage(n, &text, NULL); 198 if (text) (*PetscErrorPrintf)("%s\n", text); 199 } 200 if (mess) (*PetscErrorPrintf)("%s\n", mess); 201 PetscOptionsLeftError(); 202 (*PetscErrorPrintf)("See https://petsc.org/release/faq/ for trouble shooting.\n"); 203 if (!PetscCIEnabledPortableErrorOutput) { 204 (*PetscErrorPrintf)("%s\n", version); 205 if (PetscErrorPrintfInitializeCalled) (*PetscErrorPrintf)("%s on a %s named %s by %s %s\n", pname, arch, hostname, username, date); 206 (*PetscErrorPrintf)("Configure options %s\n", petscconfigureoptions); 207 } 208 } 209 /* print line of stack trace */ 210 if (fun) (*PetscErrorPrintf)("#%d %s() at %s:%d\n", cnt++, fun, PetscCIFilename(file), PetscCILinenumber(line)); 211 else if (file) (*PetscErrorPrintf)("#%d %s:%d\n", cnt++, PetscCIFilename(file), PetscCILinenumber(line)); 212 if (fun) { 213 PetscStrncmp(fun, "main", 4, &ismain); 214 if (ismain) { 215 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); } 216 PetscOptionsViewError(); 217 PetscErrorPrintfHilight(); 218 (*PetscErrorPrintf)("----------------End of Error Message -------send entire error message to petsc-maint@mcs.anl.gov----------\n"); 219 PetscErrorPrintfNormal(); 220 } 221 } 222 } else { 223 /* do not print error messages since process 0 will print them, sleep before aborting so will not accidentally kill process 0*/ 224 PetscSleep(10.0); 225 exit(0); 226 } 227 return n; 228 } 229