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 = ≻
! #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 = ≻
! #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