28 |
#endif |
#endif |
29 |
#include <utilities/ascMalloc.h> |
#include <utilities/ascMalloc.h> |
30 |
#include <utilities/ascSignal.h> |
#include <utilities/ascSignal.h> |
31 |
|
#include <utilities/ascPanic.h> |
32 |
#include "CUnit/CUnit.h" |
#include "CUnit/CUnit.h" |
33 |
#include "test_ascSignal.h" |
#include "test_ascSignal.h" |
34 |
#include "printutil.h" |
#include "printutil.h" |
69 |
LONGJMP(my_jmp_buf1, sigval); |
LONGJMP(my_jmp_buf1, sigval); |
70 |
} |
} |
71 |
|
|
72 |
|
void wrong_handler(int sigval){ |
73 |
|
ASC_PANIC("Don't use this one"); |
74 |
|
} |
75 |
|
|
76 |
static JMP_BUF my_jmp_buf2; |
static JMP_BUF my_jmp_buf2; |
77 |
|
|
78 |
static int f_handler2_called; |
static int f_handler2_called; |
120 |
old_seg_handler = SIGNAL(SIGSEGV, my_handler1); |
old_seg_handler = SIGNAL(SIGSEGV, my_handler1); |
121 |
} |
} |
122 |
|
|
123 |
|
#define CHECK_SIGNALS_MATCH_STACKS(FPEFN,INTFN,SEGFN) \ |
124 |
|
{ SigHandlerFn *oldfpe, *oldint, *oldseg; \ |
125 |
|
oldfpe = signal(SIGFPE,SIG_IGN);\ |
126 |
|
CU_TEST(oldfpe == FPEFN);\ |
127 |
|
CU_TEST(Asc_SignalStackTop(SIGFPE)==FPEFN);\ |
128 |
|
oldfpe = signal(SIGFPE,oldfpe);\ |
129 |
|
\ |
130 |
|
oldint = signal(SIGINT,SIG_IGN);\ |
131 |
|
CU_TEST(oldint == INTFN);\ |
132 |
|
CU_TEST(Asc_SignalStackTop(SIGINT)==INTFN);\ |
133 |
|
oldint = signal(SIGINT,oldint);\ |
134 |
|
\ |
135 |
|
oldseg = signal(SIGSEGV,SIG_IGN);\ |
136 |
|
CU_TEST(oldseg == SEGFN);\ |
137 |
|
CU_TEST(Asc_SignalStackTop(SIGSEGV)==SEGFN);\ |
138 |
|
oldseg = signal(SIGSEGV,oldseg);\ |
139 |
|
} |
140 |
|
|
141 |
static void restore_previous_signals(void){ |
static void restore_previous_signals(void){ |
142 |
CU_TEST(old_active==1); |
CU_TEST(old_active==1); |
143 |
if (NULL != old_fpe_handler) /* restore any pre-existing handlers */ |
if (NULL != old_fpe_handler) /* restore any pre-existing handlers */ |
176 |
|
|
177 |
CU_TEST(0 == Asc_SignalInit()); /* initialize the signal manager */ |
CU_TEST(0 == Asc_SignalInit()); /* initialize the signal manager */ |
178 |
|
|
179 |
old_handler = SIGNAL(SIGFPE, SIG_DFL); /* previously-installed handlers should still be active */ |
CHECK_SIGNALS_MATCH_STACKS(my_handler1, NULL, my_handler2); |
|
CU_TEST(my_handler1 == old_handler); |
|
|
old_handler = SIGNAL(SIGINT, SIG_DFL); |
|
|
CU_TEST(NULL == old_handler); |
|
|
old_handler = SIGNAL(SIGSEGV, SIG_DFL); |
|
|
CU_TEST(my_handler2 == old_handler); |
|
180 |
|
|
181 |
Asc_SignalRecover(TRUE); |
/* mix up the current handlers */ |
182 |
|
SIGNAL(SIGFPE, my_handler2); |
183 |
old_handler = SIGNAL(SIGFPE, SIG_DFL); /* handlers should have been reinstalled */ |
SIGNAL(SIGINT, SIG_IGN); |
184 |
CU_TEST(my_handler1 == old_handler); |
SIGNAL(SIGSEGV, my_handler1); |
|
old_handler = SIGNAL(SIGINT, SIG_DFL); |
|
|
CU_TEST(NULL == old_handler); |
|
|
old_handler = SIGNAL(SIGSEGV, SIG_DFL); |
|
|
CU_TEST(my_handler2 == old_handler); |
|
185 |
|
|
186 |
Asc_SignalRecover(TRUE); |
Asc_SignalRecover(TRUE); |
187 |
|
|
188 |
|
/* check that recovery worked; check that repeated calls don't damage it */ |
189 |
|
CHECK_SIGNALS_MATCH_STACKS(my_handler1, NULL, my_handler2); |
190 |
|
CHECK_SIGNALS_MATCH_STACKS(my_handler1, NULL, my_handler2); |
191 |
|
CHECK_SIGNALS_MATCH_STACKS(my_handler1, NULL, my_handler2); |
192 |
|
|
193 |
restore_previous_signals(); |
restore_previous_signals(); |
194 |
Asc_SignalDestroy(); |
Asc_SignalDestroy(); |
195 |
MEMUSED(0); |
MEMUSED(0); |
206 |
SIGNAL(SIGINT, SIG_IGN); |
SIGNAL(SIGINT, SIG_IGN); |
207 |
CU_TEST(0==Asc_SignalInit()); |
CU_TEST(0==Asc_SignalInit()); |
208 |
|
|
209 |
CU_TEST(0==Asc_SignalStackLength(SIGINT)); |
CU_TEST(Asc_SignalStackLength(SIGINT)==1); |
210 |
|
|
211 |
CU_TEST(0==Asc_SignalHandlerPush(SIGINT, my_handler1)); /* ok - supported signal, ok func */ |
CU_TEST(0==Asc_SignalHandlerPush(SIGINT, my_handler1)); /* ok - supported signal, ok func */ |
212 |
CU_TEST(Asc_SignalStackLength(SIGINT)==1); |
CU_TEST(Asc_SignalStackLength(SIGINT)==2); |
213 |
|
|
214 |
CONSOLE_DEBUG("Stack should have my_handler1..."); |
CONSOLE_DEBUG("Stack should have my_handler1..."); |
215 |
Asc_SignalPrintStack(SIGINT); |
Asc_SignalPrintStack(SIGINT); |
220 |
CU_TEST(0 != Asc_SignalHandlerPush(SIGILL, Asc_SignalTrap)); /* unsupported signal type */ |
CU_TEST(0 != Asc_SignalHandlerPush(SIGILL, Asc_SignalTrap)); /* unsupported signal type */ |
221 |
CU_TEST(0 != Asc_SignalHandlerPush(SIGABRT, my_handler2)); /* unsupported signal type */ |
CU_TEST(0 != Asc_SignalHandlerPush(SIGABRT, my_handler2)); /* unsupported signal type */ |
222 |
Asc_SignalRecover(TRUE); |
Asc_SignalRecover(TRUE); |
223 |
CU_TEST(Asc_SignalStackLength(SIGINT)==1); |
CU_TEST(Asc_SignalStackLength(SIGINT)==2); |
224 |
|
|
225 |
old_handler = SIGNAL(SIGINT, SIG_DFL); |
old_handler = SIGNAL(SIGINT, SIG_DFL); |
226 |
CU_TEST(old_handler == my_handler1); |
CU_TEST(old_handler == my_handler1); |
227 |
|
|
228 |
Asc_SignalRecover(TRUE); |
Asc_SignalRecover(TRUE); |
229 |
CU_TEST(0 == Asc_SignalHandlerPop(SIGINT, my_handler1)); |
CU_TEST(0 == Asc_SignalHandlerPop(SIGINT, my_handler1)); |
230 |
CU_TEST(Asc_SignalStackLength(SIGINT)==0); |
CU_TEST(Asc_SignalStackLength(SIGINT)==1); |
231 |
|
|
232 |
old_handler = SIGNAL(SIGINT, SIG_DFL); |
old_handler = SIGNAL(SIGINT, SIG_DFL); |
233 |
CU_TEST(old_handler == SIG_IGN); |
CU_TEST(old_handler == SIG_IGN); |
234 |
|
|
235 |
Asc_SignalRecover(TRUE); |
Asc_SignalRecover(TRUE); |
236 |
CU_TEST(Asc_SignalStackLength(SIGINT)==0); |
CU_TEST(Asc_SignalStackLength(SIGINT)==1); |
237 |
|
|
238 |
old_handler = SIGNAL(SIGINT, SIG_DFL); |
old_handler = SIGNAL(SIGINT, SIG_DFL); |
239 |
CU_TEST(SIG_IGN == old_handler); |
CU_TEST(SIG_IGN == old_handler); |
261 |
SigHandlerFn *old_handler; |
SigHandlerFn *old_handler; |
262 |
volatile int signal1_caught; |
volatile int signal1_caught; |
263 |
|
|
264 |
|
CONSOLE_DEBUG("my_handler1 = %p",my_handler1); |
265 |
|
CONSOLE_DEBUG("my_handler2 = %p",my_handler2); |
266 |
|
CONSOLE_DEBUG("Asc_SignalTrap = %p",Asc_SignalTrap); |
267 |
|
|
268 |
store_current_signals(); |
store_current_signals(); |
269 |
|
|
270 |
SIGNAL(SIGFPE, my_handler1); /* install some pre-existing handlers */ |
/* set the initial handlers */ |
271 |
|
SIGNAL(SIGFPE, my_handler1); |
272 |
SIGNAL(SIGINT, SIG_IGN); |
SIGNAL(SIGINT, SIG_IGN); |
273 |
SIGNAL(SIGSEGV, my_handler2); |
SIGNAL(SIGSEGV, my_handler2); |
274 |
|
|
275 |
|
/* initialise the stack */ |
276 |
CU_TEST(0 == Asc_SignalInit()); |
CU_TEST(0 == Asc_SignalInit()); |
277 |
|
|
278 |
/* test Asc_SignalPush(), Asc_SignalPop() */ |
CHECK_SIGNALS_MATCH_STACKS(my_handler1, SIG_IGN, my_handler2); |
|
CONSOLE_DEBUG("Initial stack for SIGFPE..."); |
|
|
Asc_SignalPrintStack(SIGFPE); |
|
279 |
|
|
280 |
CU_TEST(0 == Asc_SignalHandlerPush(SIGFPE, Asc_SignalTrap)); /* ok - supported signal, ok func */ |
/* check that initial handlers were pushed onto the stack */ |
281 |
old_handler = SIGNAL(SIGFPE, SIG_DFL); |
CU_TEST(Asc_SignalStackLength(SIGSEGV)==1); |
282 |
CU_TEST(old_handler == Asc_SignalTrap); |
CU_TEST(Asc_SignalStackLength(SIGFPE)==1); |
283 |
|
CU_TEST(Asc_SignalStackLength(SIGINT)==1); |
284 |
|
|
285 |
CU_TEST(0 == Asc_SignalHandlerPush(SIGINT, my_handler1)); /* ok - supported signal, ok func */ |
/* push an additional handler onto SIGFPE stack */ |
286 |
CONSOLE_DEBUG("Stack should have my_handler1..."); |
CU_TEST(0 == Asc_SignalHandlerPush(SIGFPE, Asc_SignalTrap)); |
|
Asc_SignalPrintStack(SIGINT); |
|
|
old_handler = SIGNAL(SIGINT, SIG_DFL); |
|
|
CU_TEST(old_handler == my_handler1); |
|
287 |
|
|
288 |
CU_TEST(0 == Asc_SignalHandlerPush(SIGSEGV, NULL)); /* NULL func - should have no effect */ |
CHECK_SIGNALS_MATCH_STACKS(Asc_SignalTrap, SIG_IGN, my_handler2); |
|
old_handler = SIGNAL(SIGSEGV, SIG_DFL); |
|
|
CU_TEST(old_handler == my_handler2); /* old handler should still be installed */ |
|
289 |
|
|
290 |
CU_TEST(0 != Asc_SignalHandlerPush(SIGILL, Asc_SignalTrap)); /* unsupported signal type */ |
CONSOLE_DEBUG("SIGFPE stack:"); |
291 |
CU_TEST(0 != Asc_SignalHandlerPush(SIGABRT, my_handler2)); /* unsupported signal type */ |
Asc_SignalPrintStack(SIGFPE); |
|
Asc_SignalRecover(TRUE); |
|
292 |
|
|
293 |
/* we expect: SIGSEGV = my_handler2, SIGINT = my_handler1, SIGFPE = Asc_SignalTrap */ |
/* push an additional handler onto SIGINT stack */ |
294 |
old_handler = SIGNAL(SIGFPE, SIG_DFL); /* handlers should have been reinstalled */ |
CU_TEST(0 == Asc_SignalHandlerPush(SIGINT, my_handler1)); |
|
CU_TEST(old_handler == Asc_SignalTrap); |
|
|
old_handler = SIGNAL(SIGINT, SIG_DFL); |
|
|
CU_TEST(old_handler == my_handler1); |
|
|
old_handler = SIGNAL(SIGSEGV, SIG_DFL); |
|
|
CU_TEST(old_handler == my_handler2); |
|
295 |
|
|
296 |
Asc_SignalRecover(TRUE); |
/* check the stacks */ |
297 |
CU_TEST(0 == Asc_SignalHandlerPop(SIGINT, my_handler1)); |
CHECK_SIGNALS_MATCH_STACKS(Asc_SignalTrap, my_handler1, my_handler2); |
298 |
|
CU_TEST(Asc_SignalStackLength(SIGSEGV)==1); /* my_handler2 */ |
299 |
|
CU_TEST(Asc_SignalStackLength(SIGINT)==2); /* SIG_IGN, my_handler1 */ |
300 |
|
CU_TEST(Asc_SignalStackLength(SIGFPE)==2); /* my_handler1, Asc_SignalTrap */ |
301 |
|
|
302 |
/* we expect: SIGSEGV = my_handler2, SIGINT = SIG_IGN, SIGFPE = Asc_SignalTrap */ |
CONSOLE_DEBUG("SIGFPE stack:"); |
303 |
old_handler = SIGNAL(SIGFPE, SIG_DFL); /* SIGINT should be reset to no handler */ |
Asc_SignalPrintStack(SIGFPE); |
|
CU_TEST(old_handler == SIG_DFL); |
|
|
old_handler = SIGNAL(SIGINT, SIG_DFL); |
|
|
CU_TEST(old_handler == SIG_IGN); |
|
|
old_handler = SIGNAL(SIGSEGV, SIG_DFL); |
|
|
CU_TEST(old_handler == my_handler2); |
|
304 |
|
|
305 |
Asc_SignalRecover(TRUE); |
/* attempt to push a NULL handler should have no effect */ |
306 |
CONSOLE_DEBUG("Stack for SIGFPE..."); |
CU_TEST(0 == Asc_SignalHandlerPush(SIGSEGV, NULL)); |
307 |
|
CHECK_SIGNALS_MATCH_STACKS(Asc_SignalTrap, my_handler1, my_handler2); |
308 |
|
CU_TEST(Asc_SignalStackLength(SIGSEGV)==1); |
309 |
|
CU_TEST(Asc_SignalStackLength(SIGINT)==2); |
310 |
|
CU_TEST(Asc_SignalStackLength(SIGFPE)==2); |
311 |
|
CHECK_SIGNALS_MATCH_STACKS(Asc_SignalTrap, my_handler1, my_handler2); |
312 |
|
|
313 |
|
CONSOLE_DEBUG("SIGFPE stack:"); |
314 |
Asc_SignalPrintStack(SIGFPE); |
Asc_SignalPrintStack(SIGFPE); |
315 |
|
CHECK_SIGNALS_MATCH_STACKS(Asc_SignalTrap, my_handler1, my_handler2); |
316 |
|
|
317 |
|
/* attempt to push handler for unsupported signal types should have no effect, should return error */ |
318 |
|
CU_TEST(0 != Asc_SignalHandlerPush(SIGILL, Asc_SignalTrap)); |
319 |
|
CU_TEST(0 != Asc_SignalHandlerPush(SIGABRT, my_handler2)); |
320 |
|
CHECK_SIGNALS_MATCH_STACKS(Asc_SignalTrap, my_handler1, my_handler2); |
321 |
|
CU_TEST(Asc_SignalStackLength(SIGSEGV)==1); |
322 |
|
CU_TEST(Asc_SignalStackLength(SIGINT)==2); |
323 |
|
CU_TEST(Asc_SignalStackLength(SIGFPE)==2); |
324 |
|
CHECK_SIGNALS_MATCH_STACKS(Asc_SignalTrap, my_handler1, my_handler2); |
325 |
|
|
326 |
CU_TEST(0 != Asc_SignalHandlerPop(SIGFPE, my_handler1)); /* wrong handler indicated */ |
/* pop off the SIGINT stack */ |
327 |
|
CU_TEST(0 == Asc_SignalHandlerPop(SIGINT, my_handler1)); |
328 |
|
|
329 |
CONSOLE_DEBUG("Stack for SIGFPE..."); |
CONSOLE_DEBUG("SIGFPE stack:"); |
330 |
Asc_SignalPrintStack(SIGFPE); |
Asc_SignalPrintStack(SIGFPE); |
331 |
|
|
332 |
/* we expect: SIGSEGV = my_handler2, SIGINT = SIG_IGN, SIGFPE = Asc_SignalTrap */ |
CHECK_SIGNALS_MATCH_STACKS(Asc_SignalTrap, SIG_IGN, my_handler2); |
333 |
old_handler = SIGNAL(SIGFPE, SIG_DFL); /* so SIGFPE should be not be reset */ |
CU_TEST(Asc_SignalStackLength(SIGSEGV)==1); |
334 |
CU_TEST(Asc_SignalTrap == old_handler); |
CU_TEST(Asc_SignalStackLength(SIGINT)==1); |
335 |
old_handler = SIGNAL(SIGINT, SIG_DFL); |
CU_TEST(Asc_SignalStackLength(SIGFPE)==2); |
|
CU_TEST(SIG_IGN == old_handler); |
|
|
old_handler = SIGNAL(SIGSEGV, SIG_DFL); |
|
|
CU_TEST(my_handler2 == old_handler); |
|
336 |
|
|
337 |
Asc_SignalRecover(TRUE); |
/* attempt to pop off an incorrect handler */ |
338 |
old_handler = SIGNAL(SIGFPE, SIG_DFL); /* but Asc_SignalRecover should reset it */ |
CONSOLE_DEBUG("Popping incorrect handler"); |
339 |
|
CU_TEST(0 != Asc_SignalHandlerPop(SIGFPE, wrong_handler)); |
340 |
|
|
341 |
/* we expect: SIGSEGV = my_handler2, SIGINT = SIG_IGN, SIGFPE = SIG_DFL */ |
CHECK_SIGNALS_MATCH_STACKS(Asc_SignalTrap, SIG_IGN, my_handler2); |
342 |
CU_TEST(my_handler1 == old_handler); |
CU_TEST(Asc_SignalStackLength(SIGSEGV)==1); |
343 |
old_handler = SIGNAL(SIGINT, SIG_DFL); |
CU_TEST(Asc_SignalStackLength(SIGINT)==1); |
344 |
CU_TEST(SIG_IGN == old_handler); |
CU_TEST(Asc_SignalStackLength(SIGFPE)==2); |
345 |
old_handler = SIGNAL(SIGSEGV, SIG_DFL); |
|
346 |
CU_TEST(my_handler2 == old_handler); |
/* mess with the SIGFPE handler, then attempt to recover from stacks */ |
347 |
|
old_handler = SIGNAL(SIGFPE, SIG_DFL); |
348 |
Asc_SignalRecover(TRUE); |
Asc_SignalRecover(TRUE); |
349 |
|
|
350 |
CU_TEST(0 != Asc_SignalHandlerPop(SIGILL, my_handler1)); /* unsupported signal type */ |
CHECK_SIGNALS_MATCH_STACKS(Asc_SignalTrap, SIG_IGN, my_handler2); |
351 |
CU_TEST(0 != Asc_SignalHandlerPop(SIGABRT, Asc_SignalTrap)); /* unsupported signal type */ |
CU_TEST(Asc_SignalStackLength(SIGSEGV)==1); |
352 |
|
CU_TEST(Asc_SignalStackLength(SIGINT)==1); |
353 |
|
CU_TEST(Asc_SignalStackLength(SIGFPE)==2); |
354 |
|
|
355 |
old_handler = SIGNAL(SIGFPE, SIG_DFL); /* should be no change in handlers */ |
/* try a couple of unsupported signal types */ |
356 |
CU_TEST(my_handler1 == old_handler); |
CU_TEST(0 != Asc_SignalHandlerPop(SIGILL, my_handler1)); |
357 |
old_handler = SIGNAL(SIGINT, SIG_DFL); |
CU_TEST(0 != Asc_SignalHandlerPop(SIGABRT, Asc_SignalTrap)); |
358 |
CU_TEST(SIG_IGN == old_handler); |
|
359 |
old_handler = SIGNAL(SIGSEGV, SIG_DFL); |
CHECK_SIGNALS_MATCH_STACKS(Asc_SignalTrap, SIG_IGN, my_handler2); |
360 |
CU_TEST(my_handler2 == old_handler); |
CU_TEST(Asc_SignalStackLength(SIGSEGV)==1); |
361 |
Asc_SignalRecover(TRUE); |
CU_TEST(Asc_SignalStackLength(SIGINT)==1); |
362 |
|
CU_TEST(Asc_SignalStackLength(SIGFPE)==2); |
363 |
|
|
364 |
restore_previous_signals(); |
restore_previous_signals(); |
365 |
Asc_SignalDestroy(); |
Asc_SignalDestroy(); |