CVS: sml-dist/src/runtime/mach-dep signal-sysdep.h,1.13,1.14 unix-fault.c,1.7,1.8 unix-signal.c,1.6,1.7

John Reppy <[email protected]>
Newsgroups gmane.comp.lang.sml.smlnj.commits
Message-ID <[email protected]>
Update of /cvsroot/smlnj/sml-dist/src/runtime/mach-dep
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19077/src/runtime/mach-dep

Modified Files:
	signal-sysdep.h unix-fault.c unix-signal.c 
Log Message:
  Cleanup of Linux signal handling plus port to x86-64.


Index: signal-sysdep.h
===================================================================
RCS file: /cvsroot/smlnj/sml-dist/src/runtime/mach-dep/signal-sysdep.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -C2 -d -r1.13 -r1.14
*** signal-sysdep.h	10 Feb 2006 22:14:58 -0000	1.13
--- signal-sysdep.h	21 Feb 2006 21:33:24 -0000	1.14
***************
*** 77,87 ****
  typedef ucontext_t SigContext_t;
  
- #define SIG_Flags		SA_SIGINFO
- 
  #elif defined(HAS_SIGCONTEXT)
  
  typedef int SigInfo_t;
  typedef struct sigcontext SigContext_t;
- #  define SIG_Flags		0
  #endif
  
--- 77,84 ----
***************
*** 89,99 ****
  #if defined(HAS_POSIX_SIGS)
  /** POSIX signals **/
! #define SIG_SetHandler(sig, h)	{       		\
! 	struct sigaction __svec;        		\
! 	sigfillset(&(__svec.sa_mask));  		\
! 	__svec.sa_flags = SIG_Flags;			\
! 	__svec.sa_handler = (h);        		\
! 	sigaction ((sig), &__svec, 0);  		\
!     }
  #define SIG_GetHandler(sig, h)  {				\
  	struct sigaction __svec;				\
--- 86,120 ----
  #if defined(HAS_POSIX_SIGS)
  /** POSIX signals **/
! #  if defined(HAS_UCONTEXT)
! #    define SIG_SetHandler(sig, h)	{       		\
! 	    struct sigaction __svec;        			\
! 	    sigfillset(&(__svec.sa_mask));  			\
! 	    __svec.sa_flags = SA_SIGINFO;			\
! 	    __svec.sa_sigaction = (h);        			\
! 	    sigaction ((sig), &__svec, 0);  			\
! 	}
! #    define SIG_SetIgnore(sig)		{			\
! 	    struct sigaction __svec;        			\
! 	    __svec.sa_flags = 0;				\
! 	    __svec.sa_handler = SIG_DFL;        		\
! 	    sigaction ((sig), &__svec, 0);  			\
! 	}
! #    define SIG_SetDefault(sig)		{			\
! 	    struct sigaction __svec;        			\
! 	    __svec.sa_flags = 0;				\
! 	    __svec.sa_handler = SIG_IGN;        		\
! 	    sigaction ((sig), &__svec, 0);  			\
! 	}
! #  else
! #    define SIG_SetHandler(sig, h)	{       		\
! 	    struct sigaction __svec;        			\
! 	    sigfillset(&(__svec.sa_mask));  			\
! 	    __svec.sa_flags = SIG_Flags;			\
! 	    __svec.sa_sighandler = (h);        			\
! 	    sigaction ((sig), &__svec, 0);  			\
! 	}
! #    define SIG_SetIgnore(sig)	SIG_SetHandler(sig, SIG_IGN)
! #    define SIG_SetDefault(sig)	SIG_SetHandler(sig, SIG_DFL)
! #endif
  #define SIG_GetHandler(sig, h)  {				\
  	struct sigaction __svec;				\
***************
*** 400,440 ****
  #  define LIMITPTR_X86OFFSET	3	/* offset (words) of limitptr in ML stack */
  					/* frame (see X86.prim.asm) */
! extern Addr_t *ML_X86Frame;   /* used to get at limitptr */
  #  define SIG_InitFPE()    FPEEnable()
  
  #  if (defined(TARGET_X86) && defined(OPSYS_LINUX))
      /** X86, LINUX **/
! #    if (!defined(_SIGCONTEXT_H) && !defined(sigcontext_struct))
!       /* older versions of Linux don't define this in <signal.h> */
! 	struct sigcontext {
! 	    unsigned short gs, __gsh;
! 	    unsigned short fs, __fsh;
! 	    unsigned short es, __esh;
! 	    unsigned short ds, __dsh;
! 	    unsigned long edi;
! 	    unsigned long esi;
! 	    unsigned long ebp;
! 	    unsigned long esp;
! 	    unsigned long ebx;
! 	    unsigned long edx;
! 	    unsigned long ecx;
! 	    unsigned long eax;
! 	    unsigned long trapno;
! 	    unsigned long err;
! 	    unsigned long eip;
! 	    unsigned short cs, __csh;
! 	    unsigned long eflags;
! 	    unsigned long esp_at_signal;
! 	    unsigned short ss, __ssh;
! 	    unsigned long i387;
! 	    unsigned long oldmask;
! 	    unsigned long cr2;
! 	};
! #    endif
! 
! #define INTO_OPCODE		0xce	/* the 'into' instruction is a single */
  					/* instruction that signals Overflow */
  
- 
  #    define SIG_FAULT1		SIGFPE
  #    define SIG_FAULT2		SIGSEGV
--- 421,432 ----
  #  define LIMITPTR_X86OFFSET	3	/* offset (words) of limitptr in ML stack */
  					/* frame (see X86.prim.asm) */
! extern Addr_t *ML_X86Frame;		/* used to get at limitptr */
  #  define SIG_InitFPE()    FPEEnable()
  
  #  if (defined(TARGET_X86) && defined(OPSYS_LINUX))
      /** X86, LINUX **/
! #    define INTO_OPCODE		0xce	/* the 'into' instruction is a single */
  					/* instruction that signals Overflow */
  
  #    define SIG_FAULT1		SIGFPE
  #    define SIG_FAULT2		SIGSEGV
***************
*** 443,452 ****
  	(((s) == SIGSEGV) && (((Byte_t *)c)[-1] == INTO_OPCODE))
  
! #    define SIG_GetCode(info,scp)	((scp)->eip)
  /* for linux, SIG_GetCode simply returns the address of the fault */
! #    define SIG_GetPC(scp)		((scp)->eip)
! #    define SIG_SetPC(scp,addr)		{ (scp)->eip = (long)(addr); }
  #    define SIG_ZeroLimitPtr(scp)	{ ML_X86Frame[LIMITPTR_X86OFFSET] = 0; }
-      typedef void SigReturn_t;
  
  #  elif defined(OPSYS_FREEBSD)
--- 435,443 ----
  	(((s) == SIGSEGV) && (((Byte_t *)c)[-1] == INTO_OPCODE))
  
! #    define SIG_GetCode(info,scp)	((scp)->uc_mcontext.gregs[REG_EIP])
  /* for linux, SIG_GetCode simply returns the address of the fault */
! #    define SIG_GetPC(scp)		((scp)->uc_mcontext.gregs[REG_EIP])
! #    define SIG_SetPC(scp,addr)		{ (scp)->uc_mcontext.gregs[REG_EIP] = (long)(addr); }
  #    define SIG_ZeroLimitPtr(scp)	{ ML_X86Frame[LIMITPTR_X86OFFSET] = 0; }
  
  #  elif defined(OPSYS_FREEBSD)

Index: unix-fault.c
===================================================================
RCS file: /cvsroot/smlnj/sml-dist/src/runtime/mach-dep/unix-fault.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** unix-fault.c	28 Apr 2005 20:51:18 -0000	1.7
--- unix-fault.c	21 Feb 2006 21:33:24 -0000	1.8
***************
*** 25,31 ****
  /* local routines */
  PVT SigReturn_t FaultHandler (/* int sig, SigInfo_t code, SigContext_t *scp */);
- #if defined(TARGET_BYTECODE)
- PVT SigReturn_t PanicTrace (/* int sig, SigInfo_t code, SigContext_t *scp */);
- #endif
  
  
--- 25,28 ----
***************
*** 35,40 ****
  {
  
- #ifndef TARGET_BYTECODE
- 
    /** Set up the Div and Overflow faults **/
  #ifdef SIG_FAULT1
--- 32,35 ----
***************
*** 48,80 ****
      SIG_InitFPE ();
  
- #else /* TARGET_BYTECODE */
- /** **/ SIG_SetHandler (SIGINT, PanicTrace);
-         SIG_SetHandler (SIGBUS, PanicTrace);
-         SIG_SetHandler (SIGSEGV, PanicTrace);
- #endif /* !TARGET_BYTECODE */
- 
  } /* end of InitFaultHandlers */
  
  
- #ifndef TARGET_BYTECODE
- 
  /* FaultHandler:
   *
   * Handle arithmetic faults (e.g., divide by zero, integer overflow).
   */
! PVT SigReturn_t FaultHandler (
!     int		    signal,
! #if (defined(TARGET_X86) && defined(OPSYS_LINUX))
!     SigContext_t    sc)
! #elif (defined(TARGET_PPC) && defined(OPSYS_LINUX))
!     SigContext_t    *scp)
! #else
!     SigInfo_t	    info,
!     SigContext_t    *scp)
! #endif
  {
! #if (defined(TARGET_X86) && defined(OPSYS_LINUX))
!     SigContext_t    *scp = &sc;
! #endif
      ml_state_t	    *msp = SELF_VPROC->vp_state;
      extern Word_t   request_fault[]; 
--- 43,58 ----
      SIG_InitFPE ();
  
  } /* end of InitFaultHandlers */
  
  
  /* FaultHandler:
   *
   * Handle arithmetic faults (e.g., divide by zero, integer overflow).
   */
! #if defined(HAS_POSIX_SIGS) && defined(HAS_UCONTEXT)
! 
! PVT SigReturn_t FaultHandler (int signal, siginfo_t *si, void *c)
  {
!     ucontext_t	    *scp = (ucontext_t *)c;
      ml_state_t	    *msp = SELF_VPROC->vp_state;
      extern Word_t   request_fault[]; 
***************
*** 108,128 ****
  } /* end of FaultHandler */
  
! #endif /* !TARGET_BYTECODE */
! 
! 
! #if defined(TARGET_BYTECODE)
! extern void PrintRegs (FILE *);
! #ifdef INSTR_HISTORY
! extern void PrintInstrHistory (FILE *);
! #endif
  
! /* PanicTrace:
!  * This signal handler prints a trace of the last few instructions executed
!  * by the bytecode interpreter (for debugging purposes).
!  */
! PVT SigReturn_t PanicTrace (
      int		    signal,
! #if (defined(TARGET_X86) && defined(OPSYS_LINUX))
!     SigContext_t    sc)
  #else
      SigInfo_t	    info,
--- 86,95 ----
  } /* end of FaultHandler */
  
! #else
  
! PVT SigReturn_t FaultHandler (
      int		    signal,
! #if (defined(TARGET_PPC) && defined(OPSYS_LINUX))
!     SigContext_t    *scp)
  #else
      SigInfo_t	    info,
***************
*** 130,149 ****
  #endif
  {
! #if (defined(TARGET_X86) && defined(OPSYS_LINUX))
!     SigContext_t    *scp = &sc;
! #endif
  
!     SayDebug ("**** PANIC: signal = %d, code = %#x ****\n",
! 	signal, SIG_GetCode(info, scp));
!     PrintRegs(DebugF);
! #ifdef INSTR_HISTORY
!     PrintInstrHistory (DebugF);
  #endif
-     SayDebug ("\n");
  
!     Exit (1);
! }
! #endif
  
  
  #if ((defined(TARGET_RS6000) || defined(TARGET_PPC)) && defined(OPSYS_AIX))
--- 97,132 ----
  #endif
  {
!     ml_state_t	    *msp = SELF_VPROC->vp_state;
!     extern Word_t   request_fault[]; 
!     int		    code = SIG_GetCode(info, scp);
  
! #ifdef SIGNAL_DEBUG
!     SayDebug ("Fault handler: sig = %d, inML = %d\n",
! 	signal, SELF_VPROC->vp_inMLFlag);
  #endif
  
!     if (! SELF_VPROC->vp_inMLFlag) 
! 	Die ("bogus fault not in ML: sig = %d, code = %#x, pc = %#x)\n",
! 	    signal, SIG_GetCode(info, scp), SIG_GetPC(scp));
! 
!    /* Map the signal to the appropriate ML exception. */
!     if (INT_OVFLW(signal, code)) {
! 	msp->ml_faultExn = OverflowId;
! 	msp->ml_faultPC = (Word_t)SIG_GetPC(scp);
!     }
!     else if (INT_DIVZERO(signal, code)) {
! 	msp->ml_faultExn = DivId;
! 	msp->ml_faultPC = (Word_t)SIG_GetPC(scp);
!     }
!     else
! 	Die ("unexpected fault, signal = %d, code = %#x", signal, code);
! 
!     SIG_SetPC (scp, request_fault);
  
+     SIG_ResetFPE (scp);
+ 
+ } /* end of FaultHandler */
+ 
+ #endif
  
  #if ((defined(TARGET_RS6000) || defined(TARGET_PPC)) && defined(OPSYS_AIX))
***************
*** 166,168 ****
  #endif
  
! #endif
--- 149,151 ----
  #endif
  
! #endif /* !defined(__CYGWIN32__) */

Index: unix-signal.c
===================================================================
RCS file: /cvsroot/smlnj/sml-dist/src/runtime/mach-dep/unix-signal.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** unix-signal.c	3 May 2005 17:26:49 -0000	1.6
--- unix-signal.c	21 Feb 2006 21:33:24 -0000	1.7
***************
*** 74,81 ****
  	    switch (sigState) {
  	      case ML_SIG_IGNORE:
! 		SIG_SetHandler (sigNum, SIG_IGN);
  		break;
  	      case ML_SIG_DEFAULT:
! 		SIG_SetHandler (sigNum, SIG_DFL);
  		break;
  	      case ML_SIG_ENABLED:
--- 74,81 ----
  	    switch (sigState) {
  	      case ML_SIG_IGNORE:
! 		SIG_SetIgnore (sigNum);
  		break;
  	      case ML_SIG_DEFAULT:
! 		SIG_SetDefault (sigNum);
  		break;
  	      case ML_SIG_ENABLED:
***************
*** 88,92 ****
  	}
  	else Die ("SetSignalState: unknown signal %d\n", sigNum);
- 	    
      } /* end of switch */
  
--- 88,91 ----
***************
*** 122,130 ****
   * The C signal handler for signals that are to be passed to the ML handler.
   */
  PVT SigReturn_t CSigHandler (
      int		    sig,
! #if (defined(TARGET_X86) && defined(OPSYS_LINUX))
!     SigContext_t    sc)
! #elif (defined(TARGET_PPC) && defined(OPSYS_LINUX))
      SigContext_t    *scp)
  #else
--- 121,161 ----
   * The C signal handler for signals that are to be passed to the ML handler.
   */
+ #if defined(HAS_POSIX_SIGS) && defined(HAS_UCONTEXT)
+ 
+ PVT SigReturn_t CSigHandler (int sig, siginfo_t *si, void *c)
+ {
+     ucontext_t	    *scp = (ucontext_t *)c;
+     vproc_state_t   *vsp = SELF_VPROC;
+ 
+     vsp->vp_sigCounts[sig].nReceived++;
+     vsp->vp_totalSigCount.nReceived++;
+ 
+ #ifdef SIGNAL_DEBUG
+ SayDebug ("CSigHandler: sig = %d, pending = %d, inHandler = %d\n",
+ sig, vsp->vp_handlerPending, vsp->vp_inSigHandler);
+ #endif
+ 
+     /* The following line is needed only when currently executing
+      * "pure" C code.  But doing it anyway in all other cases will
+      * not hurt... */
+     vsp->vp_limitPtrMask = 0;
+ 
+     if (vsp->vp_inMLFlag && (! vsp->vp_handlerPending) && (! vsp->vp_inSigHandler)) {
+ 	vsp->vp_handlerPending = TRUE;
+ #ifdef USE_ZERO_LIMIT_PTR_FN
+ 	SIG_SavePC(vsp->vp_state, scp);
+ 	SIG_SetPC(scp, ZeroLimitPtr);
+ #else /* we can adjust the heap limit directly */
+ 	SIG_ZeroLimitPtr(scp);
+ #endif
+     }
+ 
+ } /* end of CSigHandler */
+ 
+ #else
+ 
  PVT SigReturn_t CSigHandler (
      int		    sig,
! #if (defined(TARGET_PPC) && defined(OPSYS_LINUX))
      SigContext_t    *scp)
  #else
***************
*** 163,166 ****
--- 194,199 ----
  } /* end of CSigHandler */
  
+ #endif
+ 
  
  /* SetSignalMask:



-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=103432&bid=230486&dat=121642
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.