Actual source code: errtrace.c
petsc-3.6.1 2015-08-06
2: #include <petscsys.h> /*I "petscsys.h" I*/
3: #include <petscconfiginfo.h>
4: #if defined(PETSC_HAVE_UNISTD_H)
5: #include <unistd.h>
6: #endif
10: /*@C
11: PetscIgnoreErrorHandler - Ignores the error, allows program to continue as if error did not occure
13: Not Collective
15: Input Parameters:
16: + comm - communicator over which error occurred
17: . line - the line number of the error (indicated by __LINE__)
18: . func - the function where error is detected (indicated by __FUNCT__)
19: . file - the file in which the error was detected (indicated by __FILE__)
20: . mess - an error text string, usually just printed to the screen
21: . n - the generic error number
22: . p - specific error number
23: - ctx - error handler context
25: Level: developer
27: Notes:
28: Most users need not directly employ this routine and the other error
29: handlers, but can instead use the simplified interface SETERRQ, which has
30: the calling sequence
31: $ SETERRQ(comm,number,p,mess)
33: Notes for experienced users:
34: Use PetscPushErrorHandler() to set the desired error handler. The
35: currently available PETSc error handlers include PetscTraceBackErrorHandler(),
36: PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscMPIAbortErrorHandler()
38: Concepts: error handler^traceback
39: Concepts: traceback^generating
41: .seealso: PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(),
42: PetscAbortErrorHandler(), PetscTraceBackErrorHandler()
43: @*/
44: PetscErrorCode PetscIgnoreErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode n,PetscErrorType p,const char *mess,void *ctx)
45: {
47: PetscFunctionReturn(n);
48: }
50: /* ---------------------------------------------------------------------------------------*/
52: static char arch[128],hostname[128],username[128],pname[PETSC_MAX_PATH_LEN],date[128];
53: static PetscBool PetscErrorPrintfInitializeCalled = PETSC_FALSE;
54: static char version[256];
58: /*
59: Initializes arch, hostname, username,date so that system calls do NOT need
60: to be made during the error handler.
61: */
62: PetscErrorCode PetscErrorPrintfInitialize()
63: {
65: PetscBool use_stdout = PETSC_FALSE,use_none = PETSC_FALSE;
68: PetscGetArchType(arch,sizeof(arch));
69: PetscGetHostName(hostname,sizeof(hostname));
70: PetscGetUserName(username,sizeof(username));
71: PetscGetProgramName(pname,PETSC_MAX_PATH_LEN);
72: PetscGetDate(date,sizeof(date));
73: PetscGetVersion(version,sizeof(version));
75: PetscOptionsGetBool(NULL,"-error_output_stdout",&use_stdout,NULL);
76: if (use_stdout) PETSC_STDERR = PETSC_STDOUT;
77: PetscOptionsGetBool(NULL,"-error_output_none",&use_none,NULL);
78: if (use_none) PetscErrorPrintf = PetscErrorPrintfNone;
79: PetscErrorPrintfInitializeCalled = PETSC_TRUE;
80: return(0);
81: }
85: PetscErrorCode PetscErrorPrintfNone(const char format[],...)
86: {
87: return 0;
88: }
92: PetscErrorCode PetscErrorPrintfDefault(const char format[],...)
93: {
94: va_list Argp;
95: static PetscBool PetscErrorPrintfCalled = PETSC_FALSE;
97: /*
99: it may be called by PetscStackView().
101: This function does not do error checking because it is called by the error handlers.
102: */
104: if (!PetscErrorPrintfCalled) {
105: PetscErrorPrintfCalled = PETSC_TRUE;
107: /*
108: On the SGI machines and Cray T3E, if errors are generated "simultaneously" by
109: different processors, the messages are printed all jumbled up; to try to
110: prevent this we have each processor wait based on their rank
111: */
112: #if defined(PETSC_CAN_SLEEP_AFTER_ERROR)
113: {
114: PetscMPIInt rank;
115: if (PetscGlobalRank > 8) rank = 8;
116: else rank = PetscGlobalRank;
117: PetscSleep((PetscReal)rank);
118: }
119: #endif
120: }
122: PetscFPrintf(PETSC_COMM_SELF,PETSC_STDERR,"[%d]PETSC ERROR: ",PetscGlobalRank);
123: va_start(Argp,format);
124: (*PetscVFPrintf)(PETSC_STDERR,format,Argp);
125: va_end(Argp);
126: return 0;
127: }
129: static void PetscErrorPrintfHilight(void)
130: {
131: #if defined(PETSC_HAVE_UNISTD_H) && defined(PETSC_USE_ISATTY)
132: if (PetscErrorPrintf == PetscErrorPrintfDefault) {
133: if (isatty(fileno(PETSC_STDERR))) fprintf(PETSC_STDERR,"\033[1;31m");
134: }
135: #endif
136: }
138: static void PetscErrorPrintfNormal(void)
139: {
140: #if defined(PETSC_HAVE_UNISTD_H) && defined(PETSC_USE_ISATTY)
141: if (PetscErrorPrintf == PetscErrorPrintfDefault) {
142: if (isatty(fileno(PETSC_STDERR))) fprintf(PETSC_STDERR,"\033[0;39m\033[0;49m");
143: }
144: #endif
145: }
147: extern PetscErrorCode PetscOptionsViewError(void);
151: /*@C
153: PetscTraceBackErrorHandler - Default error handler routine that generates
154: a traceback on error detection.
156: Not Collective
158: Input Parameters:
159: + comm - communicator over which error occurred
160: . line - the line number of the error (indicated by __LINE__)
161: . func - the function where error is detected (indicated by __FUNCT__)
162: . file - the file in which the error was detected (indicated by __FILE__)
163: . mess - an error text string, usually just printed to the screen
164: . n - the generic error number
165: . p - PETSC_ERROR_INITIAL if this is the first call the error handler, otherwise PETSC_ERROR_REPEAT
166: - ctx - error handler context
168: Level: developer
170: Notes:
171: Most users need not directly employ this routine and the other error
172: handlers, but can instead use the simplified interface SETERRQ, which has
173: the calling sequence
174: $ SETERRQ(comm,number,n,mess)
176: Notes for experienced users:
177: Use PetscPushErrorHandler() to set the desired error handler. The
178: currently available PETSc error handlers include PetscTraceBackErrorHandler(),
179: PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscMPIAbortErrorHandler()
181: Concepts: error handler^traceback
182: Concepts: traceback^generating
184: .seealso: PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(),
185: PetscAbortErrorHandler()
186: @*/
187: PetscErrorCode PetscTraceBackErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode n,PetscErrorType p,const char *mess,void *ctx)
188: {
189: PetscLogDouble mem,rss;
190: PetscBool flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE;
191: PetscMPIInt rank = 0;
194: if (comm != PETSC_COMM_SELF) MPI_Comm_rank(comm,&rank);
196: if (!rank) {
197: PetscBool ismain,isunknown;
198: static int cnt = 1;
200: if (p == PETSC_ERROR_INITIAL) {
201: PetscErrorPrintfHilight();
202: (*PetscErrorPrintf)("--------------------- Error Message --------------------------------------------------------------\n");
203: PetscErrorPrintfNormal();
204: if (n == PETSC_ERR_MEM) {
205: (*PetscErrorPrintf)("Out of memory. This could be due to allocating\n");
206: (*PetscErrorPrintf)("too large an object or bleeding by not properly\n");
207: (*PetscErrorPrintf)("destroying unneeded objects.\n");
208: PetscMallocGetCurrentUsage(&mem);
209: PetscMemoryGetCurrentUsage(&rss);
210: PetscOptionsGetBool(NULL,"-malloc_dump",&flg1,NULL);
211: PetscOptionsGetBool(NULL,"-malloc_log",&flg2,NULL);
212: PetscOptionsHasName(NULL,"-malloc_log_threshold",&flg3);
213: if (flg2 || flg3) PetscMallocDumpLog(stdout);
214: else {
215: (*PetscErrorPrintf)("Memory allocated %.0f Memory used by process %.0f\n",mem,rss);
216: if (flg1) PetscMallocDump(stdout);
217: else (*PetscErrorPrintf)("Try running with -malloc_dump or -malloc_log for info.\n");
218: }
219: } else {
220: const char *text;
221: PetscErrorMessage(n,&text,NULL);
222: if (text) (*PetscErrorPrintf)("%s\n",text);
223: }
224: if (mess) (*PetscErrorPrintf)("%s\n",mess);
225: (*PetscErrorPrintf)("See http://www.mcs.anl.gov/petsc/documentation/faq.html for trouble shooting.\n");
226: (*PetscErrorPrintf)("%s\n",version);
227: if (PetscErrorPrintfInitializeCalled) (*PetscErrorPrintf)("%s on a %s named %s by %s %s\n",pname,arch,hostname,username,date);
228: (*PetscErrorPrintf)("Configure options %s\n",petscconfigureoptions);
229: }
230: /* print line of stack trace */
231: (*PetscErrorPrintf)("#%d %s() line %d in %s\n",cnt++,fun,line,file);
232: PetscStrncmp(fun,"main",4,&ismain);
233: PetscStrncmp(fun,"unknown",7,&isunknown);
234: if (ismain || isunknown) {
235: PetscOptionsViewError();
236: PetscErrorPrintfHilight();
237: (*PetscErrorPrintf)("----------------End of Error Message -------send entire error message to petsc-maint@mcs.anl.gov----------\n");
238: PetscErrorPrintfNormal();
239: }
240: } else {
241: /* do not print error messages since process 0 will print them, sleep before aborting so will not accidently kill process 0*/
242: PetscSleep(10.0);
243: abort();
244: }
245: PetscFunctionReturn(n);
246: }