xref: /petsc/src/sys/error/errtrace.c (revision d736bfeb4d37a01fcbdf00fe73fb60d6f0ba2142)
1 #define PETSC_DLL
2 
3 #include "petscsys.h"        /*I "petscsys.h" I*/
4 #include "petscconfiginfo.h"
5 
6 #undef __FUNCT__
7 #define __FUNCT__ "PetscIgnoreErrorHandler"
8 /*@C
9    PetscIgnoreErrorHandler - Ignores the error, allows program to continue as if error did not occure
10 
11    Not Collective
12 
13    Input Parameters:
14 +  comm - communicator over which error occurred
15 .  line - the line number of the error (indicated by __LINE__)
16 .  func - the function where error is detected (indicated by __FUNCT__)
17 .  file - the file in which the error was detected (indicated by __FILE__)
18 .  dir - the directory of the file (indicated by __SDIR__)
19 .  mess - an error text string, usually just printed to the screen
20 .  n - the generic error number
21 .  p - specific error number
22 -  ctx - error handler context
23 
24    Level: developer
25 
26    Notes:
27    Most users need not directly employ this routine and the other error
28    handlers, but can instead use the simplified interface SETERRQ, which has
29    the calling sequence
30 $     SETERRQ(comm,number,p,mess)
31 
32    Notes for experienced users:
33    Use PetscPushErrorHandler() to set the desired error handler.  The
34    currently available PETSc error handlers include PetscTraceBackErrorHandler(),
35    PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscMPIAbortErrorHandler()
36 
37    Concepts: error handler^traceback
38    Concepts: traceback^generating
39 
40 .seealso:  PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(),
41           PetscAbortErrorHandler(), PetscTraceBackErrorHandler()
42  @*/
43 PetscErrorCode PETSC_DLLEXPORT PetscIgnoreErrorHandler(MPI_Comm comm,int line,const char *fun,const char* file,const char *dir,PetscErrorCode n,PetscErrorType p,const char *mess,void *ctx)
44 {
45   PetscFunctionBegin;
46   PetscFunctionReturn(n);
47 }
48 
49 /* ---------------------------------------------------------------------------------------*/
50 
51 static char  arch[10],hostname[64],username[16],pname[PETSC_MAX_PATH_LEN],date[64];
52 static PetscTruth PetscErrorPrintfInitializeCalled = PETSC_FALSE;
53 static char version[256];
54 
55 #undef __FUNCT__
56 #define __FUNCT__ "PetscErrorPrintfInitialize"
57 /*
58    Initializes arch, hostname, username,date so that system calls do NOT need
59    to be made during the error handler.
60 */
61 PetscErrorCode PETSC_DLLEXPORT PetscErrorPrintfInitialize()
62 {
63   PetscErrorCode ierr;
64   PetscTruth     use_stdout = PETSC_FALSE,use_none = PETSC_FALSE;
65 
66   PetscFunctionBegin;
67   ierr = PetscGetArchType(arch,10);CHKERRQ(ierr);
68   ierr = PetscGetHostName(hostname,64);CHKERRQ(ierr);
69   ierr = PetscGetUserName(username,16);CHKERRQ(ierr);
70   ierr = PetscGetProgramName(pname,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
71   ierr = PetscGetDate(date,64);CHKERRQ(ierr);
72   ierr = PetscGetVersion(version,256);CHKERRQ(ierr);
73 
74   ierr = PetscOptionsGetTruth(PETSC_NULL,"-error_output_stdout",&use_stdout,PETSC_NULL);CHKERRQ(ierr);
75   if (use_stdout) {
76     PETSC_STDERR = PETSC_STDOUT;
77   }
78   ierr = PetscOptionsGetTruth(PETSC_NULL,"-error_output_none",&use_none,PETSC_NULL);CHKERRQ(ierr);
79   if (use_none) {
80     PetscErrorPrintf = PetscErrorPrintfNone;
81   }
82   PetscErrorPrintfInitializeCalled = PETSC_TRUE;
83   PetscFunctionReturn(0);
84 }
85 
86 #undef __FUNCT__
87 #define __FUNCT__ "PetscErrorPrintfNone"
88 PetscErrorCode PETSC_DLLEXPORT PetscErrorPrintfNone(const char format[],...)
89 {
90   return 0;
91 }
92 
93 #undef __FUNCT__
94 #define __FUNCT__ "PetscErrorPrintfDefault"
95 PetscErrorCode PETSC_DLLEXPORT PetscErrorPrintfDefault(const char format[],...)
96 {
97   va_list           Argp;
98   static PetscTruth PetscErrorPrintfCalled = PETSC_FALSE;
99 
100   /*
101       This function does not call PetscFunctionBegin and PetscFunctionReturn() because
102     it may be called by PetscStackView().
103 
104       This function does not do error checking because it is called by the error handlers.
105   */
106 
107   if (!PetscErrorPrintfCalled) {
108     PetscErrorPrintfCalled = PETSC_TRUE;
109 
110     /*
111         On the SGI machines and Cray T3E, if errors are generated  "simultaneously" by
112       different processors, the messages are printed all jumbled up; to try to
113       prevent this we have each processor wait based on their rank
114     */
115 #if defined(PETSC_CAN_SLEEP_AFTER_ERROR)
116     {
117       PetscMPIInt rank;
118       if (PetscGlobalRank > 8) rank = 8; else rank = PetscGlobalRank;
119       PetscSleep((PetscReal)rank);
120     }
121 #endif
122   }
123 
124   PetscFPrintf(PETSC_COMM_SELF,PETSC_STDERR,"[%d]PETSC ERROR: ",PetscGlobalRank);
125   va_start(Argp,format);
126   (*PetscVFPrintf)(PETSC_STDERR,format,Argp);
127   va_end(Argp);
128   return 0;
129 }
130 
131 #undef __FUNCT__
132 #define __FUNCT__ "PetscTraceBackErrorHandler"
133 /*@C
134 
135    PetscTraceBackErrorHandler - Default error handler routine that generates
136    a traceback on error detection.
137 
138    Not Collective
139 
140    Input Parameters:
141 +  comm - communicator over which error occurred
142 .  line - the line number of the error (indicated by __LINE__)
143 .  func - the function where error is detected (indicated by __FUNCT__)
144 .  file - the file in which the error was detected (indicated by __FILE__)
145 .  dir - the directory of the file (indicated by __SDIR__)
146 .  mess - an error text string, usually just printed to the screen
147 .  n - the generic error number
148 .  p - PETSC_ERROR_INITIAL if this is the first call the the error handler, otherwise PETSC_ERROR_REPEAT
149 -  ctx - error handler context
150 
151    Level: developer
152 
153    Notes:
154    Most users need not directly employ this routine and the other error
155    handlers, but can instead use the simplified interface SETERRQ, which has
156    the calling sequence
157 $     SETERRQ(comm,number,n,mess)
158 
159    Notes for experienced users:
160    Use PetscPushErrorHandler() to set the desired error handler.  The
161    currently available PETSc error handlers include PetscTraceBackErrorHandler(),
162    PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscMPIAbortErrorHandler()
163 
164    Concepts: error handler^traceback
165    Concepts: traceback^generating
166 
167 .seealso:  PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(),
168           PetscAbortErrorHandler()
169  @*/
170 PetscErrorCode PETSC_DLLEXPORT PetscTraceBackErrorHandler(MPI_Comm comm,int line,const char *fun,const char* file,const char *dir,PetscErrorCode n,PetscErrorType p,const char *mess,void *ctx)
171 {
172   PetscLogDouble    mem,rss;
173   PetscTruth        flg1 = PETSC_FALSE,flg2 = PETSC_FALSE;
174   PetscMPIInt       rank = 0;
175 
176   PetscFunctionBegin;
177   if (comm != PETSC_COMM_SELF) {
178     MPI_Comm_rank(comm,&rank);
179   }
180   if (!rank) {
181     if (p == PETSC_ERROR_INITIAL) {
182       (*PetscErrorPrintf)("--------------------- Error Message ------------------------------------\n");
183       if (n == PETSC_ERR_MEM) {
184 	(*PetscErrorPrintf)("Out of memory. This could be due to allocating\n");
185 	(*PetscErrorPrintf)("too large an object or bleeding by not properly\n");
186 	(*PetscErrorPrintf)("destroying unneeded objects.\n");
187 	PetscMallocGetCurrentUsage(&mem);
188 	PetscMemoryGetCurrentUsage(&rss);
189 	PetscOptionsGetTruth(PETSC_NULL,"-malloc_dump",&flg1,PETSC_NULL);
190 	PetscOptionsGetTruth(PETSC_NULL,"-malloc_log",&flg2,PETSC_NULL);
191 	if (flg2) {
192 	  PetscMallocDumpLog(stdout);
193 	} else {
194 	  (*PetscErrorPrintf)("Memory allocated %D Memory used by process %D\n",(PetscInt)mem,(PetscInt)rss);
195 	  if (flg1) {
196 	    PetscMallocDump(stdout);
197 	  } else {
198 	    (*PetscErrorPrintf)("Try running with -malloc_dump or -malloc_log for info.\n");
199 	  }
200 	}
201       } else {
202         const char *text;
203         PetscErrorMessage(n,&text,PETSC_NULL);
204         if (text) (*PetscErrorPrintf)("%s!\n",text);
205       }
206       if (mess) {
207 	(*PetscErrorPrintf)("%s!\n",mess);
208       }
209       (*PetscErrorPrintf)("------------------------------------------------------------------------\n");
210       (*PetscErrorPrintf)("%s\n",version);
211       (*PetscErrorPrintf)("See docs/changes/index.html for recent updates.\n");
212       (*PetscErrorPrintf)("See docs/faq.html for hints about trouble shooting.\n");
213       (*PetscErrorPrintf)("See docs/index.html for manual pages.\n");
214       (*PetscErrorPrintf)("------------------------------------------------------------------------\n");
215       if (PetscErrorPrintfInitializeCalled) {
216 	(*PetscErrorPrintf)("%s on a %s named %s by %s %s\n",pname,arch,hostname,username,date);
217       }
218       (*PetscErrorPrintf)("Libraries linked from %s\n",PETSC_LIB_DIR);
219       (*PetscErrorPrintf)("Configure run at %s\n",petscconfigureruntime);
220       (*PetscErrorPrintf)("Configure options %s\n",petscconfigureoptions);
221       (*PetscErrorPrintf)("------------------------------------------------------------------------\n");
222     }
223     /* print line of stack trace */
224     (*PetscErrorPrintf)("%s() line %d in %s%s\n",fun,line,dir,file);
225   } else {
226     /* do not print error messages since process 0 will print them, sleep before aborting so will not accidently kill process 0*/
227     PetscSleep(10.0);
228     abort();
229   }
230   PetscFunctionReturn(n);
231 }
232 
233 #if defined(PETSC_CLANGUAGE_CXX) && !defined(PETSC_USE_EXTERN_CXX)
234 #undef __FUNCT__
235 #define __FUNCT__ "PetscTraceBackErrorHandlerCxx"
236 /*@C
237 
238    PetscTraceBackErrorHandlerCxx - Error handler routine that generate a traceback in a C++ stream.
239 
240    Not Collective
241 
242    Input Parameters:
243 +  comm - communicator over which error occurred
244 .  line - the line number of the error (indicated by __LINE__)
245 .  func - the function where error is detected (indicated by __FUNCT__)
246 .  file - the file in which the error was detected (indicated by __FILE__)
247 .  dir - the directory of the file (indicated by __SDIR__)
248 .  n - the generic error number
249 .  p - PETSC_ERROR_INITIAL or PETSC_ERROR_REPEAT
250 .  mess - the error message
251 +  ctx - error handling context, in this case the C++ stream.
252 
253    Level: developer
254 
255    Notes:
256    Most users need not directly employ this routine and the other error
257    handlers, but can instead use the simplified interface SETERROR, which has
258    the calling sequence
259 $     SETERROR(number,n,mess)
260 
261    Concepts: error handler^traceback
262    Concepts: traceback^generating
263 
264 .seealso:  PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler()
265  @*/
266 PetscErrorCode PETSC_DLLEXPORT PetscTraceBackErrorHandlerCxx(MPI_Comm comm,int line,const char *fun,const char* file,const char *dir,PetscErrorCode n,PetscErrorType p, const char *mess,void *ctx)
267 {
268   std::ostringstream *msg = (std::ostringstream*) ctx;
269 
270   if (p == PETSC_ERROR_INITIAL) {
271     PetscLogDouble mem, rss;
272     PetscTruth     flg1 = PETSC_FALSE, flg2 = PETSC_FALSE;
273 
274     (*msg) << "--------------------- Error Message ------------------------------------" << std::endl;
275     if (n == PETSC_ERR_MEM) {
276       (*msg) << "Out of memory. This could be due to allocating" << std::endl;
277       (*msg) << "too large an object or bleeding by not properly" << std::endl;
278       (*msg) << "destroying unneeded objects." << std::endl;
279       PetscMallocGetCurrentUsage(&mem);
280       PetscMemoryGetCurrentUsage(&rss);
281       PetscOptionsGetTruth(PETSC_NULL,"-malloc_dump",&flg1,PETSC_NULL);
282       PetscOptionsGetTruth(PETSC_NULL,"-malloc_log",&flg2,PETSC_NULL);
283       if (flg2) {
284         //PetscMallocDumpLog(stdout);
285         (*msg) << "Option -malloc_log does not work in C++." << std::endl;
286       } else {
287         (*msg) << "Memory allocated " << mem << " Memory used by process " << rss << std::endl;
288         if (flg1) {
289           //PetscMallocDump(stdout);
290           (*msg) << "Option -malloc_dump does not work in C++." << std::endl;
291         } else {
292           (*msg) << "Try running with -malloc_dump or -malloc_log for info." << std::endl;
293         }
294       }
295     } else {
296       const char *text;
297 
298       PetscErrorMessage(n,&text,PETSC_NULL);
299       if (text) {(*msg) << text << "!" << std::endl;}
300     }
301     if (mess) {(*msg) << mess << "!" << std::endl;}
302     (*msg) << "------------------------------------------------------------------------" << std::endl;
303     (*msg) << version << std::endl;
304     (*msg) << "See docs/changes/index.html for recent updates." << std::endl;
305     (*msg) << "See docs/faq.html for hints about trouble shooting." << std::endl;
306     (*msg) << "See docs/index.html for manual pages." << std::endl;
307     (*msg) << "------------------------------------------------------------------------" << std::endl;
308     if (PetscErrorPrintfInitializeCalled) {
309       (*msg) << pname << " on a " << arch << " named " << hostname << " by " << username << " " << date << std::endl;
310     }
311     (*msg) << "Libraries linked from " << PETSC_LIB_DIR << std::endl;
312     (*msg) << "Configure run at " << petscconfigureruntime << std::endl;
313     (*msg) << "Configure options " << petscconfigureoptions << std::endl;
314     (*msg) << "------------------------------------------------------------------------" << std::endl;
315   }
316   (*msg) << fun<<"() line " << line << " in " << dir << file << std::endl;
317   return 0;
318 }
319 #endif
320