This is the mail archive of the java-discuss@sourceware.cygnus.com mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: SIGFPE -> ArithmeticException ?


Thanks to Bryce, who let me rlogin to his machine all the way over in
New Zealand, I have discovered that recent Linux kernels have changed
the way that signals are delivered to processes.  This means that the
SEGV and division by zero handlers don't work any more.  Oddly, none
of the machines here in the UK have any problem.

The good news is that the new interface is less of a kludge and is
much more likely to remain stable.

Bryce, as your machine is the only machine that I have ever seen with
this problem, please test this patch as soon as you possibly can.

Thanks,
Andrew.



1999-06-25  Andrew Haley  <aph@cygnus.com>

        * include/i386-signal.h: Rewritten to use SystemV style ucontext
        signal handlers where possible.

Index: libjava/include/i386-signal.h
===================================================================
RCS file: /cvs/java/libgcj/libjava/include/i386-signal.h,v
retrieving revision 1.3
diff -c -2 -p -r1.3 i386-signal.h
*** i386-signal.h	1999/05/20 08:26:52	1.3
--- i386-signal.h	1999/06/25 18:32:58
*************** Libgcj License.  Please consult the file
*** 9,15 ****
  details.  */
  
! /* This technique should work for all i386 based Unices which conform
!  * to iBCS2.  This includes all versions of Linux more recent than 1.3 
!  */
  
  
--- 9,15 ----
  details.  */
  
! /* There are two versions of the handlers here: old Linux kernels and
!  * newer SystemV sigcontext style signal handlers.  Unfortunately
!  * they are incompatible. */
  
  
*************** details.  */
*** 22,36 ****
  #define HANDLE_FPE 1
  
  #define SIGNAL_HANDLER(_name)	\
  static void _name (int _dummy)
  
! #define MAKE_THROW_FRAME						\
! do									\
! {									\
    void **_p = (void **)&_dummy;						\
    struct sigcontext_struct *_regs = (struct sigcontext_struct *)++_p;	\
  									\
!   register unsigned long _ebp = _regs->ebp;				\
!   register unsigned char *_eip = (unsigned char *)_regs->eip;		\
  									\
    asm volatile ("mov %0, (%%ebp); mov %1, 4(%%ebp)"			\
--- 22,84 ----
  #define HANDLE_FPE 1
  
+ #ifdef SA_SIGINFO
+ #include <sys/ucontext.h>
+ 
+ #define SIGNAL_HANDLER(_name) 						\
+ static void _name (int _dummy, siginfo_t *_info, ucontext_t *_context)
+ 
+ #define INSTALL_HANDLER(_signal, _handler)	\
+     struct sigaction act;			\
+     act.sa_sigaction = _handler;		\
+     act.sa_flags = SA_SIGINFO | SA_NODEFER;	\
+     sigemptyset (&act.sa_mask);			\
+     sigaction (_signal, &act, NULL);
+ 
+ #define GET_CONTEXT						\
+ 								\
+   (void)_dummy;							\
+   (void)_info;							\
+ 								\
+   greg_t *_regs = _context->uc_mcontext.gregs;			\
+ 								\
+   register unsigned long *_ebp = (unsigned long *)_regs[EBP];	\
+   register unsigned char *_eip = (unsigned char *)_regs[EIP];
+ 
+ #define SIG_REG_EAX (_regs[EAX])
+ #define SIG_REG_EIP (_regs[EIP])
+ #define SIG_REG_EBP (_regs[EBP])
+ #define SIG_REG_EDX (_regs[EDX])
+ 
+ #else
+ 
  #define SIGNAL_HANDLER(_name)	\
  static void _name (int _dummy)
  
! #define INSTALL_HANDLER(_signal, _handler)	\
!     struct sigaction act;			\
!     act.sa_handler = _handler;			\
!     sigemptyset (&act.sa_mask);			\
!     act.sa_flags = 0;				\
!     sigaction (_signal, &act, NULL);
! 
! #define GET_CONTEXT							\
    void **_p = (void **)&_dummy;						\
    struct sigcontext_struct *_regs = (struct sigcontext_struct *)++_p;	\
  									\
!   register unsigned long *_ebp = (unsigned long *)_regs->ebp;		\
!   register unsigned char *_eip = (unsigned char *)_regs->eip;
! 
! #define SIG_REG_EAX (_regs->eax)
! #define SIG_REG_EIP (_regs->eip)
! #define SIG_REG_EBP (_regs->ebp)
! #define SIG_REG_EDX (_regs->edx)
! 
! #endif
! 
! 
! #define MAKE_THROW_FRAME						\
! do									\
! {									\
!   GET_CONTEXT								\
  									\
    asm volatile ("mov %0, (%%ebp); mov %1, 4(%%ebp)"			\
*************** while (0)
*** 42,50 ****
  do									\
  {									\
!   void **_p = (void **)&_dummy;						\
!   struct sigcontext_struct *_regs = (struct sigcontext_struct *)++_p;	\
! 									\
!   register unsigned long *_ebp = (unsigned long *)_regs->ebp;		\
!   register unsigned char *_eip = (unsigned char *)_regs->eip;		\
  									\
    /* According to the JVM spec, "if the dividend is the negative	\
--- 90,94 ----
  do									\
  {									\
!   GET_CONTEXT								\
  									\
    /* According to the JVM spec, "if the dividend is the negative	\
*************** do									\
*** 58,62 ****
     * little calculation to figure out where the following instruction	\
     * actually is.							\
! 									\
     */									\
  									\
--- 102,106 ----
     * little calculation to figure out where the following instruction	\
     * actually is.							\
!   									\
     */									\
  									\
*************** do									\
*** 65,72 ****
        unsigned char _modrm = _eip[1];					\
  									\
!       if (_regs->eax == 0x80000000					\
  	  && ((_modrm >> 3) & 7) == 7) /* Signed divide */		\
  	{								\
! 	  _regs->edx = 0; /* the remainder is zero */			\
  	  switch (_modrm >> 6)						\
  	    {								\
--- 109,116 ----
        unsigned char _modrm = _eip[1];					\
  									\
!       if ((unsigned long)SIG_REG_EAX == 0x80000000L			\
  	  && ((_modrm >> 3) & 7) == 7) /* Signed divide */		\
  	{								\
! 	  SIG_REG_EDX = 0; /* the remainder is zero */			\
  	  switch (_modrm >> 6)						\
  	    {								\
*************** do									\
*** 85,89 ****
  	    }								\
  	  _eip += 2;							\
! 	  _regs->eip = (unsigned long)_eip;				\
  	  return;							\
  	}								\
--- 129,133 ----
  	    }								\
  	  _eip += 2;							\
! 	  SIG_REG_EIP = (unsigned long)_eip;				\
  	  return;							\
  	}								\
*************** while (0)
*** 110,134 ****
  do								\
    {								\
!     nullp = new java::lang::NullPointerException ();    	\
!     struct sigaction act;					\
!     act.sa_handler = catch_segv;				\
!     sigemptyset (&act.sa_mask);					\
!     act.sa_flags = 0;						\
!     sigaction (SIGSEGV, &act, NULL);				\
    }								\
! while (0)  
  
! #define INIT_FPE                                                \
  do								\
    {								\
      arithexception = new java::lang::ArithmeticException 	\
        (JvNewStringLatin1 ("/ by zero"));			\
!     struct sigaction act;					\
!     act.sa_handler = catch_fpe;					\
!     sigemptyset (&act.sa_mask);					\
!     act.sa_flags = 0;						\
!     sigaction (SIGFPE, &act, NULL);				\
    }								\
! while (0)  
  
  #endif /* JAVA_SIGNAL_H */
--- 154,170 ----
  do								\
    {								\
!     nullp = new java::lang::NullPointerException ();		\
!     INSTALL_HANDLER(SIGSEGV, catch_segv)                        \
    }								\
! while (0)							
  
! #define INIT_FPE						\
  do								\
    {								\
      arithexception = new java::lang::ArithmeticException 	\
        (JvNewStringLatin1 ("/ by zero"));			\
!     INSTALL_HANDLER(SIGFPE, catch_fpe)				\
    }								\
! while (0)
  
  #endif /* JAVA_SIGNAL_H */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]