xref: /petsc/src/sys/error/errtrace.c (revision e54fd5d204b042b248f4af47c38c0037ab771100)
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 static FILE *PetscErrorPrintfFILE = 0;
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_stderr;
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 = PetscOptionsHasName(PETSC_NULL,"-error_output_stderr",&use_stderr);CHKERRQ(ierr);
75   if (use_stderr) {
76     PetscErrorPrintfFILE = PETSC_STDERR;
77   } else {
78     PetscErrorPrintfFILE = PETSC_STDOUT;
79   }
80   PetscErrorPrintfInitializeCalled = PETSC_TRUE;
81   PetscFunctionReturn(0);
82 }
83 
84 #undef __FUNCT__
85 #define __FUNCT__ "PetscErrorPrintfNone"
86 PetscErrorCode PETSC_DLLEXPORT PetscErrorPrintfNone(const char format[],...)
87 {
88   return 0;
89 }
90 
91 #undef __FUNCT__
92 #define __FUNCT__ "PetscErrorPrintfDefault"
93 PetscErrorCode PETSC_DLLEXPORT PetscErrorPrintfDefault(const char format[],...)
94 {
95   va_list           Argp;
96   static PetscTruth PetscErrorPrintfCalled = PETSC_FALSE;
97 
98   /*
99       This function does not call PetscFunctionBegin and PetscFunctionReturn() because
100     it may be called by PetscStackView().
101 
102       This function does not do error checking because it is called by the error handlers.
103   */
104 
105   if (!PetscErrorPrintfCalled) {
106     PetscErrorPrintfCalled = PETSC_TRUE;
107     if (PetscErrorPrintfFILE == 0) PetscErrorPrintfFILE = PETSC_STDERR;
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,PetscErrorPrintfFILE,"[%d]PETSC ERROR: ",PetscGlobalRank);
124   va_start(Argp,format);
125   PetscVFPrintf(PetscErrorPrintfFILE,format,Argp);
126   va_end(Argp);
127 
128   return 0;
129 }
130 
131 
132 
133 #undef __FUNCT__
134 #define __FUNCT__ "PetscTraceBackErrorHandler"
135 /*@C
136 
137    PetscTraceBackErrorHandler - Default error handler routine that generates
138    a traceback on error detection.
139 
140    Not Collective
141 
142    Input Parameters:
143 +  line - the line number of the error (indicated by __LINE__)
144 .  func - the function where error is detected (indicated by __FUNCT__)
145 .  file - the file in which the error was detected (indicated by __FILE__)
146 .  dir - the directory of the file (indicated by __SDIR__)
147 .  mess - an error text string, usually just printed to the screen
148 .  n - the generic error number
149 .  p - specific error number
150 -  ctx - error handler context
151 
152    Level: developer
153 
154    Notes:
155    Most users need not directly employ this routine and the other error
156    handlers, but can instead use the simplified interface SETERRQ, which has
157    the calling sequence
158 $     SETERRQ(number,p,mess)
159 
160    Notes for experienced users:
161    Use PetscPushErrorHandler() to set the desired error handler.  The
162    currently available PETSc error handlers include PetscTraceBackErrorHandler(),
163    PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscMPIAbortErrorHandler()
164 
165    Concepts: error handler^traceback
166    Concepts: traceback^generating
167 
168 .seealso:  PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(),
169           PetscAbortErrorHandler()
170  @*/
171 PetscErrorCode PETSC_DLLEXPORT PetscTraceBackErrorHandler(int line,const char *fun,const char* file,const char *dir,PetscErrorCode n,int p,const char *mess,void *ctx)
172 {
173   PetscLogDouble    mem,rss;
174   PetscTruth        flg1,flg2;
175 
176   PetscFunctionBegin;
177 
178   if (p == 1) {
179     (*PetscErrorPrintf)("--------------------- Error Message ------------------------------------\n");
180     if (n == PETSC_ERR_MEM) {
181       (*PetscErrorPrintf)("Out of memory. This could be due to allocating\n");
182       (*PetscErrorPrintf)("too large an object or bleeding by not properly\n");
183       (*PetscErrorPrintf)("destroying unneeded objects.\n");
184       PetscMallocGetCurrentUsage(&mem);
185       PetscMemoryGetCurrentUsage(&rss);
186       PetscOptionsHasName(PETSC_NULL,"-malloc_dump",&flg1);
187       PetscOptionsHasName(PETSC_NULL,"-malloc_log",&flg2);
188       if (flg2) {
189         PetscMallocDumpLog(stdout);
190       } else {
191         (*PetscErrorPrintf)("Memory allocated %D Memory used by process %D\n",(PetscInt)mem,(PetscInt)rss);
192         if (flg1) {
193           PetscMallocDump(stdout);
194         } else {
195           (*PetscErrorPrintf)("Try running with -malloc_dump or -malloc_log for info.\n");
196         }
197       }
198     } else {
199         const char *text;
200         PetscErrorMessage(n,&text,PETSC_NULL);
201         if (text) (*PetscErrorPrintf)("%s!\n",text);
202     }
203     if (mess) {
204       (*PetscErrorPrintf)("%s!\n",mess);
205     }
206     (*PetscErrorPrintf)("------------------------------------------------------------------------\n");
207     (*PetscErrorPrintf)("%s\n",version);
208     (*PetscErrorPrintf)("See docs/changes/index.html for recent updates.\n");
209     (*PetscErrorPrintf)("See docs/faq.html for hints about trouble shooting.\n");
210     (*PetscErrorPrintf)("See docs/index.html for manual pages.\n");
211     (*PetscErrorPrintf)("------------------------------------------------------------------------\n");
212     if (PetscErrorPrintfInitializeCalled) {
213       (*PetscErrorPrintf)("%s on a %s named %s by %s %s\n",pname,arch,hostname,username,date);
214     }
215     (*PetscErrorPrintf)("Libraries linked from %s\n",PETSC_LIB_DIR);
216     (*PetscErrorPrintf)("Configure run at %s\n",petscconfigureruntime);
217     (*PetscErrorPrintf)("Configure options %s\n",petscconfigureoptions);
218     (*PetscErrorPrintf)("------------------------------------------------------------------------\n");
219   }
220 
221 
222   /* first line in stack trace? */
223   (*PetscErrorPrintf)("%s() line %d in %s%s\n",fun,line,dir,file);
224 
225 
226   PetscFunctionReturn(n);
227 }
228 
229