xref: /petsc/src/sys/error/errtrace.c (revision 42f9eaa75db94a4ce6aba4736149b2133916df56)
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,use_none;
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 = PetscOptionsHasName(PETSC_NULL,"-error_output_stdout",&use_stdout);CHKERRQ(ierr);
74   if (use_stdout) {
75     PETSC_STDERR = PETSC_STDOUT;
76   }
77   ierr = PetscOptionsHasName(PETSC_NULL,"-error_output_none",&use_none);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,flg2;
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       PetscOptionsHasName(PETSC_NULL,"-malloc_dump",&flg1);
184       PetscOptionsHasName(PETSC_NULL,"-malloc_log",&flg2);
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