This is the mail archive of the java-discuss@sources.redhat.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]

ArithmeticException regressions


bryce@albatross.co.nz writes:
 > 1) This test case does not run correctly:
 > 
 > public class ArithExTest {
 >     public static void main(String[] args) 
 >     {
 >       try
 >         {
 >           int k = 3 / 0;
 >         }
 >       catch (Exception x)
 >         {
 >           System.out.println ("ok");
 >         }
 >     }
 > }
 > 
 > The exception gets thrown all the way back to the default
 > handler, missing the hander defined in the test case.
 > 
 > 2) The testsuite case libjava.lang/Divide_1.java loops 
 > indefinatly. I can see the SIGFPE in gdb but execution seems
 > to resume at a point before the instructions that generated
 > the exception.

Try this.

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 -u -r1.8 i386-signal.h
--- i386-signal.h	2000/05/19 17:55:30	1.8
+++ i386-signal.h	2001/01/26 18:09:20
@@ -1,6 +1,6 @@
 // i386-signal.h - Catch runtime signals and turn them into exceptions.
 
-/* Copyright (C) 1998, 1999  Free Software Foundation
+/* Copyright (C) 1998, 1999, 2001  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -17,6 +17,7 @@
 #define JAVA_SIGNAL_H 1
 
 #include <signal.h>
+#include <syscall.h>
 
 #define HANDLE_SEGV 1
 #define HANDLE_FPE 1
@@ -140,9 +141,22 @@
     act.sa_handler = catch_fpe;					\
     sigemptyset (&act.sa_mask);					\
     act.sa_flags = 0;						\
-    __sigaction (SIGFPE, &act, NULL);				\
+    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 add 2 to 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 */
   

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