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

Diff of /trunk/base/generic/utilities/ascSignal.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1001 by johnpye, Sat Dec 30 06:15:56 2006 UTC revision 1002 by johnpye, Sat Dec 30 14:27:47 2006 UTC
# Line 61  Line 61 
61    
62  #include "ascMalloc.h"  #include "ascMalloc.h"
63  #include "ascSignal.h"  #include "ascSignal.h"
64    #include "ascPanic.h"
65    
66    #define SIGNAL_DEBUG
67    
68  /*------------------------------------------------------------------------------  /*------------------------------------------------------------------------------
69    GLOBALS AND FOWARD DECS    GLOBALS AND FOWARD DECS
# Line 96  static void initstack (SigHandlerFn **tr Line 99  static void initstack (SigHandlerFn **tr
99  static int pop_trap(SigHandlerFn **tlist, int *stackptr, SigHandlerFn *tp);  static int pop_trap(SigHandlerFn **tlist, int *stackptr, SigHandlerFn *tp);
100  static int push_trap(SigHandlerFn **tlist, int *stackptr, SigHandlerFn *tp);  static int push_trap(SigHandlerFn **tlist, int *stackptr, SigHandlerFn *tp);
101  static void reset_trap(int signum, SigHandlerFn **tlist, int tos);  static void reset_trap(int signum, SigHandlerFn **tlist, int tos);
102    static void print_stack(int signum, SigHandlerFn **tlist, int tos);
103    
104  #ifdef HAVE_C99FPE  #ifdef HAVE_C99FPE
105  static int fenv_pop(fenv_t *stack, int *top);  static int fenv_pop(fenv_t *stack, int *top);
# Line 119  static int fenv_push(fenv_t *stack,int * Line 123  static int fenv_push(fenv_t *stack,int *
123  int Asc_SignalInit(void)  int Asc_SignalInit(void)
124  {  {
125    /* initialize SIGFPE stack */    /* initialize SIGFPE stack */
126    
127    #ifdef SIGNAL_DEBUG
128      CONSOLE_DEBUG("Initialising signal stack");
129    #endif
130    
131    if (f_fpe_traps == NULL) {    if (f_fpe_traps == NULL) {
132      f_fpe_traps = ASC_NEW_ARRAY_CLEAR(SigHandlerFn*,MAX_TRAP_DEPTH);      f_fpe_traps = ASC_NEW_ARRAY_CLEAR(SigHandlerFn*,MAX_TRAP_DEPTH);
133      if (f_fpe_traps == NULL) {      if (f_fpe_traps == NULL) {
# Line 130  int Asc_SignalInit(void) Line 139  int Asc_SignalInit(void)
139  #ifdef HAVE_C99FPE  #ifdef HAVE_C99FPE
140    if(f_fenv_stack==NULL){ /* if we haven't already initialised this... */    if(f_fenv_stack==NULL){ /* if we haven't already initialised this... */
141      f_fenv_stack = ASC_NEW_ARRAY_CLEAR(fenv_t,MAX_TRAP_DEPTH);      f_fenv_stack = ASC_NEW_ARRAY_CLEAR(fenv_t,MAX_TRAP_DEPTH);
142      if(f_fenv_stack == NULL) return 1; /* failed to allocate */      if(f_fenv_stack == NULL){
143          return 1; /* failed to allocate */
144        }
145    }    }
146    f_fenv_stack_top = -1;    f_fenv_stack_top = -1;
147  #endif  #endif
# Line 138  int Asc_SignalInit(void) Line 149  int Asc_SignalInit(void)
149    /* initialize SIGINT stack */    /* initialize SIGINT stack */
150    if (f_int_traps == NULL) {    if (f_int_traps == NULL) {
151      f_int_traps = ASC_NEW_ARRAY_CLEAR(SigHandlerFn*,MAX_TRAP_DEPTH);      f_int_traps = ASC_NEW_ARRAY_CLEAR(SigHandlerFn*,MAX_TRAP_DEPTH);
152      if (f_int_traps == NULL) {      if(f_int_traps == NULL){
153        ascfree(f_fpe_traps);        /* failed malloc: free the earlier stuff */
154          ASC_FREE(f_fpe_traps);
155        f_fpe_traps = NULL;        f_fpe_traps = NULL;
156        return 1;        return 1;
157      }      }
# Line 150  int Asc_SignalInit(void) Line 162  int Asc_SignalInit(void)
162    if (f_seg_traps == NULL) {    if (f_seg_traps == NULL) {
163      f_seg_traps = ASC_NEW_ARRAY_CLEAR(SigHandlerFn*,MAX_TRAP_DEPTH);      f_seg_traps = ASC_NEW_ARRAY_CLEAR(SigHandlerFn*,MAX_TRAP_DEPTH);
164      if (f_seg_traps == NULL) {      if (f_seg_traps == NULL) {
165        ascfree(f_fpe_traps);        /* failed malloc: free the earlier stuff */
166          ASC_FREE(f_fpe_traps);
167        f_fpe_traps = NULL;        f_fpe_traps = NULL;
168        ascfree(f_int_traps);        ASC_FREE(f_int_traps);
169        f_int_traps = NULL;        f_int_traps = NULL;
170        return 1;        return 1;
171      }      }
# Line 180  void Asc_SignalDestroy(void) Line 193  void Asc_SignalDestroy(void)
193    ascfree(f_fpe_traps);    ascfree(f_fpe_traps);
194    ascfree(f_int_traps);    ascfree(f_int_traps);
195    ascfree(f_seg_traps);    ascfree(f_seg_traps);
196    if(f_fenv_stack)ASC_FREE(f_fenv_stack);  #ifdef HAVE_C99FPE
197      if(f_fenv_stack){
198        ASC_FREE(f_fenv_stack);
199        f_fenv_stack = NULL;
200      }
201    #endif
202    f_fpe_traps = f_int_traps = f_seg_traps =  NULL;    f_fpe_traps = f_int_traps = f_seg_traps =  NULL;
203    f_fpe_top_of_stack = f_int_top_of_stack = f_seg_top_of_stack =  -1;    f_fpe_top_of_stack = f_int_top_of_stack = f_seg_top_of_stack =  -1;
204    
205    #ifdef SIGNAL_DEBUG
206      CONSOLE_DEBUG("Destroyed signal stack");
207    #endif
208  }  }
209    
210  /**  /**
# Line 200  void Asc_SignalRecover(int force){ Line 222  void Asc_SignalRecover(int force){
222  #ifndef ASC_RESETNEEDED  #ifndef ASC_RESETNEEDED
223      if(force){      if(force){
224  #endif  #endif
225    # ifdef SIGNAL_DEBUG
226            CONSOLE_DEBUG("Resetting traps");
227    # endif
228          reset_trap(SIGFPE, f_fpe_traps, f_fpe_top_of_stack);          reset_trap(SIGFPE, f_fpe_traps, f_fpe_top_of_stack);
229          reset_trap(SIGINT, f_int_traps, f_int_top_of_stack);          reset_trap(SIGINT, f_int_traps, f_int_top_of_stack);
230          reset_trap(SIGSEGV, f_seg_traps, f_seg_top_of_stack);          reset_trap(SIGSEGV, f_seg_traps, f_seg_top_of_stack);
# Line 227  int Asc_SignalHandlerPush(int signum, Si Line 252  int Asc_SignalHandlerPush(int signum, Si
252    if (tp == NULL) {    if (tp == NULL) {
253      return 0;      return 0;
254    }    }
255    
256    #ifdef SIGNAL_DEBUG
257      CONSOLE_DEBUG("Pushing handler at %p for signal %d",tp,signum);
258    #endif
259    
260    switch (signum) {    switch (signum) {
261      case SIGFPE:      case SIGFPE:
262        //CONSOLE_DEBUG("PUSH SIGFPE");        //CONSOLE_DEBUG("PUSH SIGFPE");
263        err = push_trap(f_fpe_traps, &f_fpe_top_of_stack, tp);        err = push_trap(f_fpe_traps, &f_fpe_top_of_stack, tp);
264  #ifdef HAVE_C99FPE  #ifdef HAVE_C99FPE
265        if(tp == SIG_IGN){        if(tp == SIG_IGN){
266            err = fenv_push(f_fenv_stack, &f_fenv_stack_top,FE_DIVBYZERO);            err = fenv_push(f_fenv_stack, &f_fenv_stack_top,FE_ALL_EXCEPT);
267        }else{        }else{
268            err = fenv_push(f_fenv_stack, &f_fenv_stack_top,0);            err = fenv_push(f_fenv_stack, &f_fenv_stack_top,0);
269        }        }
270  #endif  #endif
271        break;        break;
272      case SIGINT:      case SIGINT:
273        /* CONSOLE_DEBUG("PUSH SIGINT"); */        CONSOLE_DEBUG("PUSH SIGINT");
274        err = push_trap(f_int_traps, &f_int_top_of_stack, tp);        err = push_trap(f_int_traps, &f_int_top_of_stack, tp);
275          print_stack(SIGINT,f_int_traps,f_int_top_of_stack);
276        break;        break;
277      case SIGSEGV:      case SIGSEGV:
278        /* CONSOLE_DEBUG("PUSH SIGSEGV"); */        /* CONSOLE_DEBUG("PUSH SIGSEGV"); */
# Line 251  int Asc_SignalHandlerPush(int signum, Si Line 282  int Asc_SignalHandlerPush(int signum, Si
282        return -1;        return -1;
283    }    }
284    if (err != 0) {    if (err != 0) {
285      ERROR_REPORTER_HERE(ASC_PROG_ERROR,"Asc_Signal (%d) stack limit exceeded.",signum);      ERROR_REPORTER_HERE(ASC_PROG_ERROR,"Error from push_trap or fenv_push (err = %d, signal=#%d).",err, signum);
286      return err;      return err;
287    }    }
288    (void)signal(signum, tp); /* install */    (void)SIGNAL(signum, tp); /* install */
289    return 0;    return 0;
290  }  }
291    
# Line 265  int Asc_SignalHandlerPopDefault(int sign Line 296  int Asc_SignalHandlerPopDefault(int sign
296  /* see ascSignal.h */  /* see ascSignal.h */
297  int Asc_SignalHandlerPop(int signum, SigHandlerFn *tp){  int Asc_SignalHandlerPop(int signum, SigHandlerFn *tp){
298    int err;    int err;
299    #ifdef SIGNAL_DEBUG
300      CONSOLE_DEBUG("Popping signal stack for signal %d (expecting top to be %p)",signum,tp);
301    #endif
302    
303    switch (signum) {    switch (signum) {
304    case SIGFPE:    case SIGFPE:
305      //CONSOLE_DEBUG("POP SIGFPE");      //CONSOLE_DEBUG("POP SIGFPE");
# Line 274  int Asc_SignalHandlerPop(int signum, Sig Line 309  int Asc_SignalHandlerPop(int signum, Sig
309  #endif  #endif
310      break;      break;
311    case SIGINT:    case SIGINT:
312      /* CONSOLE_DEBUG("POP SIGINT"); */      CONSOLE_DEBUG("POP SIGINT");
313      err = pop_trap(f_int_traps, &f_int_top_of_stack, tp);      err = pop_trap(f_int_traps, &f_int_top_of_stack, tp);
314        print_stack(SIGINT,f_int_traps,f_int_top_of_stack);
315      break;      break;
316    case SIGSEGV:    case SIGSEGV:
317      /* CONSOLE_DEBUG("POP SIGSEGV"); */      /* CONSOLE_DEBUG("POP SIGSEGV"); */
# Line 295  int Asc_SignalHandlerPop(int signum, Sig Line 331  int Asc_SignalHandlerPop(int signum, Sig
331  }  }
332    
333  void Asc_SignalTrap(int sigval) {  void Asc_SignalTrap(int sigval) {
334    #ifdef SIGNAL_DEBUG
335      CONSOLE_DEBUG("Caught signal #%d",sigval);
336    #endif
337    switch(sigval) {    switch(sigval) {
338    case SIGFPE:    case SIGFPE:
339      ERROR_REPORTER_HERE(ASC_PROG_WARNING,"Floating point error caught");      ERROR_REPORTER_HERE(ASC_PROG_WARNING,"Floating point error caught");
340      CONSOLE_DEBUG("SIGFPE caught");      CONSOLE_DEBUG("SIGFPE caught");
341    #ifdef HAVE_C99FPE
342      FPRESET;      FPRESET;
343    #endif
344      LONGJMP(g_fpe_env,sigval);      LONGJMP(g_fpe_env,sigval);
345      break;      break;
346    case SIGINT:    case SIGINT:
# Line 318  void Asc_SignalTrap(int sigval) { Line 359  void Asc_SignalTrap(int sigval) {
359    return;    return;
360  }  }
361    
362    void Asc_SignalPrintStack(int signum){
363        switch(signum){
364            case SIGINT:
365                print_stack(SIGINT,f_int_traps,f_int_top_of_stack);
366                return;
367            case SIGFPE:
368                print_stack(SIGFPE,f_fpe_traps,f_fpe_top_of_stack);
369                return;
370            case SIGSEGV:
371                print_stack(SIGSEGV,f_seg_traps,f_seg_top_of_stack);
372                return;
373            default:
374                ERROR_REPORTER_HERE(ASC_PROG_ERR,"Invalid signal %d",signum);
375        }
376    }
377    
378    int Asc_SignalStackLength(int signum){
379        switch(signum){
380            case SIGINT:
381                return f_int_top_of_stack;
382            case SIGFPE:
383                return f_fpe_top_of_stack;
384            case SIGSEGV:
385                return f_seg_top_of_stack;
386            default:
387                ERROR_REPORTER_HERE(ASC_PROG_ERR,"Invalid signal %d",signum);
388        }
389    }
390    
391    
392  /*------------------------------------------------------------------------------  /*------------------------------------------------------------------------------
393    UTILITY FUNCTIONS    UTILITY FUNCTIONS
394  */  */
# Line 348  void Asc_SignalTrap(int sigval) { Line 419  void Asc_SignalTrap(int sigval) {
419    
420  static void initstack(SigHandlerFn **traps, int *stackptr, int sig){  static void initstack(SigHandlerFn **traps, int *stackptr, int sig){
421    SigHandlerFn *old;    SigHandlerFn *old;
422    old = signal(sig,SIG_DFL);    old = SIGNAL(sig,SIG_DFL);
423    if (old != SIG_ERR && old != SIG_DFL) {    if (old != SIG_ERR && old != SIG_DFL){
424        CONSOLE_DEBUG("Initialising stack for signal %d to %p",sig,old);
425      traps[0] = old;      traps[0] = old;
426      *stackptr = 0;      *stackptr = 0;
427      (void)signal(sig,old);      (void)SIGNAL(sig,old);
428    }    }
429  }  }
430    
431  static void reset_trap(int signum, SigHandlerFn **tlist, int tos){  static void reset_trap(int signum, SigHandlerFn **tlist, int tos){
432    SigHandlerFn *tp;    SigHandlerFn *tp;
433      SigHandlerFn *oldfn;
434    if ((tlist != NULL) && (tos >= 0) && (tos < MAX_TRAP_DEPTH)) {    if ((tlist != NULL) && (tos >= 0) && (tos < MAX_TRAP_DEPTH)) {
435        oldfn = SIGNAL(signum,SIG_DFL);
436      tp = tlist[tos];      tp = tlist[tos];
437      if (tp != SIG_ERR) {      if (tp != SIG_ERR) {
438        (void)signal(signum,tp);  #ifdef ASC_RESETNEEDED
439    # ifdef SIGNAL_DEBUG
440            CONSOLE_DEBUG("Resetting signal #%d (was %p, new %p)",signum,oldfn,tp);
441    # endif
442          (void)SIGNAL(signum,tp);
443    #else
444    # ifdef SIGNAL_DEBUG
445          if(tp!=oldfn){
446            ERROR_REPORTER_HERE(ASC_PROG_WARNING,"Resetting signal %d (shouldn't be necessary)",signum);
447            (void)SIGNAL(signum,tp);
448          }
449    # endif
450    #endif
451      }      }
452    } else {    }else{
453      (void)signal(signum,SIG_DFL);      (void)SIGNAL(signum,SIG_DFL);
454    }    }
455  }  }
456    
# Line 413  static int pop_trap(SigHandlerFn **tlist Line 499  static int pop_trap(SigHandlerFn **tlist
499    return (-(oldtrap != tp));    return (-(oldtrap != tp));
500  }  }
501    
502    static void print_stack(int signum, SigHandlerFn **tlist, int tos){
503        int i;
504        CONSOLE_DEBUG("---------------");
505        for(i=0;i<tos;++i){
506            CONSOLE_DEBUG("Signal #%d, stack %d/%d: %p",signum,i,tos,tlist[i]);
507        }
508        CONSOLE_DEBUG("--------------- = %d",tos);
509    }
510    
511  /*------------------------------------------  /*------------------------------------------
512    FPE ENV STACK    FPE ENV STACK
513  */  */

Legend:
Removed from v.1001  
changed lines
  Added in v.1002

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