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