You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by gs...@apache.org on 2008/03/25 12:13:52 UTC

svn commit: r640769 - in /harmony/enhanced/drlvm/trunk/vm: port/src/signals/linux/signals_common.cpp vmcore/src/util/linux/ia32_em64t/signals_common.cpp

Author: gshimansky
Date: Tue Mar 25 04:13:29 2008
New Revision: 640769

URL: http://svn.apache.org/viewvc?rev=640769&view=rev
Log:
Applied workaround patch from HARMONY-5617
[drlvm] On Linux crash handler may crash itself when handling SOE condition


Modified:
    harmony/enhanced/drlvm/trunk/vm/port/src/signals/linux/signals_common.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/ia32_em64t/signals_common.cpp

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/signals/linux/signals_common.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/signals/linux/signals_common.cpp?rev=640769&r1=640768&r2=640769&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/signals/linux/signals_common.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/signals/linux/signals_common.cpp Tue Mar 25 04:13:29 2008
@@ -15,6 +15,8 @@
  *  limitations under the License.
  */
 
+#include <sys/mman.h>
+#include <limits.h>
 #include <unistd.h>
 #undef __USE_XOPEN
 #include <signal.h>
@@ -39,6 +41,41 @@
 }
 
 
+// Because application can set up some protected area in stack region,
+// we need to re-enable access to this area because we need to operate
+// with the original stack of the thread
+// Application should take care of restoring this protected area after
+// signal processing
+// FIXME This is workaround only; it also can break crash processing for SIGSEGV
+// Ideally all the functionality on guard pages should be in Port.
+// Unfortunately, it can involve thread creation in Port, additional
+// thread wrapper, and moving general TLS operations to Port, so
+// it's postponed
+static void clear_stack_protection(Registers* regs, void* fault_addr)
+{
+    if (!fault_addr) // is not SO
+        return;
+
+    size_t fault = (size_t)fault_addr;
+    size_t sp = (size_t)regs->get_sp();
+    size_t diff = (fault > sp) ? (fault - sp) : (sp - fault);
+    size_t page_size = (size_t)sysconf(_SC_PAGE_SIZE);
+
+    if (diff > page_size)
+        return; // Most probably is not SO
+
+    size_t start = sp & ~(page_size - 1);
+    size_t size = page_size;
+
+    if (sp - start < 0x400)
+    {
+        start -= page_size;
+        size += page_size;
+    }
+
+    int res = mprotect((void*)start, size, PROT_READ | PROT_WRITE);
+}
+
 static void c_handler(Registers* pregs, size_t signum, void* fault_addr)
 { // this exception handler is executed *after* VEH handler returned
     int result;
@@ -101,6 +138,10 @@
     Registers regs;
     // Convert OS context to Registers
     port_thread_context_to_regs(&regs, (ucontext_t*)context);
+
+    if (signum == SIGSEGV)
+        clear_stack_protection(&regs, info->si_addr);
+
     // Prepare registers for transfering control out of signal handler
     void* callback = (void*)&c_handler;
     port_set_longjump_regs(callback, &regs, 3,

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/ia32_em64t/signals_common.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/ia32_em64t/signals_common.cpp?rev=640769&r1=640768&r2=640769&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/ia32_em64t/signals_common.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/ia32_em64t/signals_common.cpp Tue Mar 25 04:13:29 2008
@@ -353,10 +353,10 @@
         regs->set_ip(new_ip);
     }
 
-    if (!vmthread || env == NULL ||
-        !is_in_java(regs) || interpreter_enabled())
+    if (!vmthread || env == NULL)
         return FALSE; // Crash
 
+    // Stack overflow can occur in native code as well as in interpreter
     if (check_stack_overflow(regs, fault_addr))
     {
         Boolean result = stack_overflow_handler(signum, regs, fault_addr);
@@ -366,6 +366,9 @@
 
         return result;
     }
+
+    if (!is_in_java(regs) || interpreter_enabled())
+        return FALSE; // Crash
 
     // Pass exception to NCAI exception handler
     bool is_handled = 0;