xref: /petsc/src/sys/error/errtrace.c (revision 2e826d6f168293946e7dc17f87075462a7cd4791)
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 
148 #undef __FUNCT__
149 #define __FUNCT__ "PetscTraceBackErrorHandler"
150 /*@C
151 
152    PetscTraceBackErrorHandler - Default error handler routine that generates
153    a traceback on error detection.
154 
155    Not Collective
156 
157    Input Parameters:
158 +  comm - communicator over which error occurred
159 .  line - the line number of the error (indicated by __LINE__)
160 .  func - the function where error is detected (indicated by __FUNCT__)
161 .  file - the file in which the error was detected (indicated by __FILE__)
162 .  mess - an error text string, usually just printed to the screen
163 .  n - the generic error number
164 .  p - PETSC_ERROR_INITIAL if this is the first call the error handler, otherwise PETSC_ERROR_REPEAT
165 -  ctx - error handler context
166 
167    Level: developer
168 
169    Notes:
170    Most users need not directly employ this routine and the other error
171    handlers, but can instead use the simplified interface SETERRQ, which has
172    the calling sequence
173 $     SETERRQ(comm,number,n,mess)
174 
175    Notes for experienced users:
176    Use PetscPushErrorHandler() to set the desired error handler.  The
177    currently available PETSc error handlers include PetscTraceBackErrorHandler(),
178    PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscMPIAbortErrorHandler()
179 
180    Concepts: error handler^traceback
181    Concepts: traceback^generating
182 
183 .seealso:  PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(),
184           PetscAbortErrorHandler()
185  @*/
186 PetscErrorCode  PetscTraceBackErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode n,PetscErrorType p,const char *mess,void *ctx)
187 {
188   PetscLogDouble mem,rss;
189   PetscBool      flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE;
190   PetscMPIInt    rank = 0;
191 
192   PetscFunctionBegin;
193   if (comm != PETSC_COMM_SELF) MPI_Comm_rank(comm,&rank);
194 
195   if (!rank) {
196     PetscBool  ismain,isunknown;
197     static int cnt = 1;
198 
199     if (p == PETSC_ERROR_INITIAL) {
200       PetscErrorPrintfHilight();
201       (*PetscErrorPrintf)("--------------------- Error Message --------------------------------------------------------------\n");
202       PetscErrorPrintfNormal();
203       if (n == PETSC_ERR_MEM) {
204         (*PetscErrorPrintf)("Out of memory. This could be due to allocating\n");
205         (*PetscErrorPrintf)("too large an object or bleeding by not properly\n");
206         (*PetscErrorPrintf)("destroying unneeded objects.\n");
207         PetscMallocGetCurrentUsage(&mem);
208         PetscMemoryGetCurrentUsage(&rss);
209         PetscOptionsGetBool(NULL,"-malloc_dump",&flg1,NULL);
210         PetscOptionsGetBool(NULL,"-malloc_log",&flg2,NULL);
211         PetscOptionsHasName(NULL,"-malloc_log_threshold",&flg3);
212         if (flg2 || flg3) PetscMallocDumpLog(stdout);
213         else {
214           (*PetscErrorPrintf)("Memory allocated %.0f Memory used by process %.0f\n",mem,rss);
215           if (flg1) PetscMallocDump(stdout);
216           else (*PetscErrorPrintf)("Try running with -malloc_dump or -malloc_log for info.\n");
217         }
218       } else {
219         const char *text;
220         PetscErrorMessage(n,&text,NULL);
221         if (text) (*PetscErrorPrintf)("%s\n",text);
222       }
223       if (mess) (*PetscErrorPrintf)("%s\n",mess);
224       (*PetscErrorPrintf)("See http://www.mcs.anl.gov/petsc/documentation/faq.html for trouble shooting.\n");
225       (*PetscErrorPrintf)("%s\n",version);
226       if (PetscErrorPrintfInitializeCalled) (*PetscErrorPrintf)("%s on a %s named %s by %s %s\n",pname,arch,hostname,username,date);
227       (*PetscErrorPrintf)("Configure options %s\n",petscconfigureoptions);
228     }
229     /* print line of stack trace */
230     (*PetscErrorPrintf)("#%d %s() line %d in %s\n",cnt++,fun,line,file);
231     PetscStrncmp(fun,"main",4,&ismain);
232     PetscStrncmp(fun,"unknown",7,&isunknown);
233     if (ismain || isunknown) {
234       PetscErrorPrintfHilight();
235       (*PetscErrorPrintf)("----------------End of Error Message -------send entire error message to petsc-maint@mcs.anl.gov----------\n");
236       PetscErrorPrintfNormal();
237     }
238   } else {
239     /* do not print error messages since process 0 will print them, sleep before aborting so will not accidently kill process 0*/
240     PetscSleep(10.0);
241     abort();
242   }
243   PetscFunctionReturn(n);
244 }
245 
246