Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / avt / avt_trap.c
1 /****************************************************************************/
2 /* */
3 /* Chaine de verification */
4 /* */
5 /* Produit : AVT Version 1 */
6 /* Fichier : avt_util.c */
7 /* */
8 /* (c) copyright 1998-1999 AVERTEC */
9 /* Tous droits reserves */
10 /* Support : e-mail support@avertec.com */
11 /* */
12 /* Auteur(s) : AUGUSTINS Gilles */
13 /* */
14 /****************************************************************************/
15
16 #include "avt_headers.h"
17
18 chain_list *SEGV_MESSAGE = NULL;
19 chain_list *FPE_MESSAGE = NULL;
20 chain_list *INT_MESSAGE = NULL;
21
22 chain_list *SEGV_EXIT = NULL;
23 chain_list *FPE_EXIT = NULL;
24 chain_list *INT_EXIT = NULL;
25
26 chain_list *SEGV_CODE = NULL;
27 chain_list *FPE_CODE = NULL;
28 chain_list *INT_CODE = NULL;
29
30 typedef void (*t_pfunc)(int);
31
32 t_pfunc orig_SEGV, orig_FPE, orig_BUS;
33 int trap_SEGV_count=0, trap_FPE_count=0;
34
35 static void
36 avt_DumpStack(void)
37 {
38 #ifdef Linux
39 void *array[40];
40 size_t size;
41 char **strings;
42 size_t i;
43
44 size = backtrace (array, 40);
45 strings = backtrace_symbols (array, size);
46
47 printf ("Obtained %zd stack frames.\n", size);
48
49 for (i = 0; i < size; i++) {
50 printf ("%s\n", strings[i]);
51 }
52
53 free (strings);
54 #endif
55 #ifdef Solaris
56 char buf[32];
57
58 sprintf(buf, "/bin/pstack %ld", (long)getpid());
59 system(buf);
60 #endif
61 }
62
63 /* ------------------------------------------------------------------------ */
64
65 char *GetMessage (chain_list *mlist)
66 {
67 return (char*)mlist->DATA;
68 }
69
70 /* ------------------------------------------------------------------------ */
71
72 t_pfunc GetExit (chain_list *mlist)
73 {
74 return (t_pfunc)mlist->DATA;
75 }
76
77 /* ------------------------------------------------------------------------ */
78 int GetCode (chain_list *mlist)
79 {
80 return (int)(long)mlist->DATA;
81 }
82
83 /* ------------------------------------------------------------------------ */
84
85 void avt_Handler (int sig)
86 {
87 char *segv_mes;
88 char *fpe_mes;
89 char *int_mes;
90 int force_core = 0;
91
92 #ifdef AVT_MORE_INFOS
93 force_core = 1;
94 #endif
95
96 if (!SEGV_MESSAGE)
97 {
98 segv_mes = "Internal error, please contact Avertec support\n";
99 }
100 else
101 segv_mes = GetMessage (SEGV_MESSAGE);
102
103 if (!FPE_MESSAGE)
104 fpe_mes = "Internal error, please contact Avertec support\n";
105 else
106 fpe_mes = GetMessage (FPE_MESSAGE);
107
108 if (!INT_MESSAGE)
109 int_mes = "Program aborted\n";
110 else
111 int_mes = GetMessage (INT_MESSAGE);
112
113 // Reset colors
114 if (AVT_COL)
115 fprintf (stdout, "\x1B[0m");
116
117 switch (sig) {
118 case SIGBUS:
119 avt_errmsg(AVT_ERRMSG,"027",-1,segv_mes);
120 fflush (stderr);
121 if (V_BOOL_TAB[__AVT_TRACE_FATAL].VALUE == 1)
122 avt_DumpStack();
123 if (V_BOOL_TAB[__AVT_ENABLE_CORE].VALUE == 1 || force_core)
124 abort();
125 else if (SEGV_EXIT)
126 GetExit (SEGV_EXIT) (GetCode (SEGV_CODE));
127 else {
128 exit (1);
129 }
130 break;
131 case SIGSEGV:
132 avt_errmsg(AVT_ERRMSG,"027",-1,segv_mes);
133 fflush (stderr);
134 if (V_BOOL_TAB[__AVT_TRACE_FATAL].VALUE == 1)
135 avt_DumpStack();
136 if (V_BOOL_TAB[__AVT_ENABLE_CORE].VALUE == 1 || force_core)
137 abort();
138 else if (SEGV_EXIT)
139 GetExit (SEGV_EXIT) (GetCode (SEGV_CODE));
140 else {
141 exit (1);
142 }
143 break;
144 case SIGFPE:
145 avt_errmsg(AVT_ERRMSG,"027",-1,fpe_mes);
146 fflush (stderr);
147 if (V_BOOL_TAB[__AVT_TRACE_FATAL].VALUE == 1)
148 avt_DumpStack();
149 if (V_BOOL_TAB[__AVT_ENABLE_CORE].VALUE == 1 || force_core)
150 abort();
151 if (FPE_EXIT)
152 GetExit (FPE_EXIT) (GetCode (FPE_CODE));
153 else
154 exit (1);
155 break;
156 case SIGINT:
157 avt_errmsg(AVT_ERRMSG,"027",-1,int_mes);
158 fflush (stderr);
159 if (INT_EXIT)
160 GetExit (INT_EXIT) (GetCode (INT_CODE));
161 else
162 exit (1);
163 break;
164 }
165 }
166
167 /* ------------------------------------------------------------------------ */
168
169 void avt_TrapSegV ()
170 {
171 if (trap_SEGV_count==0)
172 {
173 orig_SEGV = signal (SIGSEGV, avt_Handler);
174
175 #ifndef MACOS
176 orig_BUS = signal (SIGBUS, avt_Handler);
177 #endif
178 }
179 trap_SEGV_count++;
180 }
181
182 void avt_UnTrapSegV ()
183 {
184 trap_SEGV_count--;
185 if (trap_SEGV_count==0)
186 {
187 signal (SIGSEGV, orig_SEGV);
188 #ifndef MACOS
189 signal (SIGBUS, orig_BUS);
190 #endif
191 }
192 }
193 void avt_TrapFPE ()
194 {
195 if (trap_FPE_count==0)
196 orig_FPE = signal (SIGFPE, avt_Handler);
197 trap_FPE_count++;
198 }
199
200 void avt_UnTrapFPE ()
201 {
202 trap_FPE_count--;
203 if (trap_FPE_count==0)
204 signal (SIGSEGV, orig_FPE);
205 }
206
207 void avt_TrapKill ()
208 {
209 signal (SIGINT, avt_Handler);
210 }
211
212 /* ------------------------------------------------------------------------ */
213
214 void avt_PushSegVExit (void (*fexit)(int), int code)
215 {
216 SEGV_EXIT = addchain (SEGV_EXIT, fexit);
217 SEGV_CODE = addchain (SEGV_CODE, (void*)(long)code);
218 }
219
220 void avt_PopSegVExit ()
221 {
222 if (SEGV_EXIT)
223 SEGV_EXIT = delchain (SEGV_EXIT, SEGV_EXIT);
224 if (SEGV_CODE)
225 SEGV_CODE = delchain (SEGV_CODE, SEGV_CODE);
226 }
227
228 /* ------------------------------------------------------------------------ */
229
230 void avt_PushFPEExit (void (*fexit)(int), int code)
231 {
232 FPE_EXIT = addchain (FPE_EXIT, fexit);
233 FPE_CODE = addchain (FPE_CODE, (void*)(long)code);
234 }
235
236 void avt_PopFPEExit ()
237 {
238 if (FPE_EXIT)
239 FPE_EXIT = delchain (FPE_EXIT, FPE_EXIT);
240 if (FPE_CODE)
241 FPE_CODE = delchain (FPE_CODE, FPE_CODE);
242 }
243
244 /* ------------------------------------------------------------------------ */
245
246 void avt_PushKillExit (void (*fexit)(int), int code)
247 {
248 INT_EXIT = addchain (INT_EXIT, fexit);
249 INT_CODE = addchain (INT_CODE, (void*)(long)code);
250 }
251
252 void avt_PopKillExit ()
253 {
254 if (INT_EXIT)
255 INT_EXIT = delchain (INT_EXIT, INT_EXIT);
256 if (INT_CODE)
257 INT_CODE = delchain (INT_CODE, INT_CODE);
258 }
259
260 /* ------------------------------------------------------------------------ */
261
262 void avt_PushSegVMessage (char *message)
263 {
264 SEGV_MESSAGE = addchain (SEGV_MESSAGE, message);
265 }
266
267 void avt_PopSegVMessage ()
268 {
269 if (SEGV_MESSAGE)
270 SEGV_MESSAGE = delchain (SEGV_MESSAGE, SEGV_MESSAGE);
271 }
272
273 /* ------------------------------------------------------------------------ */
274
275 void avt_PushFPEMessage (char *message)
276 {
277 FPE_MESSAGE = addchain (FPE_MESSAGE, message);
278 }
279
280 void avt_PopFPEMessage ()
281 {
282 if (FPE_MESSAGE)
283 FPE_MESSAGE = delchain (FPE_MESSAGE, FPE_MESSAGE);
284 }
285
286 /* ------------------------------------------------------------------------ */
287
288 void avt_PushKillMessage (char *message)
289 {
290 INT_MESSAGE = addchain (INT_MESSAGE, message);
291 }
292
293 void avt_PopKillMessage ()
294 {
295 if (INT_MESSAGE)
296 INT_MESSAGE = delchain (INT_MESSAGE, INT_MESSAGE);
297 }
298 /* ------------------------------------------------------------------------ */
299
300