You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ge...@apache.org on 2006/10/06 19:56:08 UTC

svn commit: r453711 - in /incubator/harmony/enhanced/drlvm/trunk/vm/vmcore: include/ src/jvmti/ src/util/ src/util/em64t/base/ src/util/ia32/base/ src/util/ipf/base/

Author: geirm
Date: Fri Oct  6 10:56:07 2006
New Revision: 453711

URL: http://svn.apache.org/viewvc?view=rev&rev=453711
Log:
HARMONY-1726

When crash appears within breakpoint/single step processing,
stack unwinding algorithm cannot unwind breakpoint handler frame correctly due to it's features
(breakpoint handler does not return, it transfers control using si_transfer_control).

Ubuntu 6 - smoke, c-unit, ~kernel


Modified:
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_break_intf.h
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_stack.h
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/native_stack_ipf.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_break_intf.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_break_intf.h?view=diff&rev=453711&r1=453710&r2=453711
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_break_intf.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_break_intf.h Fri Oct  6 10:56:07 2006
@@ -219,6 +219,9 @@
     Lock_Manager         m_lock;
 };
 
+// Address of this function is used for stack unwinding througn breakpoint
+void process_native_breakpoint_event();
+
 // Callback function for native breakpoint processing
 bool jvmti_jit_breakpoint_handler(Registers *regs);
 

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_stack.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_stack.h?view=diff&rev=453711&r1=453710&r2=453711
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_stack.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_stack.h Fri Oct  6 10:56:07 2006
@@ -25,6 +25,7 @@
 #include "jni.h"
 #include "stack_iterator.h"
 #include "native_modules.h"
+#include "vm_threads.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -53,6 +54,7 @@
 int native_test_unwind_special(native_module_t* modules, void* sp);
 bool native_unwind_special(native_module_t* modules,
                 void* stack, void** ip, void** sp, void** bp, bool is_last);
+void native_unwind_interrupted_frame(VM_thread* pthread, void** p_ip, void** p_bp, void** p_sp);
 bool native_is_ip_in_modules(native_module_t* modules, void* ip);
 bool native_is_ip_stub(void* ip);
 

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h?view=diff&rev=453711&r1=453710&r2=453711
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h Fri Oct  6 10:56:07 2006
@@ -71,6 +71,7 @@
 
     void reset_ip() { ip = 0; }
     void* get_ip() { return (void*)ip; }
+    void set_ip(void* src_ip) { ip = (uint64)src_ip; }
 }; //Registers
 
 #else  // !_IPF_
@@ -100,6 +101,7 @@
 
     void reset_ip() { rip = 0; }
     void* get_ip() { return (void*)rip; }
+    void set_ip(void* src_ip) { rip = (uint64)src_ip; }
 }; //Registers
 
 #else // ! _EM64T_
@@ -118,6 +120,7 @@
 
     void reset_ip() { eip = 0; }
     void* get_ip() { return (void*)eip; }
+    void set_ip(void* src_ip) { eip = (uint32)src_ip; }
 }; //Registers
 
 #endif // _EM64T_

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp?view=diff&rev=453711&r1=453710&r2=453711
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp Fri Oct  6 10:56:07 2006
@@ -584,17 +584,12 @@
     // When we get here we know already that breakpoint occurred in JITted code,
     // JVMTI handles it, and registers context is saved for us in TLS
     VM_thread *vm_thread = p_TLS_vmthread;
+    lock();
     Registers regs = vm_thread->jvmti_saved_exception_registers;
-
-#if _IA32_ && PLATFORM_POSIX && INSTRUMENTATION_BYTE == INSTRUMENTATION_BYTE_INT3
-    // Int3 exception address points to the instruction after it
-    regs.eip -= 1;
-#endif //_IA32_ && PLATFORM_POSIX && INSTRUMENTATION_BYTE == INSTRUMENTATION_BYTE_INT3
     NativeCodePtr addr = (NativeCodePtr)regs.get_ip();
 
     TRACE2("jvmti.break", "Native breakpoint occured: " << addr);
 
-    lock();
     VMBreakPoint* bp = find_breakpoint(addr);
     if (NULL == bp) {
         // breakpoint could be deleted by another thread
@@ -1302,7 +1297,7 @@
 // Native breakpoints
 //////////////////////////////////////////////////////////////////////////////
 
-static void process_native_breakpoint_event()
+void process_native_breakpoint_event()
 {
     DebugUtilsTI *ti = VM_Global_State::loader_env->TI;
     ti->vm_brpt->process_native_breakpoint();
@@ -1327,13 +1322,12 @@
     // Now it is necessary to set up a transition to
     // process_native_breakpoint_event from the exception/signal handler
     VM_thread *vm_thread = p_TLS_vmthread;
+    // Store possibly corrected location
+    regs->set_ip((void*)native_location);
     // Copy original registers to TLS
     vm_thread->jvmti_saved_exception_registers = *regs;
-#ifndef _EM64T_
-    regs->eip = (POINTER_SIZE_INT)process_native_breakpoint_event;
-#else
-    regs->rip = (POINTER_SIZE_INT)process_native_breakpoint_event;
-#endif
+    // Set return address for exception handler
+    regs->set_ip((void*)process_native_breakpoint_event);
     return true;
 }
 

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp?view=diff&rev=453711&r1=453710&r2=453711
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp Fri Oct  6 10:56:07 2006
@@ -66,3 +66,10 @@
 {
     return false; // Not implemented
 }
+
+void native_unwind_interrupted_frame(VM_thread* pthread, void** p_ip, void** p_bp, void** p_sp)
+{ // Not implemented yet
+    *p_ip = NULL;
+    *p_bp = NULL;
+    *p_sp = NULL;
+}

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp?view=diff&rev=453711&r1=453710&r2=453711
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp Fri Oct  6 10:56:07 2006
@@ -56,7 +56,7 @@
 bool native_is_out_of_stack(void* value)
 {
     // FIXME: Invalid criterion
-    return (value < (void*)0x10000) || (value > (void*)0x80000000);
+    return (value < (void*)0x10000) || (value > (void*)0xC0000000);
 }
 
 bool native_is_frame_valid(native_module_t* modules, void* bp, void* sp)
@@ -181,4 +181,12 @@
         *bp = *sp;
 
     return true;
+}
+
+void native_unwind_interrupted_frame(VM_thread* pthread, void** p_ip, void** p_bp, void** p_sp)
+{
+    Registers* pregs = &pthread->jvmti_saved_exception_registers;
+    *p_ip = (void*)pregs->eip;
+    *p_bp = (void*)pregs->ebp;
+    *p_sp = (void*)pregs->esp;
 }

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/native_stack_ipf.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/native_stack_ipf.cpp?view=diff&rev=453711&r1=453710&r2=453711
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/native_stack_ipf.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/native_stack_ipf.cpp Fri Oct  6 10:56:07 2006
@@ -59,3 +59,10 @@
 {
     return false; // Not implemented
 }
+
+void native_unwind_interrupted_frame(VM_thread* pthread, void** p_ip, void** p_bp, void** p_sp)
+{ // Not implemented yet
+    *p_ip = NULL;
+    *p_bp = NULL;
+    *p_sp = NULL;
+}

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp?view=diff&rev=453711&r1=453710&r2=453711
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp Fri Oct  6 10:56:07 2006
@@ -26,6 +26,8 @@
 #include "interpreter.h"
 #include "interpreter_exports.h"
 #include "compile.h"
+#include "jvmti_break_intf.h"
+#include "environment.h"
 #include "native_modules.h"
 #include "native_stack.h"
 
@@ -88,6 +90,12 @@
 
     return false;
 }
+
+static bool native_is_ip_in_breakpoint_handler(void* ip)
+{
+    return (ip >= &process_native_breakpoint_event &&
+            ip < &jvmti_jit_breakpoint_handler);
+}
 /// Helper functions
 //////////////////////////////////////////////////////////////////////////////
 
@@ -143,14 +151,19 @@
 
     si = si_create_from_native(pthread);
 
-    if (is_java)
+    if (is_java ||
+        // Frame was pushed already by breakpoint handler
+        (si_is_native(si) && si_get_m2n(si) && m2n_is_suspended_frame(si_get_m2n(si))))
+    {
         si_goto_previous(si);
+    }
 
     jint inline_index = -1;
     jint inline_count;
     CodeChunkInfo* cci = NULL;
     bool is_stub = false;
     int special_count = 0;
+    bool flag_breakpoint = false;
 
     while (1)
     {
@@ -197,7 +210,7 @@
             else
             {
                 inline_index = -1;
-                // Ge to previous stack frame from StackIterator
+                // Go to previous stack frame from StackIterator
                 si_goto_previous(si);
                 native_get_ip_bp_from_si_jit_context(si, &ip, &bp);//???
                 native_get_sp_from_si_jit_context(si, &sp);
@@ -238,7 +251,25 @@
 
             if (native_is_frame_valid(modules, bp, sp))
             { // Simply bp-based frame, let's unwind it
-                native_unwind_bp_based_frame(bp, &ip, &bp, &sp);
+                void *tmp_ip, *tmp_bp, *tmp_sp;
+                native_unwind_bp_based_frame(bp, &tmp_ip, &tmp_bp, &tmp_sp);
+
+                VMBreakPoints* vm_breaks = VM_Global_State::loader_env->TI->vm_brpt;
+                vm_breaks->lock();
+
+                if (native_is_ip_in_breakpoint_handler(tmp_ip))
+                {
+                    native_unwind_interrupted_frame(pthread, &ip, &bp, &sp);
+                    flag_breakpoint = true;
+                }
+                else
+                {
+                    ip = tmp_ip;
+                    bp = tmp_bp;
+                    sp = tmp_sp;
+                }
+
+                vm_breaks->unlock();
             }
             else
             { // Is not bp-based frame
@@ -266,9 +297,10 @@
         code_type = vm_identify_eip(ip);
         is_java = (code_type == VM_TYPE_JAVA);
 
-        // If we've reached Java without native stub
-        if (is_java && !is_stub)
+        // If we've reached Java without native stub (or breakpoint handler frame)
+        if (is_java && !is_stub && !flag_breakpoint)
             break; // then stop processing
+        flag_breakpoint = false;
 // ^^ Native ^^
 /////////////////////////
     }
@@ -279,6 +311,8 @@
         m2n_set_last_frame(pthread, m2n_get_previous_frame(plm2n));
         STD_FREE(plm2n);
     }
+
+    si_free(si);
 
     return frame_count;
 }