This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Prevent infinite recursion in signal->exception converter
- To: gcc-patches at gcc dot gnu dot org, java-patches at gcc dot gnu dot org
- Subject: Prevent infinite recursion in signal->exception converter
- From: "Zack Weinberg" <zackw at stanford dot edu>
- Date: Thu, 19 Apr 2001 19:00:17 -0700
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