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