Actual source code: errtrace.c
1: #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for fileno() */
2: #include <petscsys.h>
3: #include <petsc/private/petscimpl.h>
4: #include <petscconfiginfo.h>
5: #if defined(PETSC_HAVE_UNISTD_H)
6: #include <unistd.h>
7: #endif
9: /*@C
10: PetscIgnoreErrorHandler - Deprecated, use `PetscReturnErrorHandler()`. Ignores the error, allows program to continue as if error did not occur
12: Not Collective
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
23: Level: developer
25: Note:
26: Users do not directly call this routine
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: }
35: /* ---------------------------------------------------------------------------------------*/
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];
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;
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)));
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: }
65: PetscErrorCode PetscErrorPrintfNone(const char format[], ...)
66: {
67: return PETSC_SUCCESS;
68: }
70: PetscErrorCode PetscErrorPrintfDefault(const char format[], ...)
71: {
72: va_list Argp;
73: static PetscBool PetscErrorPrintfCalled = PETSC_FALSE;
74: PetscErrorCode ierr;
76: /*
77: This function does not call PetscFunctionBegin and PetscFunctionReturn() because
78: it may be called by PetscStackView().
80: This function does not do error checking because it is called by the error handlers.
81: */
83: if (!PetscErrorPrintfCalled) {
84: PetscErrorPrintfCalled = PETSC_TRUE;
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: }
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: }
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: }
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: }
132: PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void);
134: /*@C
136: PetscTraceBackErrorHandler - Default error handler routine that generates
137: a traceback on error detection.
139: Not Collective
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
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
154: Notes:
155: Users do not directly call this routine
157: Use `PetscPushErrorHandler()` to set the desired error handler.
159: Level: developer
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;
171: if (comm != PETSC_COMM_SELF) MPI_Comm_rank(comm, &rank);
173: if (rank == 0 && (!PetscCIEnabledPortableErrorOutput || PetscGlobalRank == 0)) {
174: static int cnt = 1;
176: /* reset counter to one in case a new error is thrown */
177: if (p == PETSC_ERROR_INITIAL) cnt = 1;
178: if (cnt == 1) {
179: PetscErrorPrintfHilight();
180: ierr = (*PetscErrorPrintf)("--------------------- Error Message --------------------------------------------------------------\n");
181: PetscErrorPrintfNormal();
182: if (n == PETSC_ERR_MEM) {
183: ierr = (*PetscErrorPrintf)("Out of memory. This could be due to allocating\n");
184: ierr = (*PetscErrorPrintf)("too large an object or bleeding by not properly\n");
185: ierr = (*PetscErrorPrintf)("destroying unneeded objects.\n");
186: ierr = PetscMallocGetCurrentUsage(&mem);
187: ierr = PetscMemoryGetCurrentUsage(&rss);
188: ierr = PetscOptionsGetBool(NULL, NULL, "-malloc_dump", &flg1, NULL);
189: ierr = PetscOptionsGetBool(NULL, NULL, "-malloc_view", &flg2, NULL);
190: ierr = PetscOptionsHasName(NULL, NULL, "-malloc_view_threshold", &flg3);
191: if (flg2 || flg3) ierr = PetscMallocView(stdout);
192: else {
193: ierr = (*PetscErrorPrintf)("Memory allocated %.0f Memory used by process %.0f\n", mem, rss);
194: if (flg1) ierr = PetscMallocDump(stdout);
195: else ierr = (*PetscErrorPrintf)("Try running with -malloc_dump or -malloc_view for info.\n");
196: }
197: } else {
198: const char *text;
199: ierr = PetscErrorMessage(n, &text, NULL);
200: if (text) ierr = (*PetscErrorPrintf)("%s\n", text);
201: }
202: if (mess) ierr = (*PetscErrorPrintf)("%s\n", mess);
203: ierr = PetscOptionsLeftError();
204: ierr = (*PetscErrorPrintf)("See https://petsc.org/release/faq/ for trouble shooting.\n");
205: if (!PetscCIEnabledPortableErrorOutput) {
206: ierr = (*PetscErrorPrintf)("%s\n", version);
207: if (PetscErrorPrintfInitializeCalled) ierr = (*PetscErrorPrintf)("%s on a %s named %s by %s %s\n", pname, arch, hostname, username, date);
208: ierr = (*PetscErrorPrintf)("Configure options %s\n", petscconfigureoptions);
209: }
210: }
211: /* print line of stack trace */
212: if (fun) ierr = (*PetscErrorPrintf)("#%d %s() at %s:%d\n", cnt++, fun, PetscCIFilename(file), PetscCILinenumber(line));
213: else if (file) ierr = (*PetscErrorPrintf)("#%d %s:%d\n", cnt++, PetscCIFilename(file), PetscCILinenumber(line));
214: if (fun) {
215: PetscBool ismain = PETSC_FALSE;
217: ierr = PetscStrncmp(fun, "main", 4, &ismain);
218: if (ismain) {
219: 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);
220: ierr = PetscOptionsViewError();
221: PetscErrorPrintfHilight();
222: ierr = (*PetscErrorPrintf)("----------------End of Error Message -------send entire error message to petsc-maint@mcs.anl.gov----------\n");
223: PetscErrorPrintfNormal();
224: }
225: }
226: } else {
227: /* do not print error messages since process 0 will print them, sleep before aborting so will not accidentally kill process 0*/
228: ierr = PetscSleep(10.0);
229: exit(0);
230: }
231: (void)ierr;
232: return n;
233: }