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