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