/[ascend]/trunk/base/generic/utilities/test/test_ascSignal.c
ViewVC logotype

Contents of /trunk/base/generic/utilities/test/test_ascSignal.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 953 - (show annotations) (download) (as text)
Thu Dec 7 14:47:15 2006 UTC (17 years, 10 months ago) by johnpye
File MIME type: text/x-csrc
File size: 17009 byte(s)
Added test for C99 FPE handling
Fixing mess-up of ChildByChar in arrayinst.h header.
Added 'safeeval' config option to IDA.
Changed 'SigHandler' to 'SigHandlerFn *' in line with other function pointer datatypes being used in ASCEND.
Moved processVarStatus *after* 'Failed integrator' exception (ongoing issue).
1 /*
2 * Unit test functions for ASCEND: utilities/ascSignal.c
3 *
4 * Copyright (C) 2005 Jerry St.Clair
5 *
6 * This file is part of the Ascend Environment.
7 *
8 * The Ascend Environment is free software; you can redistribute it
9 * and/or modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
13 * The Ascend Environment is distributed in hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with the program; if not, write to the Free Software Foundation,
20 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
21 * COPYING.
22 */
23
24 #include <stdio.h>
25 #include <utilities/ascConfig.h>
26 #ifdef __WIN32__
27 #include <io.h>
28 #endif
29 #include <utilities/ascMalloc.h>
30 #include <utilities/ascSignal.h>
31 #include "CUnit/CUnit.h"
32 #include "test_ascSignal.h"
33
34 static jmp_buf my_jmp_buf1;
35
36 static int f_handler1_called;
37 static int f_handler1_sigval;
38 /*
39 * Signal handler for unit tests.
40 * Resets the signal handlers and sets f_handler1_called to
41 * TRUE and f_handler1_sigval to the signal type code (-1 if
42 * an unsupported sigval). Then longjmp's using
43 * my_jmp_buf1 and the sigval.
44 */
45 void my_handler1(int sigval)
46 {
47 f_handler1_called = TRUE;
48 Asc_SignalRecover(FALSE);
49 switch (sigval)
50 {
51 case SIGFPE:
52 f_handler1_sigval = SIGFPE;
53 FPRESET;
54 break;
55 case SIGINT:
56 f_handler1_sigval = SIGINT;
57 break;
58 case SIGSEGV:
59 f_handler1_sigval = SIGSEGV;
60 break;
61 default:
62 f_handler1_sigval = -1;
63 break;
64 }
65 longjmp(my_jmp_buf1, sigval);
66 }
67
68 static jmp_buf my_jmp_buf2;
69
70 static int f_handler2_called;
71 static int f_handler2_sigval;
72 /*
73 * Signal handler for unit tests.
74 * Resets the signal handlers and sets f_handler1_called to
75 * TRUE and f_handler1_sigval to the signal type code (-1 if
76 * an unsupported sigval). Then longjmp's using
77 * my_jmp_buf1 and the sigval.
78 */
79 void my_handler2(int sigval)
80 {
81 f_handler2_called = TRUE;
82 Asc_SignalRecover(FALSE);
83 switch (sigval)
84 {
85 case SIGFPE:
86 f_handler2_sigval = SIGFPE;
87 FPRESET;
88 break;
89 case SIGINT:
90 f_handler2_sigval = SIGINT;
91 break;
92 case SIGSEGV:
93 f_handler2_sigval = SIGSEGV;
94 break;
95 default:
96 f_handler2_sigval = -1;
97 break;
98 }
99 longjmp(my_jmp_buf2, sigval);
100 }
101
102
103 static void test_ascSignal(void)
104 {
105 SigHandlerFn *old_fpe_handler = NULL;
106 SigHandlerFn *old_int_handler = NULL;
107 SigHandlerFn *old_seg_handler = NULL;
108 SigHandlerFn *old_handler;
109 volatile int signal1_caught;
110 volatile int signal2_caught;
111 volatile int signal3_caught;
112 unsigned long prior_meminuse;
113
114 prior_meminuse = ascmeminuse(); /* save meminuse() at start of test function */
115
116 #ifdef NO_SIGNAL_TRAPS
117 /* no point in testing if the functionality is disabled */
118 CU_FAIL("Signal handler manager not enabled.");
119 #else
120
121 old_fpe_handler = signal(SIGFPE, my_handler1); /* save any pre-existing handlers */
122 old_int_handler = signal(SIGINT, my_handler1);
123 old_seg_handler = signal(SIGSEGV, my_handler1);
124
125 signal(SIGFPE, my_handler1); /* install some pre-existing handlers */
126 signal(SIGINT, SIG_DFL);
127 signal(SIGSEGV, my_handler2);
128
129 /* Asc_SignalInit(), Asc_SignalDestroy() - not much to test */
130
131 CU_TEST(0 == Asc_SignalInit()); /* initialize the signal manager */
132
133 old_handler = signal(SIGFPE, SIG_DFL); /* previously-installed handlers should still be active */
134 CU_TEST(my_handler1 == old_handler);
135 old_handler = signal(SIGINT, SIG_DFL);
136 CU_TEST(NULL == old_handler);
137 old_handler = signal(SIGSEGV, SIG_DFL);
138 CU_TEST(my_handler2 == old_handler);
139
140 Asc_SignalRecover(TRUE);
141
142 old_handler = signal(SIGFPE, SIG_DFL); /* handlers should have been reinstalled */
143 CU_TEST(my_handler1 == old_handler);
144 old_handler = signal(SIGINT, SIG_DFL);
145 CU_TEST(NULL == old_handler);
146 old_handler = signal(SIGSEGV, SIG_DFL);
147 CU_TEST(my_handler2 == old_handler);
148
149 Asc_SignalRecover(TRUE);
150
151 /* test Asc_SignalPush(), Asc_SignalPop() */
152
153 CU_TEST(0 == Asc_SignalHandlerPush(SIGFPE, Asc_SignalTrap)); /* ok - supported signal, ok func */
154 old_handler = signal(SIGFPE, SIG_DFL);
155 CU_TEST(Asc_SignalTrap == old_handler);
156
157 CU_TEST(0 == Asc_SignalHandlerPush(SIGINT, my_handler1)); /* ok - supported signal, ok func */
158 old_handler = signal(SIGINT, SIG_DFL);
159 CU_TEST(my_handler1 == old_handler);
160
161 CU_TEST(0 == Asc_SignalHandlerPush(SIGSEGV, NULL)); /* NULL func - should have no effect */
162 old_handler = signal(SIGSEGV, SIG_DFL);
163 CU_TEST(my_handler2 == old_handler); /* old handler should still be installed */
164
165 CU_TEST(0 != Asc_SignalHandlerPush(SIGILL, Asc_SignalTrap)); /* unsupported signal type */
166 CU_TEST(0 != Asc_SignalHandlerPush(SIGABRT, my_handler2)); /* unsupported signal type */
167
168 Asc_SignalRecover(TRUE);
169
170 old_handler = signal(SIGFPE, SIG_DFL); /* handlers should have been reinstalled */
171 CU_TEST(Asc_SignalTrap == old_handler);
172 old_handler = signal(SIGINT, SIG_DFL);
173 CU_TEST(my_handler1 == old_handler);
174 old_handler = signal(SIGSEGV, SIG_DFL);
175 CU_TEST(my_handler2 == old_handler);
176 Asc_SignalRecover(TRUE);
177
178 CU_TEST(0 == Asc_SignalHandlerPop(SIGINT, my_handler1));
179 old_handler = signal(SIGFPE, SIG_DFL); /* SIGINT should be reset to no handler */
180 CU_TEST(Asc_SignalTrap == old_handler);
181 old_handler = signal(SIGINT, SIG_DFL);
182 CU_TEST(NULL == old_handler);
183 old_handler = signal(SIGSEGV, SIG_DFL);
184 CU_TEST(my_handler2 == old_handler);
185 Asc_SignalRecover(TRUE);
186
187 CU_TEST(0 != Asc_SignalHandlerPop(SIGFPE, my_handler1)); /* wrong handler indicated */
188 old_handler = signal(SIGFPE, SIG_DFL); /* so SIGFPE should be not be reset */
189 CU_TEST(Asc_SignalTrap == old_handler);
190 old_handler = signal(SIGINT, SIG_DFL);
191 CU_TEST(NULL == old_handler);
192 old_handler = signal(SIGSEGV, SIG_DFL);
193 CU_TEST(my_handler2 == old_handler);
194 Asc_SignalRecover(TRUE);
195
196 old_handler = signal(SIGFPE, SIG_DFL); /* but Asc_SignalRecover should reset it */
197 CU_TEST(my_handler1 == old_handler);
198 old_handler = signal(SIGINT, SIG_DFL);
199 CU_TEST(NULL == old_handler);
200 old_handler = signal(SIGSEGV, SIG_DFL);
201 CU_TEST(my_handler2 == old_handler);
202 Asc_SignalRecover(TRUE);
203
204 CU_TEST(0 != Asc_SignalHandlerPop(SIGILL, my_handler1)); /* unsupported signal type */
205 CU_TEST(0 != Asc_SignalHandlerPop(SIGABRT, Asc_SignalTrap)); /* unsupported signal type */
206
207 old_handler = signal(SIGFPE, SIG_DFL); /* should be no change in handlers */
208 CU_TEST(my_handler1 == old_handler);
209 old_handler = signal(SIGINT, SIG_DFL);
210 CU_TEST(NULL == old_handler);
211 old_handler = signal(SIGSEGV, SIG_DFL);
212 CU_TEST(my_handler2 == old_handler);
213 Asc_SignalRecover(TRUE);
214
215 /* test Asc_SignalTrap() */
216
217 CU_TEST(0 == Asc_SignalHandlerPush(SIGFPE, Asc_SignalTrap));
218 CU_TEST(0 == Asc_SignalHandlerPush(SIGINT, Asc_SignalTrap));
219 CU_TEST(0 == Asc_SignalHandlerPush(SIGSEGV, Asc_SignalTrap));
220
221 signal1_caught = FALSE;
222 if (0 == setjmp(g_fpe_env)) { /* raise & catch a SIGFPE */
223 raise(SIGFPE);
224 }
225 else {
226 signal1_caught = TRUE;
227 CU_PASS("SIGFPE caught.");
228 }
229 CU_TEST(TRUE == signal1_caught);
230
231 signal1_caught = FALSE;
232 if (0 == setjmp(g_int_env)) { /* raise & catch a SIGINT */
233 raise(SIGINT);
234 }
235 else {
236 signal1_caught = TRUE;
237 CU_PASS("SIGINT caught.");
238 }
239 CU_TEST(TRUE == signal1_caught);
240
241 signal1_caught = FALSE;
242 if (0 == setjmp(g_seg_env)) { /* raise & catch a SIGSEGV */
243 raise(SIGSEGV);
244 }
245 else {
246 signal1_caught = TRUE;
247 CU_PASS("SIGSEGV caught.");
248 }
249 CU_TEST(TRUE == signal1_caught);
250
251 Asc_SignalRecover(TRUE);
252
253 CU_TEST(0 == Asc_SignalHandlerPop(SIGFPE, Asc_SignalTrap));
254 CU_TEST(0 == Asc_SignalHandlerPop(SIGINT, Asc_SignalTrap));
255 CU_TEST(0 == Asc_SignalHandlerPop(SIGSEGV, Asc_SignalTrap));
256
257 old_handler = signal(SIGFPE, SIG_DFL); /* handlers should be restored at this point */
258 CU_TEST(my_handler1 == old_handler);
259 old_handler = signal(SIGINT, SIG_DFL);
260 CU_TEST(NULL == old_handler);
261 old_handler = signal(SIGSEGV, SIG_DFL);
262 CU_TEST(my_handler2 == old_handler);
263 Asc_SignalRecover(TRUE);
264
265 /* test typical use with nesting of handlers */
266
267 f_handler1_called = FALSE; /* initialize flags for detecting flow */
268 f_handler1_sigval = 0;
269 f_handler2_called = FALSE;
270 f_handler2_sigval = 0;
271 signal1_caught = FALSE;
272 signal2_caught = FALSE;
273 signal3_caught = FALSE;
274
275 CU_TEST(0 == Asc_SignalHandlerPush(SIGFPE, my_handler1)); /* test for SIGFPE */
276 if (0 == setjmp(my_jmp_buf1)) {
277 CU_TEST(0 == Asc_SignalHandlerPush(SIGFPE, my_handler2));
278 if (0 == setjmp(my_jmp_buf2)) {
279 CU_TEST(0 == Asc_SignalHandlerPush(SIGFPE, Asc_SignalTrap));
280 if (0 == setjmp(g_fpe_env)) {
281 raise(SIGFPE);
282 }
283 else {
284 CU_TEST(f_handler1_called == FALSE);
285 CU_TEST(f_handler1_sigval == 0);
286 CU_TEST(f_handler2_called == FALSE);
287 CU_TEST(f_handler2_sigval == 0);
288 signal3_caught = TRUE;
289 }
290 CU_TEST(FALSE == signal1_caught);
291 CU_TEST(FALSE == signal2_caught);
292 CU_TEST(TRUE == signal3_caught);
293 CU_TEST(0 == Asc_SignalHandlerPop(SIGFPE, Asc_SignalTrap));
294 f_handler1_called = FALSE;
295 f_handler1_sigval = 0;
296 f_handler2_called = FALSE;
297 f_handler2_sigval = 0;
298 signal1_caught = FALSE;
299 signal2_caught = FALSE;
300 signal3_caught = FALSE;
301 raise(SIGFPE);
302 }
303 else {
304 CU_TEST(f_handler1_called == FALSE);
305 CU_TEST(f_handler1_sigval == 0);
306 CU_TEST(f_handler2_called == TRUE);
307 CU_TEST(f_handler2_sigval == SIGFPE);
308 signal2_caught = TRUE;
309 }
310 CU_TEST(FALSE == signal1_caught);
311 CU_TEST(TRUE == signal2_caught);
312 CU_TEST(FALSE == signal3_caught);
313 CU_TEST(0 == Asc_SignalHandlerPop(SIGFPE, my_handler2));
314 f_handler1_called = FALSE;
315 f_handler1_sigval = 0;
316 f_handler2_called = FALSE;
317 f_handler2_sigval = 0;
318 signal1_caught = FALSE;
319 signal2_caught = FALSE;
320 signal3_caught = FALSE;
321 raise(SIGFPE);
322 }
323 else {
324 CU_TEST(f_handler1_called == TRUE);
325 CU_TEST(f_handler1_sigval == SIGFPE);
326 CU_TEST(f_handler2_called == FALSE);
327 CU_TEST(f_handler2_sigval == 0);
328 signal1_caught = TRUE;
329 }
330 CU_TEST(TRUE == signal1_caught);
331 CU_TEST(FALSE == signal2_caught);
332 CU_TEST(FALSE == signal3_caught);
333 CU_TEST(0 == Asc_SignalHandlerPop(SIGFPE, my_handler1));
334
335 f_handler1_called = FALSE; /* initialize flags for detecting flow */
336 f_handler1_sigval = 0;
337 f_handler2_called = FALSE;
338 f_handler2_sigval = 0;
339 signal1_caught = FALSE;
340 signal2_caught = FALSE;
341 signal3_caught = FALSE;
342
343 CU_TEST(0 == Asc_SignalHandlerPush(SIGINT, my_handler2)); /* test for SIGINT */
344 if (0 == setjmp(my_jmp_buf2)) {
345 CU_TEST(0 == Asc_SignalHandlerPush(SIGINT, Asc_SignalTrap));
346 if (0 == setjmp(g_int_env)) {
347 CU_TEST(0 == Asc_SignalHandlerPush(SIGINT, my_handler1));
348 if (0 == setjmp(my_jmp_buf1)) {
349 raise(SIGINT);
350 }
351 else {
352 CU_TEST(f_handler1_called == TRUE);
353 CU_TEST(f_handler1_sigval == SIGINT);
354 CU_TEST(f_handler2_called == FALSE);
355 CU_TEST(f_handler2_sigval == 0);
356 signal3_caught = TRUE;
357 }
358 CU_TEST(FALSE == signal1_caught);
359 CU_TEST(FALSE == signal2_caught);
360 CU_TEST(TRUE == signal3_caught);
361 CU_TEST(0 == Asc_SignalHandlerPop(SIGINT, my_handler1));
362 f_handler1_called = FALSE;
363 f_handler1_sigval = 0;
364 f_handler2_called = FALSE;
365 f_handler2_sigval = 0;
366 signal1_caught = FALSE;
367 signal2_caught = FALSE;
368 signal3_caught = FALSE;
369 raise(SIGINT);
370 }
371 else {
372 CU_TEST(f_handler1_called == FALSE);
373 CU_TEST(f_handler1_sigval == 0);
374 CU_TEST(f_handler2_called == FALSE);
375 CU_TEST(f_handler2_sigval == 0);
376 signal2_caught = TRUE;
377 }
378 CU_TEST(FALSE == signal1_caught);
379 CU_TEST(TRUE == signal2_caught);
380 CU_TEST(FALSE == signal3_caught);
381 CU_TEST(0 == Asc_SignalHandlerPop(SIGINT, Asc_SignalTrap));
382 f_handler1_called = FALSE;
383 f_handler1_sigval = 0;
384 f_handler2_called = FALSE;
385 f_handler2_sigval = 0;
386 signal1_caught = FALSE;
387 signal2_caught = FALSE;
388 signal3_caught = FALSE;
389 raise(SIGINT);
390 }
391 else {
392 CU_TEST(f_handler1_called == FALSE);
393 CU_TEST(f_handler1_sigval == 0);
394 CU_TEST(f_handler2_called == TRUE);
395 CU_TEST(f_handler2_sigval == SIGINT);
396 signal1_caught = TRUE;
397 }
398 CU_TEST(TRUE == signal1_caught);
399 CU_TEST(FALSE == signal2_caught);
400 CU_TEST(FALSE == signal3_caught);
401 CU_TEST(0 == Asc_SignalHandlerPop(SIGINT, my_handler2));
402
403 f_handler1_called = FALSE; /* initialize flags for detecting flow */
404 f_handler1_sigval = 0;
405 f_handler2_called = FALSE;
406 f_handler2_sigval = 0;
407 signal1_caught = FALSE;
408 signal2_caught = FALSE;
409 signal3_caught = FALSE;
410
411 CU_TEST(0 == Asc_SignalHandlerPush(SIGSEGV, Asc_SignalTrap)); /* test for SIGSEGV */
412 if (0 == setjmp(g_seg_env)) {
413 CU_TEST(0 == Asc_SignalHandlerPush(SIGSEGV, my_handler2));
414 if (0 == setjmp(my_jmp_buf2)) {
415 CU_TEST(0 == Asc_SignalHandlerPush(SIGSEGV, my_handler1));
416 if (0 == setjmp(my_jmp_buf1)) {
417 raise(SIGSEGV);
418 }
419 else {
420 CU_TEST(f_handler1_called == TRUE);
421 CU_TEST(f_handler1_sigval == SIGSEGV);
422 CU_TEST(f_handler2_called == FALSE);
423 CU_TEST(f_handler2_sigval == 0);
424 signal3_caught = TRUE;
425 }
426 CU_TEST(FALSE == signal1_caught);
427 CU_TEST(FALSE == signal2_caught);
428 CU_TEST(TRUE == signal3_caught);
429 CU_TEST(0 == Asc_SignalHandlerPop(SIGSEGV, my_handler1));
430 f_handler1_called = FALSE;
431 f_handler1_sigval = 0;
432 f_handler2_called = FALSE;
433 f_handler2_sigval = 0;
434 signal1_caught = FALSE;
435 signal2_caught = FALSE;
436 signal3_caught = FALSE;
437 raise(SIGSEGV);
438 }
439 else {
440 CU_TEST(f_handler1_called == FALSE);
441 CU_TEST(f_handler1_sigval == 0);
442 CU_TEST(f_handler2_called == TRUE);
443 CU_TEST(f_handler2_sigval == SIGSEGV);
444 signal2_caught = TRUE;
445 }
446 CU_TEST(FALSE == signal1_caught);
447 CU_TEST(TRUE == signal2_caught);
448 CU_TEST(FALSE == signal3_caught);
449 CU_TEST(0 == Asc_SignalHandlerPop(SIGSEGV, my_handler2));
450 f_handler1_called = FALSE;
451 f_handler1_sigval = 0;
452 f_handler2_called = FALSE;
453 f_handler2_sigval = 0;
454 signal1_caught = FALSE;
455 signal2_caught = FALSE;
456 signal3_caught = FALSE;
457 raise(SIGSEGV);
458 }
459 else {
460 CU_TEST(f_handler1_called == FALSE);
461 CU_TEST(f_handler1_sigval == 0);
462 CU_TEST(f_handler2_called == FALSE);
463 CU_TEST(f_handler2_sigval == 0);
464 signal1_caught = TRUE;
465 }
466 CU_TEST(TRUE == signal1_caught);
467 CU_TEST(FALSE == signal2_caught);
468 CU_TEST(FALSE == signal3_caught);
469 CU_TEST(0 == Asc_SignalHandlerPop(SIGSEGV, Asc_SignalTrap));
470
471 old_handler = signal(SIGFPE, SIG_DFL); /* handlers should be restored at this point */
472 CU_TEST(my_handler1 == old_handler);
473 old_handler = signal(SIGINT, SIG_DFL);
474 CU_TEST(NULL == old_handler);
475 old_handler = signal(SIGSEGV, SIG_DFL);
476 CU_TEST(my_handler2 == old_handler);
477 Asc_SignalRecover(TRUE);
478
479 Asc_SignalDestroy();
480
481 old_handler = signal(SIGFPE, SIG_DFL); /* original handlers should still be in place */
482 CU_TEST(my_handler1 == old_handler);
483 old_handler = signal(SIGINT, SIG_DFL);
484 CU_TEST(NULL == old_handler);
485 old_handler = signal(SIGSEGV, SIG_DFL);
486 CU_TEST(my_handler2 == old_handler);
487 Asc_SignalRecover(TRUE);
488
489 #endif /* NO_SIGNAL_TRAPS */
490
491 if (NULL != old_fpe_handler) /* restore any pre-existing handlers */
492 signal(SIGFPE, old_fpe_handler);
493 if (NULL != old_int_handler)
494 signal(SIGINT, old_int_handler);
495 if (NULL != old_seg_handler)
496 signal(SIGSEGV, old_seg_handler);
497
498 CU_TEST(prior_meminuse == ascmeminuse()); /* make sure we cleaned up after ourselves */
499 }
500
501 /*===========================================================================*/
502 /* Registration information */
503
504 static CU_TestInfo ascSignal_test_list[] = {
505 {"test_ascSignal", test_ascSignal},
506 CU_TEST_INFO_NULL
507 };
508
509 static CU_SuiteInfo suites[] = {
510 {"test_utilities_ascSignal", NULL, NULL, ascSignal_test_list},
511 CU_SUITE_INFO_NULL
512 };
513
514 /*-------------------------------------------------------------------*/
515 CU_ErrorCode test_register_utilities_ascSignal(void)
516 {
517 return CU_register_suites(suites);
518 }

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22