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