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]

Prevent infinite recursion in signal->exception converter


If the exception-handling runtime's data structures get trashed, we
may segfault inside the unwinder library.  In Java programs, this will
be intercepted by libjava's SIGSEGV handler, which will convert the
signal into a NullPointerException and attempt to throw it.  The
unwind library is still hosed, so it will segfault again; it'll get
caught again; round and round we go, till we run out of stack, which
can take a while (at least two minutes on my system).

This patch wraps the signal-to-exception code so that if the program
gets another SIGSEGV before the stack is unwound past the original
handler, it will dump core cleanly.  A more skillful C++ hacker may be
able to write this better than me.  signal_depth was originally a
static data member of prevent_signal_recursion, but I couldn't make it
be private to the file.

I compiled this and verified that a properly-linked Divide_1 now
segfaults cleanly instead of going into an infinite loop.  I did not
run the libjava test suite, because there's still a libtool bug to
deal with.

zw

	* prims.cc: Prevent infinite recursion should the unwind
	library get SIGSEGV or SIGFPE:
	(prevent_signal_recursion): New private class.
	(catch_segv, catch_fpe): Use it.

===================================================================
Index: prims.cc
--- prims.cc	2001/03/26 07:05:31	1.49
+++ prims.cc	2001/04/20 01:56:00
@@ -100,6 +100,21 @@ void (*_Jv_JVMPI_Notify_THREAD_END) (JVM
 #endif
 
 
+// This class prevents us from getting into infinite recursion
+// should the unwind handlers themselves cause SIGSEGV or SIGFPE.
+#if defined HANDLE_SEGV || defined HANDLE_FPE
+static int signal_depth = 0;
+struct prevent_signal_recursion {
+  prevent_signal_recursion(int signo) {
+    if (signal_depth++) {
+      signal (signo, SIG_DFL);
+      raise (signo);
+    }
+  }
+  ~prevent_signal_recursion() { signal_depth--; }
+};
+#endif
+
 extern "C" void _Jv_ThrowSignal (jthrowable) __attribute ((noreturn));
 
 // Just like _Jv_Throw, but fill in the stack trace first.  Although
@@ -117,6 +132,7 @@ static java::lang::NullPointerException 
 
 SIGNAL_HANDLER (catch_segv)
 {
+  prevent_signal_recursion here (SIGSEGV);
   MAKE_THROW_FRAME (nullp);
   _Jv_ThrowSignal (nullp);
 }
@@ -127,6 +143,7 @@ static java::lang::ArithmeticException *
 #ifdef HANDLE_FPE
 SIGNAL_HANDLER (catch_fpe)
 {
+  prevent_signal_recursion here (SIGFPE);
 #ifdef HANDLE_DIVIDE_OVERFLOW
   HANDLE_DIVIDE_OVERFLOW;
 #else


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