LAL 7.7.0.1-678514e
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
46int 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
57int (*lalRaiseHook) (int, const char *, ...) = LALRaise;
58int 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
75void (*lalAbortHook) (const char *, ...) = LALAbort;
76void 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
93int LALError(LALStatus * status, const char *statement)
94{
95 int n = 0;
96 if (lalDebugLevel & LALERROR) {
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
108int LALWarning(LALStatus * status, const char *warning)
109{
110 int n = 0;
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
122int 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
135int 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
148int
149LALInitStatus(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
182int 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
199int
200LALAttatchStatusPtr(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
224int
225LALDetatchStatusPtr(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
243int
244LALPrepareAbort(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
263int
264LALPrepareAssertFail(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;
276 (void) statement;
277 (void) LALError(status, statement);
278 (void) LALTrace(status, 1);
279 return 1;
280}
281
282
283
284int
285LALCheckStatusPtr(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";
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
361int 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
#define LAL_ERR_DFLT
Definition: LALError.h:139
int(* lal_errhandler_t)(LALStatus *, const char *func, const char *file, const int line, volatile const char *id)
Definition: LALError.h:131
#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