LAL  7.5.0.1-08ee4f4
LALError.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2007 Jolien Creighton, Bernd Machenschalk
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with with program; see the file COPYING. If not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 */
19 
20 // ---------- SEE LALError.dox for doxygen documentation ----------
21 
22 #include <config.h>
23 
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <stdarg.h>
28 #include <signal.h>
29 
30 #ifdef HAVE_EXECINFO_H
31 #include <execinfo.h>
32 #define BACKTRACE_LEVELMAX 0100
33 #endif
34 
35 #include <lal/LALMalloc.h>
36 #include <lal/LALError.h>
37 
40 
41 #undef LALError
42 #undef LALWarning
43 #undef LALInfo
44 #undef LALTrace
45 
46 int LALPrintError(const char *fmt, ...)
47 {
48  int n;
49  va_list ap;
50  va_start(ap, fmt);
51  n = vfprintf(stderr, fmt, ap);
52  va_end(ap);
53  return n;
54 }
55 
56 
57 int (*lalRaiseHook) (int, const char *, ...) = LALRaise;
58 int LALRaise(int sig, const char *fmt, ...)
59 {
60  va_list ap;
61  va_start(ap, fmt);
62  (void) vfprintf(stderr, fmt, ap);
63  va_end(ap);
64 #if defined(HAVE_BACKTRACE) && defined(BACKTRACE_LEVELMAX)
65  void *callstack[BACKTRACE_LEVELMAX];
66  size_t frames = backtrace(callstack, BACKTRACE_LEVELMAX);
67  fprintf(stderr, "backtrace:\n");
68  backtrace_symbols_fd(callstack, frames, fileno(stderr));
69 #endif
70  return raise(sig);
71 }
72 
73 
74 
75 void (*lalAbortHook) (const char *, ...) = LALAbort;
76 void LALAbort(const char *fmt, ...)
77 {
78  va_list ap;
79  va_start(ap, fmt);
80  (void) vfprintf(stderr, fmt, ap);
81  va_end(ap);
82 #if defined(HAVE_BACKTRACE) && defined(BACKTRACE_LEVELMAX)
83  void *callstack[BACKTRACE_LEVELMAX];
84  size_t frames = backtrace(callstack, BACKTRACE_LEVELMAX);
85  fprintf(stderr, "backtrace:\n");
86  backtrace_symbols_fd(callstack, frames, fileno(stderr));
87 #endif
88  abort();
89 }
90 
91 
92 
93 int LALError(LALStatus * status, const char *statement)
94 {
95  int n = 0;
96  if (lalDebugLevel & LALERROR) {
97  n = LALPrintError
98  ("Error[%d] %d: function %s, file %s, line %d, %s\n"
99  " %s %s\n", status->level, status->statusCode,
100  status->function, status->file, status->line, status->Id,
101  statement ? statement : "", status->statusDescription);
102  }
103  return n;
104 }
105 
106 
107 
108 int LALWarning(LALStatus * status, const char *warning)
109 {
110  int n = 0;
111  if (lalDebugLevel & LALWARNING) {
112  n = LALPrintError
113  ("Warning[%d]: function %s, file %s, line %d, %s\n"
114  " %s\n", status->level, status->function, status->file,
115  status->line, status->Id, warning);
116  }
117  return n;
118 }
119 
120 
121 
122 int LALInfo(LALStatus * status, const char *info)
123 {
124  int n = 0;
125  if (lalDebugLevel & LALINFO) {
126  n = LALPrintError("Info[%d]: function %s, file %s, line %d, %s\n"
127  " %s\n", status->level, status->function,
128  status->file, status->line, status->Id, info);
129  }
130  return n;
131 }
132 
133 
134 
135 int LALTrace(LALStatus * status, int exitflg)
136 {
137  int n = 0;
138  if (lalDebugLevel & LALTRACE) {
139  n = LALPrintError("%s[%d]: function %s, file %s, line %d, %s\n",
140  exitflg ? "Leave" : "Enter", status->level,
141  status->function, status->file, status->line,
142  status->Id);
143  }
144  return n;
145 }
146 
147 
148 int
149 LALInitStatus(LALStatus * status, const char *function, const char *id,
150  const char *file, const int line)
151 {
152  int exitcode = 0;
153  if (status) {
154  INT4 level = status->level;
155  exitcode = status->statusPtr ? 1 : 0;
156  memset(status, 0, sizeof(LALStatus)); /* possible memory leak */
157  status->level = level > 0 ? level : 1;
158  status->Id = id;
159  status->function = function;
160  status->file = file;
161  status->line = line;
162  (void) LALTrace(status, 0);
163  if (exitcode) {
165  "INITSTATUS: non-null status pointer", file,
166  line);
167  } else if (xlalErrno) {
168  LALPrepareAbort(status, -16, "INITSTATUS: non-zero xlalErrno",
169  file, line);
170  exitcode = 1;
171  }
172  } else {
173  lalAbortHook("Abort: function %s, file %s, line %d, %s\n"
174  " Null status pointer passed to function\n",
175  function, file, line, id);
176  }
177  return exitcode;
178 }
179 
180 
181 
182 int LALPrepareReturn(LALStatus * status, const char *file, const int line)
183 {
184  status->file = file;
185  status->line = line;
186  if (status->statusCode) {
187  (void) LALError(status, "RETURN:");
188  }
189  (void) LALTrace(status, 1);
190  if (xlalErrno) {
191  LALPrepareAbort(status, -32, "RETURN: untrapped XLAL error",
192  file, line);
193  }
194  return 1;
195 }
196 
197 
198 
199 int
200 LALAttatchStatusPtr(LALStatus * status, const char *file, const int line)
201 {
202  int exitcode = 0;
203  if (status->statusPtr) {
205  "ATTATCHSTATUSPTR: non-null status pointer", file,
206  line);
207  exitcode = 1;
208  } else {
209  status->statusPtr = (LALStatus *) LALCalloc(1, sizeof(LALStatus));
210  if (!status->statusPtr) {
212  "ATTATCHSTATUSPTR: memory allocation error",
213  file, line);
214  exitcode = 1;
215  } else {
216  status->statusPtr->level = status->level + 1;
217  }
218  }
219  return exitcode;
220 }
221 
222 
223 
224 int
225 LALDetatchStatusPtr(LALStatus * status, const char *file, const int line)
226 {
227  int exitcode = 0;
228  if (status->statusPtr) {
230  status->statusCode = 0;
231  status->statusDescription = NULL;
232  } else {
234  "DETATCHSTATUSPTR: null status pointer", file,
235  line);
236  exitcode = 1;
237  }
238  return exitcode;
239 }
240 
241 
242 
243 int
244 LALPrepareAbort(LALStatus * status, const INT4 code, const char *mesg,
245  const char *file, const int line)
246 {
247  if (status->statusPtr) {
249  }
250  status->file = file;
251  status->line = line;
252  status->statusCode = code;
253  status->statusDescription = mesg;
254  if (code) {
255  (void) LALError(status, "ABORT:");
256  }
257  (void) LALTrace(status, 1);
258  return 1;
259 }
260 
261 
262 
263 int
264 LALPrepareAssertFail(LALStatus * status, const INT4 code, const char *mesg,
265  const char *statement, const char *file,
266  const int line)
267 {
268  if (status->statusPtr) {
270  }
271  status->file = file;
272  status->line = line;
273  status->statusCode = code;
274  status->statusDescription = mesg;
275  if (lalDebugLevel & LALERROR)
276  (void) statement;
277  (void) LALError(status, statement);
278  (void) LALTrace(status, 1);
279  return 1;
280 }
281 
282 
283 
284 int
285 LALCheckStatusPtr(LALStatus * status, const char *statement,
286  const char *file, const int line)
287 {
288  if (status->statusPtr->statusCode) {
289  status->file = file;
290  status->line = line;
291  status->statusCode = -1;
292  status->statusDescription = "Recursive error";
293  if (lalDebugLevel & LALERROR)
294  (void) statement;
295  (void) LALError(status, statement);
296  (void) LALTrace(status, 1);
297  return 1;
298  }
299  return 0;
300 }
301 
302 
303 
304 /*
305  * This function is somewhat dangerous: need to check to see
306  * if status->statusPtr is initially null before calling FREESTATUSPTR
307  */
308 
310 {
311  do {
312  LALStatus *next = status->statusPtr->statusPtr;
313  LALFree(status->statusPtr);
314  status->statusPtr = next;
315  }
316  while (status->statusPtr);
317  return;
318 }
319 
320 
321 
323 {
324  LALStatus *ptr;
325  for (ptr = status; ptr; ptr = ptr->statusPtr) {
326  LALPrintError("\nLevel %i: %s\n", ptr->level, ptr->Id);
327  if (ptr->statusCode) {
328  LALPrintError("\tStatus code %i: %s\n", ptr->statusCode,
329  ptr->statusDescription);
330  } else {
331  LALPrintError("\tStatus code 0: Nominal\n");
332  }
333  LALPrintError("\tfunction %s, file %s, line %i\n",
334  ptr->function, ptr->file, ptr->line);
335  }
336  return;
337 }
338 
339 
340 
341 
342 /*
343  * Error handlers for LALApps applications
344  */
345 
346 #define FAILMSG( stat, func, file, line, id ) \
347  do { \
348  if ( lalDebugLevel & LALERROR ) \
349  { \
350  LALPrintError( "Error[0]: file %s, line %d, %s\n" \
351  "\tLAL_CALL: Function call `%s' failed.\n", file, line, id, func ); \
352  } \
353  if ( vrbflg ) \
354  { \
355  fprintf(stderr,"Level 0: %s\n\tFunction call `%s' failed.\n" \
356  "\tfile %s, line %d\n", id, func, file, line ); \
357  REPORTSTATUS( stat ); \
358  } \
359  } while( 0 )
360 
361 int vrbflg = 0;
362 
364 
366  LALStatus *stat,
367  const char *func,
368  const char *file,
369  const int line,
370  volatile const char *id
371  )
372 {
373  if ( stat->statusCode )
374  {
375  FAILMSG( stat, func, file, line, id );
376  exit( 1 );
377  }
378  return stat->statusCode;
379 }
380 
382  LALStatus *stat,
383  const char *func,
384  const char *file,
385  const int line,
386  volatile const char *id
387  )
388 {
389  if ( stat->statusCode )
390  {
391  FAILMSG( stat, func, file, line, id );
392  abort();
393  }
394  return 0;
395 }
396 
398  LALStatus *stat,
399  const char *func,
400  const char *file,
401  const int line,
402  volatile const char *id
403  )
404 {
405  if ( stat->statusCode )
406  {
407  FAILMSG( stat, func, file, line, id );
408  }
409  return stat->statusCode;
410 }
int LAL_ERR_ABRT(LALStatus *stat, const char *func, const char *file, const int line, volatile const char *id)
Definition: LALError.c:381
int(* lalRaiseHook)(int, const char *,...)
Definition: LALError.c:57
int LALPrepareAbort(LALStatus *status, const INT4 code, const char *mesg, const char *file, const int line)
Definition: LALError.c:244
void(* lalAbortHook)(const char *,...)
Definition: LALError.c:75
void FREESTATUSPTR(LALStatus *status)
Definition: LALError.c:309
void REPORTSTATUS(LALStatus *status)
Definition: LALError.c:322
int LALDetatchStatusPtr(LALStatus *status, const char *file, const int line)
Definition: LALError.c:225
int vrbflg
Definition: LALError.c:361
lal_errhandler_t lal_errhandler
Definition: LALError.c:363
int LALPrepareAssertFail(LALStatus *status, const INT4 code, const char *mesg, const char *statement, const char *file, const int line)
Definition: LALError.c:264
int LAL_ERR_RTRN(LALStatus *stat, const char *func, const char *file, const int line, volatile const char *id)
Definition: LALError.c:397
int LALCheckStatusPtr(LALStatus *status, const char *statement, const char *file, const int line)
Definition: LALError.c:285
int LAL_ERR_EXIT(LALStatus *stat, const char *func, const char *file, const int line, volatile const char *id)
Definition: LALError.c:365
#define FAILMSG(stat, func, file, line, id)
Definition: LALError.c:346
int LALPrepareReturn(LALStatus *status, const char *file, const int line)
Definition: LALError.c:182
int LALInitStatus(LALStatus *status, const char *function, const char *id, const char *file, const int line)
Definition: LALError.c:149
int LALAttatchStatusPtr(LALStatus *status, const char *file, const int line)
Definition: LALError.c:200
int(* lal_errhandler_t)(LALStatus *, const char *func, const char *file, const int line, volatile const char *id)
Definition: LALError.h:131
#define LAL_ERR_DFLT
Definition: LALError.h:139
#define LALCalloc(m, n)
Definition: LALMalloc.h:94
#define LALFree(p)
Definition: LALMalloc.h:96
#define fprintf
int32_t INT4
Four-byte signed integer.
#define lalDebugLevel
Definition: LALDebugLevel.h:58
@ LALTRACE
enable tracing messages
Definition: LALDebugLevel.h:49
@ LALINFO
enable info messages
Definition: LALDebugLevel.h:48
@ LALERROR
enable error messages
Definition: LALDebugLevel.h:46
@ LALWARNING
enable warning messages
Definition: LALDebugLevel.h:47
int LALRaise(int sig, const char *fmt,...)
Definition: LALError.c:58
void LALAbort(const char *fmt,...)
Definition: LALError.c:76
int LALTrace(LALStatus *status, int exitflg)
Definition: LALError.c:135
int LALWarning(LALStatus *status, const char *warning)
Definition: LALError.c:108
int LALError(LALStatus *status, const char *statement)
Definition: LALError.c:93
int LALInfo(LALStatus *status, const char *info)
Definition: LALError.c:122
int LALPrintError(const char *fmt,...)
Definition: LALError.c:46
#define xlalErrno
Modifiable lvalue containing the XLAL error number.
Definition: XLALError.h:571
LAL status structure, see The LALStatus structure for more details.
Definition: LALDatatypes.h:947
const CHAR * file
The name of the source file containing the function code.
Definition: LALDatatypes.h:952
INT4 statusCode
A numerical code identifying the type of error, or 0 for nominal status; Negative values are reserved...
Definition: LALDatatypes.h:948
INT4 level
The nested-function level where any error was reported.
Definition: LALDatatypes.h:955
const CHAR * function
The name of the function.
Definition: LALDatatypes.h:951
volatile const CHAR * Id
A character string identifying the source file and version number of the function being reported on.
Definition: LALDatatypes.h:950
const CHAR * statusDescription
An explanatory string corresponding to the numerical status code.
Definition: LALDatatypes.h:949
struct tagLALStatus * statusPtr
Pointer to the next node in the list; NULL if this function is not reporting a subroutine error.
Definition: LALDatatypes.h:954
INT4 line
The line number in the source file where the current statusCode was set.
Definition: LALDatatypes.h:953