/[ascend]/branches/relerrorlist/ascend/utilities/ascSignal.c
ViewVC logotype

Diff of /branches/relerrorlist/ascend/utilities/ascSignal.c

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

revision 3216 by jpye, Sun Apr 2 13:37:54 2017 UTC revision 3217 by jpye, Sat Oct 28 07:01:00 2017 UTC
# Line 65  Line 65 
65  #include "ascSignal.h"  #include "ascSignal.h"
66  #include <ascend/general/panic.h>  #include <ascend/general/panic.h>
67    
68  /* #define SIGNAL_DEBUG */  //#define SIGNAL_DEBUG
69    #ifdef SIGNAL_DEBUG
70    # define MSG CONSOLE_DEBUG
71    #else
72    # define MSG(ARGS...) ((void)0)
73    #endif
74  /*------------------------------------------------------------------------------  /*------------------------------------------------------------------------------
75    GLOBALS AND FOWARD DECS    GLOBALS AND FOWARD DECS
76  */  */
# Line 77  JMP_BUF g_seg_env; Line 81  JMP_BUF g_seg_env;
81  JMP_BUF g_int_env;  JMP_BUF g_int_env;
82    
83  #ifdef HAVE_C99FPE  #ifdef HAVE_C99FPE
84  fenv_t g_fenv;  fexcept_t g_fenv;
85  #endif  #endif
86    
87  /* for future use */  /* for future use */
# Line 151  static int fenv_push(fenv_t *stack,int * Line 155  static int fenv_push(fenv_t *stack,int *
155  int Asc_SignalInit(void){  int Asc_SignalInit(void){
156    /* initialize SIGFPE stack */    /* initialize SIGFPE stack */
157    
 #ifdef SIGNAL_DEBUG  
158  # ifdef ASC_RESETNEEDED  # ifdef ASC_RESETNEEDED
159    CONSOLE_DEBUG("Initialising signal stack (with resets needed)");    MSG("Initialising signal stack (with resets needed)");
160  # else  # else
161    CONSOLE_DEBUG("Initialising signal stack (with resets not required)");    MSG("Initialising signal stack (with resets not required)");
162  # endif  # endif
 #endif  
163    
164    if(f_traps == NULL){    if(f_traps == NULL){
165      f_traps = ASC_NEW(SignalStacks);      f_traps = ASC_NEW(SignalStacks);
# Line 184  int Asc_SignalInit(void){ Line 186  int Asc_SignalInit(void){
186    initstack(SIGINT);    initstack(SIGINT);
187    initstack(SIGSEGV);    initstack(SIGSEGV);
188    
189  #if defined(HAVE_C99FPE)  #ifdef HAVE_C99FPE
190  # ifdef SIGNAL_DEBUG    MSG("Initialise FPE state to stack (%d)",f_fenv_stack_top);
   CONSOLE_DEBUG("Initialise FPE state to stack (%d)",f_fenv_stack_top);  
 # endif  
191    fenv_push(f_fenv_stack,&f_fenv_stack_top,0);    fenv_push(f_fenv_stack,&f_fenv_stack_top,0);
192  #endif  #endif
193    
# Line 197  int Asc_SignalInit(void){ Line 197  int Asc_SignalInit(void){
197  /**  /**
198      Clears and destroys the stacks of signal handlers.      Clears and destroys the stacks of signal handlers.
199  */  */
200  void Asc_SignalDestroy(void)  void Asc_SignalDestroy(void){
201  {  #ifdef HAVE_C99FPE
202      MSG("Restoring FPE state from stack (%d)",f_fenv_stack_top);
203      fenv_pop(f_fenv_stack,&f_fenv_stack_top);
204    #endif
205    
206    ascfree(f_traps);    ascfree(f_traps);
207  #ifdef HAVE_C99FPE  #ifdef HAVE_C99FPE
208    if(f_fenv_stack){    if(f_fenv_stack){
# Line 207  void Asc_SignalDestroy(void) Line 211  void Asc_SignalDestroy(void)
211    }    }
212  #endif  #endif
213    f_traps = NULL;    f_traps = NULL;
214  #ifdef SIGNAL_DEBUG    MSG("Destroyed signal stack");
   CONSOLE_DEBUG("Destroyed signal stack");  
 #endif  
215  }  }
216    
217  /**  /**
# Line 227  void Asc_SignalRecover(int force){ Line 229  void Asc_SignalRecover(int force){
229  #ifndef ASC_RESETNEEDED  #ifndef ASC_RESETNEEDED
230      if(force){      if(force){
231  #endif  #endif
232  # ifdef SIGNAL_DEBUG          MSG("Resetting traps");
         CONSOLE_DEBUG("Resetting traps");  
 # endif  
233          reset_trap(SIGFPE);          reset_trap(SIGFPE);
234          reset_trap(SIGINT);          reset_trap(SIGINT);
235          reset_trap(SIGSEGV);          reset_trap(SIGSEGV);
# Line 258  int Asc_SignalHandlerPush_impl(int signu Line 258  int Asc_SignalHandlerPush_impl(int signu
258      return -2;      return -2;
259    }    }
260    
261  #ifdef SIGNAL_DEBUG    MSG("Pushing handler %s for signal %s(%d)",name,SIGNAME(signum),signum);
   CONSOLE_DEBUG("Pushing handler %s for signal %s(%d)"  
     ,name,SIGNAME(signum),signum  
   );  
 #endif  
262    
263    err = push_trap(signum, func, name, file, line);    err = push_trap(signum, func, name, file, line);
264    
# Line 306  int Asc_SignalHandlerPop_impl(int signum Line 302  int Asc_SignalHandlerPop_impl(int signum
302      , char *file, int line      , char *file, int line
303  ){  ){
304    int err;    int err;
305  #ifdef SIGNAL_DEBUG    MSG("(%s:%d) Popping signal stack for signal %s (%d) (expecting top to be %p '%s')",file,line,SIGNAME(signum),signum,tp,name);
   CONSOLE_DEBUG("(%s:%d) Popping signal stack for signal %s (%d) (expecting top to be %p '%s')",file,line,SIGNAME(signum),signum,tp,name);  
 #endif  
306    
307    err = pop_trap(signum, tp, name, file, line);    err = pop_trap(signum, tp, name, file, line);
308    
309    if (err != 0 && tp != NULL) {    if (err != 0 && tp != NULL) {
310  #ifdef SIGNAL_DEBUG      MSG("stack pop mismatch");
     CONSOLE_DEBUG("stack pop mismatch");  
 #endif  
311      ERROR_REPORTER_HERE(ASC_PROG_ERROR,"Asc_Signal (%d) stack pop mismatch.",signum);      ERROR_REPORTER_HERE(ASC_PROG_ERROR,"Asc_Signal (%d) stack pop mismatch.",signum);
312      return err;      return err;
313    }    }
# Line 349  int Asc_SignalHandlerPop_impl(int signum Line 341  int Asc_SignalHandlerPop_impl(int signum
341  }  }
342    
343  void Asc_SignalTrap(int sigval){  void Asc_SignalTrap(int sigval){
344  #ifdef SIGNAL_DEBUG    MSG("Caught signal #%d",sigval);
   CONSOLE_DEBUG("Caught signal #%d",sigval);  
 #endif  
345    switch(sigval) {    switch(sigval) {
346    case SIGFPE:    case SIGFPE:
347      ERROR_REPORTER_HERE(ASC_PROG_WARNING,"Floating point error caught");      ERROR_REPORTER_HERE(ASC_PROG_WARNING,"Floating point error caught");
348      CONSOLE_DEBUG("SIGFPE caught");      MSG("SIGFPE caught");
349  #ifdef HAVE_C99FPE  #ifdef HAVE_C99FPE
350      FPRESET;      FPRESET;
351  #endif  #endif
352      LONGJMP(g_fpe_env,sigval);      LONGJMP(g_fpe_env,sigval);
353    case SIGINT:    case SIGINT:
354      CONSOLE_DEBUG("SIGINT (Ctrl-C) caught");      MSG("SIGINT (Ctrl-C) caught");
355      LONGJMP(g_int_env,sigval);      LONGJMP(g_int_env,sigval);
356    case SIGSEGV:    case SIGSEGV:
357  #ifdef SIGNAL_DEBUG      MSG("SIGSEGV caught");
     CONSOLE_DEBUG("SIGSEGV caught");  
 #endif  
358      LONGJMP(g_seg_env,sigval);      LONGJMP(g_seg_env,sigval);
359    default:    default:
360  #ifdef SIGNAL_DEBUG      MSG("Unrecognised signal %d caught",sigval);
     CONSOLE_DEBUG("Unrecognised signal %d caught",sigval);  
 #endif  
361      ERROR_REPORTER_HERE(ASC_PROG_ERR,"Installed on unexpected signal (sigval = %d). Returning (who knows where...)", sigval);      ERROR_REPORTER_HERE(ASC_PROG_ERR,"Installed on unexpected signal (sigval = %d). Returning (who knows where...)", sigval);
362      return;      return;
363    }    }
# Line 486  static void initstack(int sig){ Line 472  static void initstack(int sig){
472      }      }
473      old = SIGNAL(sig, SIG_DFL);      old = SIGNAL(sig, SIG_DFL);
474      if(old != SIG_ERR && old != SIG_DFL){      if(old != SIG_ERR && old != SIG_DFL){
475  #ifdef SIGNAL_DEBUG          MSG("Initialising stack for signal %d to %p",sig,old);
         CONSOLE_DEBUG("Initialising stack for signal %d to %p",sig,old);  
 #endif  
476          stack[0].handler = old;          stack[0].handler = old;
477  #ifdef SIGNAL_DEBUG  #ifdef SIGNAL_DEBUG
478          if(old == SIG_DFL){          if(old == SIG_DFL){
# Line 502  static void initstack(int sig){ Line 486  static void initstack(int sig){
486          *index = 0;          *index = 0;
487          (void)SIGNAL(sig,old);          (void)SIGNAL(sig,old);
488      }else{      }else{
489  #ifdef SIGNAL_DEBUG          MSG("Initialising stack for signal %d as empty",sig);
         CONSOLE_DEBUG("Initialising stack for signal %d as empty",sig);  
 #endif  
490          *index = -1;          *index = -1;
491      }      }
492  }  }
# Line 529  static void reset_trap(int signum){ Line 511  static void reset_trap(int signum){
511              top = stack[*index];              top = stack[*index];
512              if(top.handler != SIG_ERR && top.handler != SIG_DFL){              if(top.handler != SIG_ERR && top.handler != SIG_DFL){
513                  /* reset the signal, if it's not already set to what we want */                  /* reset the signal, if it's not already set to what we want */
514  #ifdef SIGNAL_DEBUG                  MSG("Resetting signal %s from %p to %p (%s)"
                 CONSOLE_DEBUG("Resetting signal %s from %p to %p (%s)"  
515                      ,SIGNAME(signum)                      ,SIGNAME(signum)
516                      ,oldfn,top.handler,top.name                      ,oldfn,top.handler,top.name
517                  );                  );
 #endif  
518                  (void)SIGNAL(signum,top.handler);                  (void)SIGNAL(signum,top.handler);
519                  return;                  return;
520              }              }
521          }          }
522  #ifdef SIGNAL_DEBUG          MSG("Resetting %s handler to SIG_DFL (stack empty or invalid)"
         CONSOLE_DEBUG("Resetting %s handler to SIG_DFL (stack empty or invalid)"  
523              ,SIGNAME(signum)              ,SIGNAME(signum)
524          );          );
 #endif  
525          (void)SIGNAL(signum,SIG_DFL);          (void)SIGNAL(signum,SIG_DFL);
526      }else{      }else{
527          ERROR_REPORTER_HERE(ASC_PROG_ERR,"Signal handler not yet initialised! Setting %s handler to SIG_DFL.",SIGNAME(signum));          ERROR_REPORTER_HERE(ASC_PROG_ERR,"Signal handler not yet initialised! Setting %s handler to SIG_DFL.",SIGNAME(signum));
# Line 648  static int pop_trap(int signum, SigHandl Line 626  static int pop_trap(int signum, SigHandl
626      return 0 on success      return 0 on success
627  */  */
628  static int fenv_push(fenv_t *stack, int *top, int excepts){  static int fenv_push(fenv_t *stack, int *top, int excepts){
629  #ifdef SIGNAL_DEBUG      MSG("Pushing FENV flags %d",excepts);
     CONSOLE_DEBUG("Pushing FENV flags %d",excepts);  
 #endif  
630    
631      if(*top > MAX_TRAP_DEPTH - 1){      if(*top > MAX_TRAP_DEPTH - 1){
632          ERROR_REPORTER_HERE(ASC_PROG_ERR,"FPE stack is full");          ERROR_REPORTER_HERE(ASC_PROG_ERR,"FPE stack is full");
# Line 670  static int fenv_push(fenv_t *stack, int Line 646  static int fenv_push(fenv_t *stack, int
646          return 4;          return 4;
647      }      }
648      fesetexceptflag(&g_fenv, excepts);      fesetexceptflag(&g_fenv, excepts);
649      //CONSOLE_DEBUG("Enabled div-by-zero FPE exception (%d)",*top);      MSG("Enabled div-by-zero FPE exception (%d)",*top);
650      return 0;      return 0;
651  }  }
652    
# Line 678  static int fenv_push(fenv_t *stack, int Line 654  static int fenv_push(fenv_t *stack, int
654      Restore a saved FPU state. Return 0 on success.      Restore a saved FPU state. Return 0 on success.
655  */  */
656  static int fenv_pop(fenv_t *stack, int *top){  static int fenv_pop(fenv_t *stack, int *top){
657  #ifdef CONSOLE_DEBUG      MSG("Popping FENV flags");
     CONSOLE_DEBUG("Popping FENV flags");  
 #endif  
658      if(*top < 0){      if(*top < 0){
659          ERROR_REPORTER_HERE(ASC_PROG_ERR,"FPE stack is empty");          ERROR_REPORTER_HERE(ASC_PROG_ERR,"FPE stack is empty");
660          return 1;          return 1;
# Line 694  static int fenv_pop(fenv_t *stack, int * Line 668  static int fenv_pop(fenv_t *stack, int *
668          ERROR_REPORTER_HERE(ASC_PROG_ERR,"unable to set env");          ERROR_REPORTER_HERE(ASC_PROG_ERR,"unable to set env");
669          return 3;          return 3;
670      }      }
671      //CONSOLE_DEBUG("Restorted FPE state");      MSG("Restorted FPE state");
672      return 0;      return 0;
673  }  }
674    

Legend:
Removed from v.3216  
changed lines
  Added in v.3217

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