Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmergrid/src/metis-5.1.0/GKlib/error.c
3206 views
1
/*!
2
\file error.c
3
\brief Various error-handling functions
4
5
This file contains functions dealing with error reporting and termination
6
7
\author George
8
\date 1/1/2007
9
\version\verbatim $Id: error.c 10711 2011-08-31 22:23:04Z karypis $ \endverbatim
10
*/
11
12
13
#define _GK_ERROR_C_ /* this is needed to properly declare the gk_jub* variables
14
as an extern function in GKlib.h */
15
16
#include <GKlib.h>
17
18
19
/* These are the jmp_buf for the graceful exit in case of severe errors.
20
Multiple buffers are defined to allow for recursive invokation. */
21
#define MAX_JBUFS 128
22
__thread int gk_cur_jbufs=-1;
23
__thread jmp_buf gk_jbufs[MAX_JBUFS];
24
__thread jmp_buf gk_jbuf;
25
26
typedef void (*gksighandler_t)(int);
27
28
/* These are the holders of the old singal handlers for the trapped signals */
29
static __thread gksighandler_t old_SIGMEM_handler; /* Custom signal */
30
static __thread gksighandler_t old_SIGERR_handler; /* Custom signal */
31
static __thread gksighandler_t old_SIGMEM_handlers[MAX_JBUFS]; /* Custom signal */
32
static __thread gksighandler_t old_SIGERR_handlers[MAX_JBUFS]; /* Custom signal */
33
34
/* The following is used to control if the gk_errexit() will actually abort or not.
35
There is always a single copy of this variable */
36
static int gk_exit_on_error = 1;
37
38
39
/*************************************************************************/
40
/*! This function sets the gk_exit_on_error variable
41
*/
42
/*************************************************************************/
43
void gk_set_exit_on_error(int value)
44
{
45
gk_exit_on_error = value;
46
}
47
48
49
50
/*************************************************************************/
51
/*! This function prints an error message and exits
52
*/
53
/*************************************************************************/
54
void errexit(char *f_str,...)
55
{
56
va_list argp;
57
58
va_start(argp, f_str);
59
vfprintf(stderr, f_str, argp);
60
va_end(argp);
61
62
if (strlen(f_str) == 0 || f_str[strlen(f_str)-1] != '\n')
63
fprintf(stderr,"\n");
64
fflush(stderr);
65
66
if (gk_exit_on_error)
67
exit(-2);
68
69
/* abort(); */
70
}
71
72
73
/*************************************************************************/
74
/*! This function prints an error message and raises a signum signal
75
*/
76
/*************************************************************************/
77
void gk_errexit(int signum, char *f_str,...)
78
{
79
va_list argp;
80
81
va_start(argp, f_str);
82
vfprintf(stderr, f_str, argp);
83
va_end(argp);
84
85
fprintf(stderr,"\n");
86
fflush(stderr);
87
88
if (gk_exit_on_error)
89
raise(signum);
90
}
91
92
93
/***************************************************************************/
94
/*! This function sets a number of signal handlers and sets the return point
95
of a longjmp
96
*/
97
/***************************************************************************/
98
int gk_sigtrap()
99
{
100
if (gk_cur_jbufs+1 >= MAX_JBUFS)
101
return 0;
102
103
gk_cur_jbufs++;
104
105
old_SIGMEM_handlers[gk_cur_jbufs] = signal(SIGMEM, gk_sigthrow);
106
old_SIGERR_handlers[gk_cur_jbufs] = signal(SIGERR, gk_sigthrow);
107
108
return 1;
109
}
110
111
112
/***************************************************************************/
113
/*! This function sets the handlers for the signals to their default handlers
114
*/
115
/***************************************************************************/
116
int gk_siguntrap()
117
{
118
if (gk_cur_jbufs == -1)
119
return 0;
120
121
signal(SIGMEM, old_SIGMEM_handlers[gk_cur_jbufs]);
122
signal(SIGERR, old_SIGERR_handlers[gk_cur_jbufs]);
123
124
gk_cur_jbufs--;
125
126
return 1;
127
}
128
129
130
/*************************************************************************/
131
/*! This function is the custome signal handler, which all it does is to
132
perform a longjump to the most recent saved environment
133
*/
134
/*************************************************************************/
135
void gk_sigthrow(int signum)
136
{
137
longjmp(gk_jbufs[gk_cur_jbufs], signum);
138
}
139
140
141
/***************************************************************************
142
* This function sets a number of signal handlers and sets the return point
143
* of a longjmp
144
****************************************************************************/
145
void gk_SetSignalHandlers()
146
{
147
old_SIGMEM_handler = signal(SIGMEM, gk_NonLocalExit_Handler);
148
old_SIGERR_handler = signal(SIGERR, gk_NonLocalExit_Handler);
149
}
150
151
152
/***************************************************************************
153
* This function sets the handlers for the signals to their default handlers
154
****************************************************************************/
155
void gk_UnsetSignalHandlers()
156
{
157
signal(SIGMEM, old_SIGMEM_handler);
158
signal(SIGERR, old_SIGERR_handler);
159
}
160
161
162
/*************************************************************************
163
* This function is the handler for SIGUSR1 that implements the cleaning up
164
* process prior to a non-local exit.
165
**************************************************************************/
166
void gk_NonLocalExit_Handler(int signum)
167
{
168
longjmp(gk_jbuf, signum);
169
}
170
171
172
/*************************************************************************/
173
/*! \brief Thread-safe implementation of strerror() */
174
/**************************************************************************/
175
char *gk_strerror(int errnum)
176
{
177
#if defined(WIN32) || defined(__MINGW32__)
178
return strerror(errnum);
179
#else
180
#ifndef SUNOS
181
static __thread char buf[1024];
182
183
strerror_r(errnum, buf, 1024);
184
185
buf[1023] = '\0';
186
return buf;
187
#else
188
return strerror(errnum);
189
#endif
190
#endif
191
}
192
193
194
195
/*************************************************************************
196
* This function prints a backtrace of calling functions
197
**************************************************************************/
198
void PrintBackTrace()
199
{
200
#ifdef HAVE_EXECINFO_H
201
void *array[10];
202
int i, size;
203
char **strings;
204
205
size = backtrace(array, 10);
206
strings = backtrace_symbols(array, size);
207
208
printf("Obtained %d stack frames.\n", size);
209
for (i=0; i<size; i++) {
210
printf("%s\n", strings[i]);
211
}
212
free(strings);
213
#endif
214
}
215
216