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 return n; 35 } 36 37 /* ---------------------------------------------------------------------------------------*/ 38 39 static char arch[128], hostname[128], username[128], pname[PETSC_MAX_PATH_LEN], date[128]; 40 static PetscBool PetscErrorPrintfInitializeCalled = PETSC_FALSE; 41 static char version[256]; 42 43 /* 44 Initializes arch, hostname, username, date so that system calls do NOT need 45 to be made during the error handler. 46 */ 47 PetscErrorCode PetscErrorPrintfInitialize(void) { 48 PetscBool use_stdout = PETSC_FALSE, use_none = PETSC_FALSE; 49 50 PetscFunctionBegin; 51 PetscCall(PetscGetArchType(arch, sizeof(arch))); 52 PetscCall(PetscGetHostName(hostname, sizeof(hostname))); 53 PetscCall(PetscGetUserName(username, sizeof(username))); 54 PetscCall(PetscGetProgramName(pname, sizeof(pname))); 55 PetscCall(PetscGetDate(date, sizeof(date))); 56 PetscCall(PetscGetVersion(version, sizeof(version))); 57 58 PetscCall(PetscOptionsGetBool(NULL, NULL, "-error_output_stdout", &use_stdout, NULL)); 59 if (use_stdout) PETSC_STDERR = PETSC_STDOUT; 60 PetscCall(PetscOptionsGetBool(NULL, NULL, "-error_output_none", &use_none, NULL)); 61 if (use_none) PetscErrorPrintf = PetscErrorPrintfNone; 62 PetscErrorPrintfInitializeCalled = PETSC_TRUE; 63 PetscFunctionReturn(0); 64 } 65 66 PetscErrorCode PetscErrorPrintfNone(const char format[], ...) { 67 return 0; 68 } 69 70 PetscErrorCode PetscErrorPrintfDefault(const char format[], ...) { 71 va_list Argp; 72 static PetscBool PetscErrorPrintfCalled = PETSC_FALSE; 73 74 /* 75 This function does not call PetscFunctionBegin and PetscFunctionReturn() because 76 it may be called by PetscStackView(). 77 78 This function does not do error checking because it is called by the error handlers. 79 */ 80 81 if (!PetscErrorPrintfCalled) { 82 PetscErrorPrintfCalled = PETSC_TRUE; 83 84 /* 85 On the SGI machines and Cray T3E, if errors are generated "simultaneously" by 86 different processors, the messages are printed all jumbled up; to try to 87 prevent this we have each processor wait based on their rank 88 */ 89 #if defined(PETSC_CAN_SLEEP_AFTER_ERROR) 90 { 91 PetscMPIInt rank; 92 if (PetscGlobalRank > 8) rank = 8; 93 else rank = PetscGlobalRank; 94 PetscSleep((PetscReal)rank); 95 } 96 #endif 97 } 98 99 PetscFPrintf(PETSC_COMM_SELF, PETSC_STDERR, "[%d]PETSC ERROR: ", PetscGlobalRank); 100 va_start(Argp, format); 101 (*PetscVFPrintf)(PETSC_STDERR, format, Argp); 102 va_end(Argp); 103 return 0; 104 } 105 106 /* 107 On some systems when the stderr is nested through several levels of shell script 108 before being passed to a file the isatty() falsely returns true resulting in 109 the screen highlight variables being passed through the test harness. Therefore 110 simply do not highlight when the PETSC_STDERR is PETSC_STDOUT. 111 */ 112 static void PetscErrorPrintfHilight(void) { 113 #if defined(PETSC_HAVE_UNISTD_H) && defined(PETSC_USE_ISATTY) 114 if (PetscErrorPrintf == PetscErrorPrintfDefault && PETSC_STDERR != PETSC_STDOUT) { 115 if (isatty(fileno(PETSC_STDERR))) fprintf(PETSC_STDERR, "\033[1;31m"); 116 } 117 #endif 118 } 119 120 static void PetscErrorPrintfNormal(void) { 121 #if defined(PETSC_HAVE_UNISTD_H) && defined(PETSC_USE_ISATTY) 122 if (PetscErrorPrintf == PetscErrorPrintfDefault && PETSC_STDERR != PETSC_STDOUT) { 123 if (isatty(fileno(PETSC_STDERR))) fprintf(PETSC_STDERR, "\033[0;39m\033[0;49m"); 124 } 125 #endif 126 } 127 128 PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void); 129 130 /*@C 131 132 PetscTraceBackErrorHandler - Default error handler routine that generates 133 a traceback on error detection. 134 135 Not Collective 136 137 Input Parameters: 138 + comm - communicator over which error occurred 139 . line - the line number of the error (indicated by __LINE__) 140 . file - the file in which the error was detected (indicated by __FILE__) 141 . mess - an error text string, usually just printed to the screen 142 . n - the generic error number 143 . p - PETSC_ERROR_INITIAL if this is the first call the error handler, otherwise PETSC_ERROR_REPEAT 144 - ctx - error handler context 145 146 Options Database: 147 + -error_output_stdout - output the error messages to stdout instead of the default stderr 148 - -error_output_none - do not output the error messages 149 150 Notes: 151 Most users need not directly employ this routine and the other error 152 handlers, but can instead use the simplified interface SETERRQ, which has 153 the calling sequence 154 $ SETERRQ(comm,number,n,mess) 155 156 Notes for experienced users: 157 Use PetscPushErrorHandler() to set the desired error handler. 158 159 Level: developer 160 161 .seealso: `PetscError()`, `PetscPushErrorHandler()`, `PetscPopErrorHandler()`, `PetscAttachDebuggerErrorHandler()`, 162 `PetscAbortErrorHandler()`, `PetscMPIAbortErrorHandler()`, `PetscReturnErrorHandler()`, `PetscEmacsClientErrorHandler()` 163 @*/ 164 PetscErrorCode PetscTraceBackErrorHandler(MPI_Comm comm, int line, const char *fun, const char *file, PetscErrorCode n, PetscErrorType p, const char *mess, void *ctx) { 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