This is the mail archive of the
java-discuss@sources.redhat.com
mailing list for the Java project.
ArithmeticException regressions
- To: bryce at albatross dot co dot nz
- Subject: ArithmeticException regressions
- From: Andrew Haley <aph at redhat dot com>
- Date: Fri, 26 Jan 2001 18:18:48 +0000 (GMT)
- Cc: java-discuss at sources dot redhat dot com
- References: <20010121120441.1173.qmail@sourceware.cygnus.com>
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 */