changeset 1187:b182fe895dda

2008-11-06 Gary Benson <gbenson@redhat.com> * ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp (JVM_handle_linux_signal): Added signal chaining, abort_if_unrecognised, and stack overflow recognition.
author Gary Benson <gbenson@redhat.com>
date Thu, 06 Nov 2008 12:14:32 -0500
parents 9e45d56689ab
children 56fbf813637d
files ChangeLog ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp
diffstat 2 files changed, 70 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Nov 06 08:02:02 2008 -0500
+++ b/ChangeLog	Thu Nov 06 12:14:32 2008 -0500
@@ -1,3 +1,9 @@
+2008-11-06  Gary Benson  <gbenson@redhat.com>
+
+	* ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp
+	(JVM_handle_linux_signal): Added signal chaining,
+	abort_if_unrecognised, and stack overflow recognition.
+
 2008-11-06  Gary Benson  <gbenson@redhat.com>
 
 	* ports/hotspot/src/cpu/zero/vm/globals_zero.hpp
--- a/ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Thu Nov 06 08:02:02 2008 -0500
+++ b/ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Thu Nov 06 12:14:32 2008 -0500
@@ -131,6 +131,60 @@
   }
 
   if (info != NULL && thread != NULL) {
+    // Handle ALL stack overflow variations here
+    if (sig == SIGSEGV) {
+      address addr = (address) info->si_addr;
+
+      // check if fault address is within thread stack
+      if (addr < thread->stack_base() &&
+          addr >= thread->stack_base() - thread->stack_size()) {
+        // stack overflow
+        if (thread->in_stack_yellow_zone(addr)) {
+          thread->disable_stack_yellow_zone();
+          Unimplemented();
+        }
+        else if (thread->in_stack_red_zone(addr)) {
+          thread->disable_stack_red_zone();
+          Unimplemented();
+        }
+        else {
+          // Accessing stack address below sp may cause SEGV if
+          // current thread has MAP_GROWSDOWN stack. This should
+          // only happen when current thread was created by user
+          // code with MAP_GROWSDOWN flag and then attached to VM.
+          // See notes in os_linux.cpp.
+          if (thread->osthread()->expanding_stack() == 0) {
+            thread->osthread()->set_expanding_stack();
+            if (os::Linux::manually_expand_stack(thread, addr)) {
+              thread->osthread()->clear_expanding_stack();
+              return true;
+            }
+            thread->osthread()->clear_expanding_stack();
+          }
+          else {
+            fatal("recursive segv. expanding stack.");
+          }
+        } 
+      }
+    }
+
+    /*if (thread->thread_state() == _thread_in_Java) {
+      Unimplemented();
+    }
+    else*/ if (thread->thread_state() == _thread_in_vm &&
+               sig == SIGBUS && thread->doing_unsafe_access()) {
+      Unimplemented();
+    }
+
+    // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC
+    // kicks in and the heap gets shrunk before the field access.
+    /*if (sig == SIGSEGV || sig == SIGBUS) {
+      address addr = JNI_FastGetField::find_slowcase_pc(pc);
+      if (addr != (address)-1) {
+        stub = addr;
+      }
+    }*/
+
     // Check to see if we caught the safepoint code in the process
     // of write protecting the memory serialization page.  It write
     // enables the page immediately after protecting it so we can
@@ -143,6 +197,16 @@
     }
   }
 
+  // signal-chaining
+  if (os::Linux::chained_handler(sig, info, ucVoid)) {
+     return true;
+  }
+
+  if (!abort_if_unrecognized) {
+    // caller wants another chance, so give it to him
+    return false;
+  }
+
 #ifndef PRODUCT
   if (sig == SIGSEGV) {
     fatal("\n#"