LAL  7.1.7.1-15d842a
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 #ifdef LAL_NDEBUG
149 
150 #define LALError( statusptr, statement ) 0
151 #define LALWarning( statusptr, warning ) 0
152 #define LALInfo( statusptr, info ) 0
153 #define LALTrace( statusptr, exitflg ) 0
154 
155 #endif
156 
157 
158 int
159 LALInitStatus(LALStatus * status, const char *function, const char *id,
160  const char *file, const int line)
161 {
162  int exitcode = 0;
163  if (status) {
164  INT4 level = status->level;
165  exitcode = status->statusPtr ? 1 : 0;
166  memset(status, 0, sizeof(LALStatus)); /* possible memory leak */
167  status->level = level > 0 ? level : 1;
168  status->Id = id;
169  status->function = function;
170  status->file = file;
171  status->line = line;
172  (void) LALTrace(status, 0);
173  if (exitcode) {
174  LALPrepareAbort(status, -2,
175  "INITSTATUS: non-null status pointer", file,
176  line);
177  } else if (xlalErrno) {
178  LALPrepareAbort(status, -16, "INITSTATUS: non-zero xlalErrno",
179  file, line);
180  exitcode = 1;
181  }
182  } else {
183  lalAbortHook("Abort: function %s, file %s, line %d, %s\n"
184  " Null status pointer passed to function\n",
185  function, file, line, id);
186  }
187  return exitcode;
188 }
189 
190 
191 
192 int LALPrepareReturn(LALStatus * status, const char *file, const int line)
193 {
194  status->file = file;
195  status->line = line;
196  if (status->statusCode) {
197  (void) LALError(status, "RETURN:");
198  }
199  (void) LALTrace(status, 1);
200  if (xlalErrno) {
201  LALPrepareAbort(status, -32, "RETURN: untrapped XLAL error",
202  file, line);
203  }
204  return 1;
205 }
206 
207 
208 
209 int
210 LALAttatchStatusPtr(LALStatus * status, const char *file, const int line)
211 {
212  int exitcode = 0;
213  if (status->statusPtr) {
214  LALPrepareAbort(status, -2,
215  "ATTATCHSTATUSPTR: non-null status pointer", file,
216  line);
217  exitcode = 1;
218  } else {
219  status->statusPtr = (LALStatus *) LALCalloc(1, sizeof(LALStatus));
220  if (!status->statusPtr) {
221  LALPrepareAbort(status, -4,
222  "ATTATCHSTATUSPTR: memory allocation error",
223  file, line);
224  exitcode = 1;
225  } else {
226  status->statusPtr->level = status->level + 1;
227  }
228  }
229  return exitcode;
230 }
231 
232 
233 
234 int
235 LALDetatchStatusPtr(LALStatus * status, const char *file, const int line)
236 {
237  int exitcode = 0;
238  if (status->statusPtr) {
239  FREESTATUSPTR(status);
240  status->statusCode = 0;
241  status->statusDescription = NULL;
242  } else {
243  LALPrepareAbort(status, -8,
244  "DETATCHSTATUSPTR: null status pointer", file,
245  line);
246  exitcode = 1;
247  }
248  return exitcode;
249 }
250 
251 
252 
253 int
254 LALPrepareAbort(LALStatus * status, const INT4 code, const char *mesg,
255  const char *file, const int line)
256 {
257  if (status->statusPtr) {
258  FREESTATUSPTR(status);
259  }
260  status->file = file;
261  status->line = line;
262  status->statusCode = code;
263  status->statusDescription = mesg;
264  if (code) {
265  (void) LALError(status, "ABORT:");
266  }
267  (void) LALTrace(status, 1);
268  return 1;
269 }
270 
271 
272 
273 int
274 LALPrepareAssertFail(LALStatus * status, const INT4 code, const char *mesg,
275  const char *statement, const char *file,
276  const int line)
277 {
278  if (status->statusPtr) {
279  FREESTATUSPTR(status);
280  }
281  status->file = file;
282  status->line = line;
283  status->statusCode = code;
284  status->statusDescription = mesg;
285  if (lalDebugLevel & LALERROR)
286  (void) statement;
287  (void) LALError(status, statement);
288  (void) LALTrace(status, 1);
289  return 1;
290 }
291 
292 
293 
294 int
295 LALCheckStatusPtr(LALStatus * status, const char *statement,
296  const char *file, const int line)
297 {
298  if (status->statusPtr->statusCode) {
299  status->file = file;
300  status->line = line;
301  status->statusCode = -1;
302  status->statusDescription = "Recursive error";
303  if (lalDebugLevel & LALERROR)
304  (void) statement;
305  (void) LALError(status, statement);
306  (void) LALTrace(status, 1);
307  return 1;
308  }
309  return 0;
310 }
311 
312 
313 
314 /*
315  * This function is somewhat dangerous: need to check to see
316  * if status->statusPtr is initially null before calling FREESTATUSPTR
317  */
318 
320 {
321  do {
322  LALStatus *next = status->statusPtr->statusPtr;
323  LALFree(status->statusPtr);
324  status->statusPtr = next;
325  }
326  while (status->statusPtr);
327  return;
328 }
329 
330 
331 
333 {
334  LALStatus *ptr;
335  for (ptr = status; ptr; ptr = ptr->statusPtr) {
336  LALPrintError("\nLevel %i: %s\n", ptr->level, ptr->Id);
337  if (ptr->statusCode) {
338  LALPrintError("\tStatus code %i: %s\n", ptr->statusCode,
339  ptr->statusDescription);
340  } else {
341  LALPrintError("\tStatus code 0: Nominal\n");
342  }
343  LALPrintError("\tfunction %s, file %s, line %i\n",
344  ptr->function, ptr->file, ptr->line);
345  }
346  return;
347 }
348 
349 
350 
351 
352 /*
353  * Error handlers for LALApps applications
354  */
355 
356 #define FAILMSG( stat, func, file, line, id ) \
357  do { \
358  if ( lalDebugLevel & LALERROR ) \
359  { \
360  LALPrintError( "Error[0]: file %s, line %d, %s\n" \
361  "\tLAL_CALL: Function call `%s' failed.\n", file, line, id, func ); \
362  } \
363  if ( vrbflg ) \
364  { \
365  fprintf(stderr,"Level 0: %s\n\tFunction call `%s' failed.\n" \
366  "\tfile %s, line %d\n", id, func, file, line ); \
367  REPORTSTATUS( stat ); \
368  } \
369  } while( 0 )
370 
371 int vrbflg = 0;
372 
374 
376  LALStatus *stat,
377  const char *func,
378  const char *file,
379  const int line,
380  volatile const char *id
381  )
382 {
383  if ( stat->statusCode )
384  {
385  FAILMSG( stat, func, file, line, id );
386  exit( 1 );
387  }
388  return stat->statusCode;
389 }
390 
392  LALStatus *stat,
393  const char *func,
394  const char *file,
395  const int line,
396  volatile const char *id
397  )
398 {
399  if ( stat->statusCode )
400  {
401  FAILMSG( stat, func, file, line, id );
402  abort();
403  }
404  return 0;
405 }
406 
408  LALStatus *stat,
409  const char *func,
410  const char *file,
411  const int line,
412  volatile const char *id
413  )
414 {
415  if ( stat->statusCode )
416  {
417  FAILMSG( stat, func, file, line, id );
418  }
419  return stat->statusCode;
420 }
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
int LALInfo(LALStatus *status, const char *info)
Definition: LALError.c:122
enable tracing messages
Definition: LALDebugLevel.h:47
const CHAR * file
The name of the source file containing the function code.
Definition: LALDatatypes.h:952
INT4 level
The nested-function level where any error was reported.
Definition: LALDatatypes.h:955
#define xlalErrno
Modifiable lvalue containing the XLAL error number.
Definition: XLALError.h:572
int LALError(LALStatus *status, const char *statement)
Definition: LALError.c:93
#define LALFree(p)
Definition: LALMalloc.h:96
int LALDetatchStatusPtr(LALStatus *status, const char *file, const int line)
Definition: LALError.c:235
int LALInitStatus(LALStatus *status, const char *function, const char *id, const char *file, const int line)
Definition: LALError.c:159
int LALPrepareAssertFail(LALStatus *status, const INT4 code, const char *mesg, const char *statement, const char *file, const int line)
Definition: LALError.c:274
int LAL_ERR_ABRT(LALStatus *stat, const char *func, const char *file, const int line, volatile const char *id)
Definition: LALError.c:391
int LALAttatchStatusPtr(LALStatus *status, const char *file, const int line)
Definition: LALError.c:210
#define fprintf
int LALTrace(LALStatus *status, int exitflg)
Definition: LALError.c:135
struct tagLALDictEntry * next
Definition: LALDict.h:44
int vrbflg
Definition: LALError.c:371
int LAL_ERR_EXIT(LALStatus *stat, const char *func, const char *file, const int line, volatile const char *id)
Definition: LALError.c:375
const CHAR * statusDescription
An explanatory string corresponding to the numerical status code.
Definition: LALDatatypes.h:949
int LALPrepareReturn(LALStatus *status, const char *file, const int line)
Definition: LALError.c:192
int LALPrepareAbort(LALStatus *status, const INT4 code, const char *mesg, const char *file, const int line)
Definition: LALError.c:254
INT4 statusCode
A numerical code identifying the type of error, or 0 for nominal status; Negative values are reserved...
Definition: LALDatatypes.h:948
lal_errhandler_t lal_errhandler
Definition: LALError.c:373
int LALWarning(LALStatus *status, const char *warning)
Definition: LALError.c:108
int LALRaise(int sig, const char *fmt,...)
Definition: LALError.c:58
int(* lal_errhandler_t)(LALStatus *, const char *func, const char *file, const int line, volatile const char *id)
Definition: LALError.h:142
#define lalDebugLevel
Definition: LALDebugLevel.h:56
int LAL_ERR_RTRN(LALStatus *stat, const char *func, const char *file, const int line, volatile const char *id)
Definition: LALError.c:407
int LALCheckStatusPtr(LALStatus *status, const char *statement, const char *file, const int line)
Definition: LALError.c:295
LAL status structure, see The LALStatus structure for more details.
Definition: LALDatatypes.h:947
const CHAR * function
The name of the function.
Definition: LALDatatypes.h:951
void REPORTSTATUS(LALStatus *status)
Definition: LALError.c:332
#define LALCalloc(m, n)
Definition: LALMalloc.h:94
volatile const CHAR * Id
A character string identifying the source file and version number of the function being reported on...
Definition: LALDatatypes.h:950
enable info messages
Definition: LALDebugLevel.h:46
void(* lalAbortHook)(const char *,...)
Definition: LALError.c:75
enable error messages
Definition: LALDebugLevel.h:44
int(* lalRaiseHook)(int, const char *,...)
Definition: LALError.c:57
#define FAILMSG(stat, func, file, line, id)
Definition: LALError.c:356
int32_t INT4
Four-byte signed integer.
#define LAL_ERR_DFLT
Definition: LALError.h:150
void FREESTATUSPTR(LALStatus *status)
Definition: LALError.c:319
enable warning messages
Definition: LALDebugLevel.h:45
int LALPrintError(const char *fmt,...)
Definition: LALError.c:46
void LALAbort(const char *fmt,...)
Definition: LALError.c:76