xref: /petsc/src/sys/error/errtrace.c (revision e6e75211d226c622f451867f53ce5d558649ff4f)
1 
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
7 
8 #undef __FUNCT__
9 #define __FUNCT__ "PetscIgnoreErrorHandler"
10 /*@C
11    PetscIgnoreErrorHandler - Ignores the error, allows program to continue as if error did not occure
12 
13    Not Collective
14 
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
24 
25    Level: developer
26 
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)
32 
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()
37 
38    Concepts: error handler^traceback
39    Concepts: traceback^generating
40 
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 {
46   PetscFunctionBegin;
47   PetscFunctionReturn(n);
48 }
49 
50 /* ---------------------------------------------------------------------------------------*/
51 
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];
55 
56 #undef __FUNCT__
57 #define __FUNCT__ "PetscErrorPrintfInitialize"
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 {
64   PetscErrorCode ierr;
65   PetscBool      use_stdout = PETSC_FALSE,use_none = PETSC_FALSE;
66 
67   PetscFunctionBegin;
68   ierr = PetscGetArchType(arch,sizeof(arch));CHKERRQ(ierr);
69   ierr = PetscGetHostName(hostname,sizeof(hostname));CHKERRQ(ierr);
70   ierr = PetscGetUserName(username,sizeof(username));CHKERRQ(ierr);
71   ierr = PetscGetProgramName(pname,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
72   ierr = PetscGetDate(date,sizeof(date));CHKERRQ(ierr);
73   ierr = PetscGetVersion(version,sizeof(version));CHKERRQ(ierr);
74 
75   ierr = PetscOptionsGetBool(NULL,"-error_output_stdout",&use_stdout,NULL);CHKERRQ(ierr);
76   if (use_stdout) PETSC_STDERR = PETSC_STDOUT;
77   ierr = PetscOptionsGetBool(NULL,"-error_output_none",&use_none,NULL);CHKERRQ(ierr);
78   if (use_none) PetscErrorPrintf = PetscErrorPrintfNone;
79   PetscErrorPrintfInitializeCalled = PETSC_TRUE;
80   PetscFunctionReturn(0);
81 }
82 
83 #undef __FUNCT__
84 #define __FUNCT__ "PetscErrorPrintfNone"
85 PetscErrorCode  PetscErrorPrintfNone(const char format[],...)
86 {
87   return 0;
88 }
89 
90 #undef __FUNCT__
91 #define __FUNCT__ "PetscErrorPrintfDefault"
92 PetscErrorCode  PetscErrorPrintfDefault(const char format[],...)
93 {
94   va_list          Argp;
95   static PetscBool PetscErrorPrintfCalled = PETSC_FALSE;
96 
97   /*
98       This function does not call PetscFunctionBegin and PetscFunctionReturn() because
99     it may be called by PetscStackView().
100 
101       This function does not do error checking because it is called by the error handlers.
102   */
103 
104   if (!PetscErrorPrintfCalled) {
105     PetscErrorPrintfCalled = PETSC_TRUE;
106 
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   }
121 
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 }
128 
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 }
137 
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 }
146 
147 extern PetscErrorCode  PetscOptionsViewError(void);
148 
149 #undef __FUNCT__
150 #define __FUNCT__ "PetscTraceBackErrorHandler"
151 /*@C
152 
153    PetscTraceBackErrorHandler - Default error handler routine that generates
154    a traceback on error detection.
155 
156    Not Collective
157 
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
167 
168    Level: developer
169 
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)
175 
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()
180 
181    Concepts: error handler^traceback
182    Concepts: traceback^generating
183 
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;
192 
193   PetscFunctionBegin;
194   if (comm != PETSC_COMM_SELF) MPI_Comm_rank(comm,&rank);
195 
196   if (!rank) {
197     PetscBool  ismain,isunknown;
198     static int cnt = 1;
199 
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 }
247 
248