xref: /petsc/src/sys/error/errtrace.c (revision 5b6bfdb9644f185dbf5e5a09b808ec241507e1e7)
1 #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for fileno() */
2 #include <petscsys.h>        /*I "petscsys.h" I*/
3 #include <petsc/private/petscimpl.h>
4 #include <petscconfiginfo.h>
5 #if defined(PETSC_HAVE_UNISTD_H)
6 #include <unistd.h>
7 #endif
8 
9 /*@C
10    PetscIgnoreErrorHandler - Ignores the error, allows program to continue as if error did not occure
11 
12    Not Collective
13 
14    Input Parameters:
15 +  comm - communicator over which error occurred
16 .  line - the line number of the error (indicated by __LINE__)
17 .  file - the file in which the error was detected (indicated by __FILE__)
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(comm,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  PetscIgnoreErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode n,PetscErrorType p,const char *mess,void *ctx)
43 {
44   PetscFunctionBegin;
45   PetscFunctionReturn(n);
46 }
47 
48 /* ---------------------------------------------------------------------------------------*/
49 
50 static char      arch[128],hostname[128],username[128],pname[PETSC_MAX_PATH_LEN],date[128];
51 static PetscBool PetscErrorPrintfInitializeCalled = PETSC_FALSE;
52 static char      version[256];
53 
54 /*
55    Initializes arch, hostname, username,date so that system calls do NOT need
56    to be made during the error handler.
57 */
58 PetscErrorCode  PetscErrorPrintfInitialize(void)
59 {
60   PetscErrorCode ierr;
61   PetscBool      use_stdout = PETSC_FALSE,use_none = PETSC_FALSE;
62 
63   PetscFunctionBegin;
64   ierr = PetscGetArchType(arch,sizeof(arch));CHKERRQ(ierr);
65   ierr = PetscGetHostName(hostname,sizeof(hostname));CHKERRQ(ierr);
66   ierr = PetscGetUserName(username,sizeof(username));CHKERRQ(ierr);
67   ierr = PetscGetProgramName(pname,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
68   ierr = PetscGetDate(date,sizeof(date));CHKERRQ(ierr);
69   ierr = PetscGetVersion(version,sizeof(version));CHKERRQ(ierr);
70 
71   ierr = PetscOptionsGetBool(NULL,NULL,"-error_output_stdout",&use_stdout,NULL);CHKERRQ(ierr);
72   if (use_stdout) PETSC_STDERR = PETSC_STDOUT;
73   ierr = PetscOptionsGetBool(NULL,NULL,"-error_output_none",&use_none,NULL);CHKERRQ(ierr);
74   if (use_none) PetscErrorPrintf = PetscErrorPrintfNone;
75   PetscErrorPrintfInitializeCalled = PETSC_TRUE;
76   PetscFunctionReturn(0);
77 }
78 
79 PetscErrorCode  PetscErrorPrintfNone(const char format[],...)
80 {
81   return 0;
82 }
83 
84 PetscErrorCode  PetscErrorPrintfDefault(const char format[],...)
85 {
86   va_list          Argp;
87   static PetscBool PetscErrorPrintfCalled = PETSC_FALSE;
88 
89   /*
90       This function does not call PetscFunctionBegin and PetscFunctionReturn() because
91     it may be called by PetscStackView().
92 
93       This function does not do error checking because it is called by the error handlers.
94   */
95 
96   if (!PetscErrorPrintfCalled) {
97     PetscErrorPrintfCalled = PETSC_TRUE;
98 
99     /*
100         On the SGI machines and Cray T3E, if errors are generated  "simultaneously" by
101       different processors, the messages are printed all jumbled up; to try to
102       prevent this we have each processor wait based on their rank
103     */
104 #if defined(PETSC_CAN_SLEEP_AFTER_ERROR)
105     {
106       PetscMPIInt rank;
107       if (PetscGlobalRank > 8) rank = 8;
108       else rank = PetscGlobalRank;
109       PetscSleep((PetscReal)rank);
110     }
111 #endif
112   }
113 
114   PetscFPrintf(PETSC_COMM_SELF,PETSC_STDERR,"[%d]PETSC ERROR: ",PetscGlobalRank);
115   va_start(Argp,format);
116   (*PetscVFPrintf)(PETSC_STDERR,format,Argp);
117   va_end(Argp);
118   return 0;
119 }
120 
121 static void PetscErrorPrintfHilight(void)
122 {
123 #if defined(PETSC_HAVE_UNISTD_H) && defined(PETSC_USE_ISATTY)
124   if (PetscErrorPrintf == PetscErrorPrintfDefault) {
125     if (isatty(fileno(PETSC_STDERR))) fprintf(PETSC_STDERR,"\033[1;31m");
126   }
127 #endif
128 }
129 
130 static void PetscErrorPrintfNormal(void)
131 {
132 #if defined(PETSC_HAVE_UNISTD_H) && defined(PETSC_USE_ISATTY)
133   if (PetscErrorPrintf == PetscErrorPrintfDefault) {
134     if (isatty(fileno(PETSC_STDERR))) fprintf(PETSC_STDERR,"\033[0;39m\033[0;49m");
135   }
136 #endif
137 }
138 
139 extern PetscErrorCode  PetscOptionsViewError(void);
140 
141 /*@C
142 
143    PetscTraceBackErrorHandler - Default error handler routine that generates
144    a traceback on error detection.
145 
146    Not Collective
147 
148    Input Parameters:
149 +  comm - communicator over which error occurred
150 .  line - the line number of the error (indicated by __LINE__)
151 .  file - the file in which the error was detected (indicated by __FILE__)
152 .  mess - an error text string, usually just printed to the screen
153 .  n - the generic error number
154 .  p - PETSC_ERROR_INITIAL if this is the first call the error handler, otherwise PETSC_ERROR_REPEAT
155 -  ctx - error handler context
156 
157    Level: developer
158 
159    Notes:
160    Most users need not directly employ this routine and the other error
161    handlers, but can instead use the simplified interface SETERRQ, which has
162    the calling sequence
163 $     SETERRQ(comm,number,n,mess)
164 
165    Notes for experienced users:
166    Use PetscPushErrorHandler() to set the desired error handler.  The
167    currently available PETSc error handlers include PetscTraceBackErrorHandler(),
168    PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscMPIAbortErrorHandler()
169 
170    Concepts: error handler^traceback
171    Concepts: traceback^generating
172 
173 .seealso:  PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(),
174           PetscAbortErrorHandler()
175  @*/
176 PetscErrorCode  PetscTraceBackErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode n,PetscErrorType p,const char *mess,void *ctx)
177 {
178   PetscLogDouble mem,rss;
179   PetscBool      flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE;
180   PetscMPIInt    rank = 0;
181 
182   PetscFunctionBegin;
183   if (comm != PETSC_COMM_SELF) MPI_Comm_rank(comm,&rank);
184 
185   if (!rank) {
186     PetscBool  ismain;
187     static int cnt = 1;
188 
189     if (p == PETSC_ERROR_INITIAL) {
190       PetscErrorPrintfHilight();
191       (*PetscErrorPrintf)("--------------------- Error Message --------------------------------------------------------------\n");
192       PetscErrorPrintfNormal();
193       if (n == PETSC_ERR_MEM) {
194         (*PetscErrorPrintf)("Out of memory. This could be due to allocating\n");
195         (*PetscErrorPrintf)("too large an object or bleeding by not properly\n");
196         (*PetscErrorPrintf)("destroying unneeded objects.\n");
197         PetscMallocGetCurrentUsage(&mem);
198         PetscMemoryGetCurrentUsage(&rss);
199         PetscOptionsGetBool(NULL,NULL,"-malloc_dump",&flg1,NULL);
200         PetscOptionsGetBool(NULL,NULL,"-malloc_log",&flg2,NULL);
201         PetscOptionsHasName(NULL,NULL,"-malloc_log_threshold",&flg3);
202         if (flg2 || flg3) PetscMallocDumpLog(stdout);
203         else {
204           (*PetscErrorPrintf)("Memory allocated %.0f Memory used by process %.0f\n",mem,rss);
205           if (flg1) PetscMallocDump(stdout);
206           else (*PetscErrorPrintf)("Try running with -malloc_dump or -malloc_log for info.\n");
207         }
208       } else {
209         const char *text;
210         PetscErrorMessage(n,&text,NULL);
211         if (text) (*PetscErrorPrintf)("%s\n",text);
212       }
213       if (mess) (*PetscErrorPrintf)("%s\n",mess);
214       (*PetscErrorPrintf)("See http://www.mcs.anl.gov/petsc/documentation/faq.html for trouble shooting.\n");
215       (*PetscErrorPrintf)("%s\n",version);
216       if (PetscErrorPrintfInitializeCalled) (*PetscErrorPrintf)("%s on a %s named %s by %s %s\n",pname,arch,hostname,username,date);
217       (*PetscErrorPrintf)("Configure options %s\n",petscconfigureoptions);
218     }
219     /* print line of stack trace */
220     (*PetscErrorPrintf)("#%d %s() line %d in %s\n",cnt++,fun,line,file);
221     PetscStrncmp(fun,"main",4,&ismain);
222     if (ismain) {
223       PetscOptionsViewError();
224       PetscErrorPrintfHilight();
225       (*PetscErrorPrintf)("----------------End of Error Message -------send entire error message to petsc-maint@mcs.anl.gov----------\n");
226       PetscErrorPrintfNormal();
227     }
228   } else {
229     /* do not print error messages since process 0 will print them, sleep before aborting so will not accidently kill process 0*/
230     PetscSleep(10.0);
231     abort();
232   }
233   PetscFunctionReturn(n);
234 }
235 
236