PATCH: Divide overflow handler

Andrew Haley aph@redhat.com
Tue Jan 30 13:00:00 GMT 2001


This fixes a bug that causes the testsuite to hang; the divide
overflow handler returns to the faulting instruction so the program
never terminates.  This is causing grief for those trying to get the
gcc 3.0 branch done.

I checked it in.

Andrew.

2001-01-26  Andrew Haley  <aph@redhat.com>

        (INIT_FPE): Use a direct system call to set the handler.

Index: i386-signal.h
===================================================================
RCS file: /cvs/gcc/egcs/libjava/include/i386-signal.h,v
retrieving revision 1.8
diff -p -2 -c -r1.8 i386-signal.h
*** i386-signal.h       2000/05/19 17:55:30     1.8
--- i386-signal.h       2001/01/30 20:43:42
***************
*** 1,5 ****
  // i386-signal.h - Catch runtime signals and turn them into exceptions.
  
! /* Copyright (C) 1998, 1999  Free Software Foundation
  
     This file is part of libgcj.
--- 1,5 ----
  // i386-signal.h - Catch runtime signals and turn them into exceptions.
  
! /* Copyright (C) 1998, 1999, 2001  Free Software Foundation
  
     This file is part of libgcj.
*************** details.  */
*** 18,21 ****
--- 18,22 ----
  
  #include <signal.h>
+ #include <sys/syscall.h>
  
  #define HANDLE_SEGV 1
*************** do                                                             \
*** 141,147 ****
      sigemptyset (&act.sa_mask);                                       \
      act.sa_flags = 0;                                         \
!     __sigaction (SIGFPE, &act, NULL);                         \
    }                                                           \
  while (0)  
  
  #endif /* JAVA_SIGNAL_H */
--- 142,161 ----
      sigemptyset (&act.sa_mask);                                       \
      act.sa_flags = 0;                                         \
!     syscall (SYS_sigaction, SIGFPE, &act, NULL);              \
    }                                                           \
  while (0)  
+ 
+ /* You might wonder why we use syscall(SYS_sigaction) in INIT_FPE
+  * instead of the standard sigaction().  This is necessary because of
+  * the shenanigans above where we increment the PC saved in the
+  * context and then return.  This trick will only work when we are
+  * called _directly_ by the kernel, because linuxthreads wraps signal
+  * handlers and its wrappers do not copy the sigcontext struct back
+  * when returning from a signal handler.  If we return from our divide
+  * handler to a linuxthreads wrapper, we will lose the PC adjustment
+  * we made and return to the faulting instruction again.  Using
+  * syscall(SYS_sigaction) causes our handler to be called directly by
+  * the kernel, bypassing any wrappers.  This is a kludge, and a future
+  * version of this handler will do something better.  */
  
  #endif /* JAVA_SIGNAL_H */


More information about the Java-patches mailing list