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