This is the mail archive of the java-patches@gcc.gnu.org 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]
Other format: [Raw text]

Patch: Fix signal handlers under indirect-dispatch on MIPS


For some (as yet unknown) reason on MIPS with -findirect-dispatch, the SIGSEGV and SIGFPE signal handlers were not being installed properly. This caused the failure of any test case that triggered an ArithmeticException or NullPointerException via the signal handling mechanism.

The fix is to call libc's sigaction function instead of trying to trick libc by doing a direct system call to the kernel. Since the MIPS port does not need to patch-up and restart any faulting divide instructions, the syscall trick is not needed. This has the added benefit of slightly simplifying the code.

I guess it is not nice to trick glibc...

These are the test cases that this patch fixes:
Array_3
Divide_1
Invoke_1
StackTrace2
Throw_2
pr83

Regression tested on mipsel-linux with no new failures.

OK to commit?

2006-07-19 David Daney <ddaney@avtrex.com)

	* include/mips-signal.h: Update copyright.
	(struct kernel_sigaction): Removed.
	(SIGNAL_HANDLER): Changed prototype.
	(MAKE_THROW_FRAME): Added cast.
	(INIT_SEGV): Use sigaction instead of syscall.
	(INIT_FPE): Likewise.
Index: include/mips-signal.h
===================================================================
--- include/mips-signal.h	(revision 115540)
+++ include/mips-signal.h	(working copy)
@@ -1,7 +1,8 @@
 // mips-signal.h - Catch runtime signals and turn them into exceptions
 // on an mips based Linux system. 
 
-/* Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2006
+   Free Software Foundation
 
    This file is part of libgcj.
 
@@ -35,28 +36,10 @@
     sigset_t	  uc_sigmask;
 } sig_ucontext_t;
 
-/* We use 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.
-   Additionally we want a proper prototype for the handler function
-   with the struct sigcontext pointer passed by the kernel as the 2nd
-   argument, which isn't there in userland headers. */
-
-struct kernel_sigaction {
-    unsigned int k_sa_flags;
-    void       (*k_sa_handler) (int, siginfo_t *, sig_ucontext_t *);
-    sigset_t     k_sa_mask;
-    void       (*k_sa_restorer)(void);
-    int          k_sa_resv[1];	/* reserved */
-};
-
-
-
 #define SIGNAL_HANDLER(_name) \
 static void _name (int _dummy __attribute__ ((__unused__)), \
 		   siginfo_t *_info __attribute__ ((__unused__)), \
-		   sig_ucontext_t *_arg __attribute__ ((__unused__)))
+		   void *_arg __attribute__ ((__unused__)))
 
 /*
  *  MIPS leaves pc pointing at the faulting instruction, but the
@@ -66,35 +49,32 @@
 #define MAKE_THROW_FRAME(_exception) \
 do                                   \
 {                                    \
-  _arg->uc_mcontext.sc_pc += 4;      \
+  ((sig_ucontext_t *)_arg)->uc_mcontext.sc_pc += 4;      \
   (void)_dummy;                      \
   (void)_info;                       \
 }                                    \
 while (0)
 
-/* For an explanation why we cannot simply use sigaction to
-   install the handlers, see i386-signal.h.  */
-
-#define INIT_SEGV                                    \
-do                                                   \
-  {                                                  \
-    struct kernel_sigaction kact;                    \
-    kact.k_sa_handler = catch_segv;                  \
-    kact.k_sa_flags = SA_SIGINFO | SA_NODEFER;       \
-    sigemptyset (&kact.k_sa_mask);                   \
-    syscall (SYS_sigaction, SIGSEGV, &kact, NULL);   \
-  }                                                  \
+#define INIT_SEGV                            \
+do                                           \
+  {                                          \
+    struct sigaction act;                    \
+    act.sa_sigaction = catch_segv;           \
+    act.sa_flags = SA_SIGINFO | SA_NODEFER;  \
+    sigemptyset (&act.sa_mask);              \
+    sigaction(SIGSEGV, &act, NULL);          \
+  }                                          \
 while (0)
 
-#define INIT_FPE                                     \
-do                                                   \
-  {                                                  \
-    struct kernel_sigaction kact;                    \
-    kact.k_sa_handler = catch_fpe;                   \
-    kact.k_sa_flags = SA_SIGINFO | SA_NODEFER;       \
-    sigemptyset (&kact.k_sa_mask);                   \
-    syscall (SYS_sigaction, SIGFPE, &kact, NULL);    \
-  }                                                  \
+#define INIT_FPE                             \
+do                                           \
+  {                                          \
+    struct sigaction act;                    \
+    act.sa_sigaction = catch_fpe;            \
+    act.sa_flags = SA_SIGINFO | SA_NODEFER;  \
+    sigemptyset (&act.sa_mask);              \
+    sigaction(SIGFPE, &act, NULL);           \
+  }                                          \
 while (0)
 
 #undef HANDLE_DIVIDE_OVERFLOW

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