This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
include/i386-signal.h fix
- From: Andrew Haley <aph at cambridge dot redhat dot com>
- To: java-patches at gcc dot gnu dot org
- Date: Mon, 18 Mar 2002 15:45:05 +0000 (GMT)
- Subject: include/i386-signal.h fix
- References: <3C95C96E.3040404@waitaki.otago.ac.nz>
Hans Boehm has persuaded me that I should fix a longstanding bug in
the signal handling for the i386.
The problem was that I was using an incorrect struct to pass the
signal handler info to the kernel. As it happens, the structs were so
similar that it still worked, but this fix is overdue.
This patch should not change the behaviour of libgcj in any way. If
it does, I need to be told about it.
Andrew.
2002-03-18 Andrew Haley <aph@cambridge.redhat.com>
* include/i386-signal.h (old_i386_kernel_sigaction): New.
INIT_SEGV: Use old_i386_kernel_sigaction.
INIT_FP: Likewise.
Index: i386-signal.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/include/i386-signal.h,v
retrieving revision 1.13
diff -u -w -r1.13 i386-signal.h
--- i386-signal.h 2001/07/17 23:59:07 1.13
+++ i386-signal.h 2002/03/18 15:41:39
@@ -1,6 +1,7 @@
-// i386-signal.h - Catch runtime signals and turn them into exceptions.
+// i386-signal.h - Catch runtime signals and turn them into exceptions
+// on an i386 based Linux system.
-/* Copyright (C) 1998, 1999, 2001 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation
This file is part of libgcj.
@@ -8,11 +9,7 @@
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
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
- */
-
#ifndef JAVA_SIGNAL_H
#define JAVA_SIGNAL_H 1
@@ -99,15 +96,27 @@
} \
while (0)
+/* We use old_kernel_sigaction here because we're calling the kernel
+ directly rather than via glibc. The sigaction structure that the
+ syscall uses is a different shape from the one in userland and not
+ visible to us in a header file so we define it here. */
+
+struct old_i386_kernel_sigaction {
+ void (*k_sa_handler) (int);
+ unsigned long k_sa_mask;
+ unsigned long k_sa_flags;
+ void (*sa_restorer) (void);
+};
+
#define INIT_SEGV \
do \
{ \
nullp = new java::lang::NullPointerException (); \
- struct sigaction act; \
- act.sa_handler = catch_segv; \
- sigemptyset (&act.sa_mask); \
- act.sa_flags = 0; \
- syscall (SYS_sigaction, SIGSEGV, &act, NULL); \
+ struct old_i386_kernel_sigaction kact; \
+ kact.k_sa_handler = catch_segv; \
+ kact.k_sa_mask = 0; \
+ kact.k_sa_flags = 0; \
+ syscall (SYS_sigaction, SIGSEGV, &kact, NULL); \
} \
while (0)
@@ -116,11 +125,11 @@
{ \
arithexception = new java::lang::ArithmeticException \
(JvNewStringLatin1 ("/ by zero")); \
- struct sigaction act; \
- act.sa_handler = catch_fpe; \
- sigemptyset (&act.sa_mask); \
- act.sa_flags = 0; \
- syscall (SYS_sigaction, SIGFPE, &act, NULL); \
+ struct old_i386_kernel_sigaction kact; \
+ kact.k_sa_handler = catch_fpe; \
+ kact.k_sa_mask = 0; \
+ kact.k_sa_flags = 0; \
+ syscall (SYS_sigaction, SIGFPE, &kact, NULL); \
} \
while (0)
@@ -133,9 +142,15 @@
* 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. */
+ * syscall(SYS_sigaction) causes our handler to be called directly
+ * by the kernel, bypassing any wrappers.
+
+ * Also, there is at the present time no unwind info in the
+ * linuxthreads library's signal handlers and so we can't unwind
+ * through them anyway.
+
+ * Finally, the code that glibc uses to return from a signal handler
+ * is subject to change. */
#endif /* JAVA_SIGNAL_H */