harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gshiman...@apache.org
Subject svn commit: r487371 - in /harmony/enhanced/drlvm/trunk/vm/vmcore/src: jvmti/jvmti_break_intf.cpp util/linux/signals_ia32.cpp util/win/ia32/nt_exception_filter.cpp
Date Thu, 14 Dec 2006 22:09:16 GMT
Author: gshimansky
Date: Thu Dec 14 14:09:15 2006
New Revision: 487371

URL: http://svn.apache.org/viewvc?view=rev&rev=487371
Log:
Applied HARMONY-2531 [drlvm][jvmti] Incorrect code type when HWE occures on JIT breakpoint

Tests passed on Ubuntu6 x86, WindowsXP and SuSE9 x86_64


Modified:
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp?view=diff&rev=487371&r1=487370&r2=487371
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp Thu Dec 14 14:09:15
2006
@@ -699,6 +699,11 @@
             }
         }
     }
+
+    // Registers in TLS can be changed in user callbacks
+    // It should be restored to keep original address of instrumented instruction
+    // Exception/signal handlers use it when HWE occurs in instruction buffer
+    vm_thread->jvmti_saved_exception_registers = regs;
     unlock();
 
     // Now we need to return back to normal code execution, it is

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp?view=diff&rev=487371&r1=487370&r2=487371
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp Thu Dec 14 14:09:15
2006
@@ -680,6 +680,59 @@
 
 }
 */
+
+void general_signal_handler(int signum, siginfo_t* info, void* context)
+{
+    bool replaced = false;
+    ucontext_t* uc = (ucontext_t *)context;
+    uint32 saved_eip = (uint32)uc->uc_mcontext.gregs[REG_EIP];
+    uint32 new_eip = 0;
+
+    // If exception is occured in processor instruction previously
+    // instrumented by breakpoint, the actual exception address will reside
+    // in jvmti_jit_breakpoints_handling_buffer
+    // We should replace exception address with saved address of instruction
+    uint32 break_buf = (uint32)p_TLS_vmthread->jvmti_jit_breakpoints_handling_buffer;
+    if (saved_eip >= break_buf &&
+        saved_eip < break_buf + 50)
+    {
+        // Breakpoints should not occur in breakpoint buffer
+        assert(signum != SIGTRAP);
+
+        replaced = true;
+        new_eip = p_TLS_vmthread->jvmti_saved_exception_registers.eip;
+        uc->uc_mcontext.gregs[REG_EIP] = (greg_t)new_eip;
+    }
+
+    switch (signum)
+    {
+    case SIGTRAP:
+        jvmti_jit_breakpoint_handler(signum, info, context);
+        break;
+    case SIGSEGV:
+        null_java_reference_handler(signum, info, context);
+        break;
+    case SIGFPE:
+        null_java_divide_by_zero_handler(signum, info, context);
+        break;
+    case SIGABRT:
+        abort_handler(signum, info, context);
+        break;
+    default:
+        // Unknown signal
+        assert(1);
+        break;
+    }
+
+    // If EIP was not changed in specific handler to start another handler,
+    // we should restore original EIP, if it's nesessary
+    if (replaced &&
+        (uint32)uc->uc_mcontext.gregs[REG_EIP] == new_eip)
+    {
+        uc->uc_mcontext.gregs[REG_EIP] = (greg_t)saved_eip;
+    }
+}
+
 void initialize_signals()
 {
     // First figure out how to locate the context in the
@@ -701,17 +754,17 @@
 */
     sigemptyset(&sa.sa_mask);
     sa.sa_flags = SA_SIGINFO;
-    sa.sa_sigaction = &jvmti_jit_breakpoint_handler;
+    sa.sa_sigaction = &general_signal_handler;
     sigaction(SIGTRAP, &sa, NULL);
     
     sigemptyset(&sa.sa_mask);
     sa.sa_flags = SA_SIGINFO | SA_ONSTACK;;
-    sa.sa_sigaction = &null_java_reference_handler;
+    sa.sa_sigaction = &general_signal_handler;
     sigaction(SIGSEGV, &sa, NULL);
 
     sigemptyset(&sa.sa_mask);
     sa.sa_flags = SA_SIGINFO;
-    sa.sa_sigaction = &null_java_divide_by_zero_handler;
+    sa.sa_sigaction = &general_signal_handler;
     sigaction(SIGFPE, &sa, NULL);
 
     extern void interrupt_handler(int);
@@ -722,7 +775,7 @@
     /* install abort_handler to print out call stack on assertion failures */
     sigemptyset(&sa.sa_mask);
     sa.sa_flags = SA_SIGINFO;
-    sa.sa_sigaction = &abort_handler;
+    sa.sa_sigaction = &general_signal_handler;
     sigaction( SIGABRT, &sa, NULL);
     /* abort_handler installed */
 

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp?view=diff&rev=487371&r1=487370&r2=487371
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp Thu Dec
14 14:09:15 2006
@@ -301,6 +301,20 @@
 {
     DWORD code = nt_exception->ExceptionRecord->ExceptionCode;
     PCONTEXT context = nt_exception->ContextRecord;
+    bool flag_replaced = false;
+    uint32 saved_eip = context->Eip;
+
+    // If exception is occured in processor instruction previously
+    // instrumented by breakpoint, the actual exception address will reside
+    // in jvmti_jit_breakpoints_handling_buffer
+    // We should replace exception address with saved address of instruction
+    uint32 break_buf = (uint32)p_TLS_vmthread->jvmti_jit_breakpoints_handling_buffer;
+    if (saved_eip >= break_buf &&
+        saved_eip < break_buf + 50)
+    {
+        flag_replaced = true;
+        context->Eip = (uint32)p_TLS_vmthread->jvmti_saved_exception_registers.eip;
+    }
 
     TRACE2("signals", ("VEH received an exception: code = %x, eip = %p, esp = %p",
         nt_exception->ExceptionRecord->ExceptionCode,
@@ -323,7 +337,10 @@
 
     // delegate "other" cases to default handler
     if (!in_java && code != STATUS_STACK_OVERFLOW)
+    {
+        context->Eip = saved_eip;
         return EXCEPTION_CONTINUE_SEARCH;
+    }
 
     // if HWE occured in java code, suspension should also have been disabled
     assert(!in_java || !hythread_is_suspend_enabled());
@@ -357,6 +374,7 @@
                 // cannot be unwound.
                 // Mark raised exception in TLS and resume execution
                 exn_raise_by_class(env->java_lang_StackOverflowError_Class);
+                context->Eip = saved_eip;
                 return EXCEPTION_CONTINUE_EXECUTION;
             }
         }
@@ -379,6 +397,9 @@
     case JVMTI_EXCEPTION_STATUS:
         // JVMTI breakpoint in JITted code
         {
+            // Breakpoints should not occur in breakpoint buffer
+            assert(!flag_replaced);
+
             Registers regs;
             nt_to_vm_context(context, &regs);
             TRACE2("signals",
@@ -394,6 +415,7 @@
         }
     default:
         // unexpected hardware exception occured in java code
+        context->Eip = saved_eip;
         return EXCEPTION_CONTINUE_SEARCH;
     }
 
@@ -434,7 +456,8 @@
 {
     // this exception handler is executed *after* NT exception handler returned
     DebugUtilsTI* ti = VM_Global_State::loader_env->TI;
-    Registers & regs = p_TLS_vmthread->regs;
+    // Create local copy for registers because registers in TLS can be changed
+    Registers regs = p_TLS_vmthread->regs;
 
     M2nFrame* prev_m2n = m2n_get_last_frame();
     M2nFrame* m2n = NULL;



Mime
View raw message