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