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/02/12 18:30:58 UTC
svn commit: r620872 - in /harmony/enhanced/drlvm/trunk/vm:
port/src/encoder/ia32_em64t/ port/src/lil/ia32/pim/ vmcore/include/
vmcore/src/ncai/ vmcore/src/stack/ vmcore/src/util/
vmcore/src/util/em64t/base/ vmcore/src/util/ia32/base/ vmcore/src/util/ip...
Author: gshimansky
Date: Tue Feb 12 09:30:49 2008
New Revision: 620872
URL: http://svn.apache.org/viewvc?rev=620872&view=rev
Log:
Applied patch from HARMONY-5490
[drlvm][signals] New heuristics for crash handler
Added:
harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_stack_os.cpp (with props)
harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_stack_os.cpp (with props)
Modified:
harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.cpp
harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp
harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_stack.h
harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_internal.h
harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h
harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_stack.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/native_stack_ipf.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp
Modified: harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.cpp?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.cpp Tue Feb 12 09:30:49 2008
@@ -74,7 +74,7 @@
if (is_prefix(bytes)) {
// More than 4 prefixes together ?
- assert(false);
+// assert(false);
return 0;
}
@@ -96,7 +96,7 @@
}
}
if (!found) {
- assert(false);
+// assert(false);
return 0;
}
tmp.size = (unsigned)(bytes-(const unsigned char*)addr);
@@ -167,7 +167,7 @@
}
return true;
case OpcodeByteKind_cw:
- assert(false); // not an error, but not expected in current env
+// assert(false); // not an error, but not expected in current env
break;
case OpcodeByteKind_cd:
{
@@ -231,11 +231,11 @@
return true;
}
case OpcodeByteKind_ZeroOpcodeByte: // cant be here
- assert(false);
+// assert(false);
break;
default:
// unknown kind ? how comes ?
- assert(false);
+// assert(false);
break;
}
return false;
Modified: harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp Tue Feb 12 09:30:49 2008
@@ -470,7 +470,7 @@
BEGIN_OPCODES()
{OpcodeInfo::all, {0xE8, cd}, {rel32}, U },
{OpcodeInfo::ia32, {0xFF, _2}, {r_m32}, U },
- {OpcodeInfo::em64t, {REX_W, 0xFF, _2}, {r_m64}, U },
+ {OpcodeInfo::em64t, {0xFF, _2}, {r_m64}, U },
END_OPCODES()
END_MNEMONIC()
Modified: harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp Tue Feb 12 09:30:49 2008
@@ -115,7 +115,6 @@
si->c.p_esi = &m2nfl->esi;
si->c.p_ebx = &m2nfl->ebx;
si->c.p_ebp = &m2nfl->ebp;
- si->c.p_eip = &m2nfl->eip;
}
}
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_stack.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_stack.h?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_stack.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_stack.h Tue Feb 12 09:30:49 2008
@@ -38,26 +38,33 @@
void* stack;
} native_frame_t;
+typedef struct WalkContext {
+ native_module_t* modules;
+ bool clean_modules;
+ native_segment_t stack;
+} WalkContext;
+
// If frame_array is NULL, only returns real frame count
-int walk_native_stack_registers(Registers* pregs,
+int walk_native_stack_registers(WalkContext* context, Registers* pregs,
VM_thread* pthread, int max_depth, native_frame_t* frame_array);
+bool native_init_walk_context(WalkContext* context, native_module_t* modules, Registers* regs);
+void native_clean_walk_context(WalkContext* context);
+
//////////////////////////////////////////////////////////////////////////////
// Interchange between platform-dependent and general functions
-void native_get_frame_info(Registers* regs, void** ip, void** bp, void** sp);
-bool native_unwind_bp_based_frame(void* frame, void** ip, void** bp, void** sp);
-void native_get_ip_bp_from_si_jit_context(StackIterator* si, void** ip, void** bp);
-void native_get_sp_from_si_jit_context(StackIterator* si, void** sp);
-bool native_is_out_of_stack(void* value);
-bool native_is_frame_valid(native_module_t* modules, void* bp, void* sp);
-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(jvmti_thread_t thread, void** p_ip, void** p_bp, void** p_sp);
-bool native_is_ip_in_modules(native_module_t* modules, void* ip);
+
+bool native_unwind_stack_frame(WalkContext* context, Registers* regs);
+void native_get_regs_from_jit_context(JitFrameContext* jfc, Registers* regs);
+bool native_get_stack_range(WalkContext* context, Registers* regs, native_segment_t* seg);
+bool native_is_frame_exists(WalkContext* context, Registers* regs);
+bool native_unwind_special(WalkContext* context, Registers* regs);
+bool native_is_in_code(WalkContext* context, void* ip);
+bool native_is_in_stack(WalkContext* context, void* sp);
bool native_is_ip_stub(void* ip);
char* native_get_stub_name(void* ip, char* buf, size_t buflen);
+void native_fill_frame_info(Registers* regs, native_frame_t* frame, jint jdepth);
#ifdef __cplusplus
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_internal.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_internal.h?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_internal.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_internal.h Tue Feb 12 09:30:49 2008
@@ -28,9 +28,6 @@
extern NcaiRegisterTableItem g_ncai_reg_table[];
-int walk_native_stack(hythread_t thread,
- VM_thread* pthread, int max_depth, ncaiFrameInfo* frame_info);
-
void clean_all_modules(ncaiModule* pmodules);
void ncai_library_load_callback(const char* name);
void ncai_library_unload_callback(const char* name);
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h Tue Feb 12 09:30:49 2008
@@ -69,9 +69,11 @@
uint64 *bsp;
uint64 ip;
- void reset_ip() { ip = 0; }
+ void reset_ip() { ip = 0; }
void* get_ip() { return (void*)ip; }
- void set_ip(void* src_ip) { ip = (uint64)src_ip; }
+ void set_ip(void* src_ip) { ip = (uint64)src_ip; }
+ void* get_sp() { return (void*)bsp; }
+ void set_sp(void* src_sp) { }
}; //Registers
#else // !_IPF_
@@ -101,9 +103,11 @@
uint32 eflags;
- void reset_ip() { rip = 0; }
+ void reset_ip() { rip = 0; }
void* get_ip() { return (void*)rip; }
- void set_ip(void* src_ip) { rip = (uint64)src_ip; }
+ void set_ip(void* src_ip) { rip = (uint64)src_ip; }
+ void* get_sp() { return (void*)rsp; }
+ void set_sp(void* src_sp) { rsp = (uint64)src_sp; }
}; //Registers
#else // ! _EM64T_
@@ -120,9 +124,11 @@
uint32 eip;
uint32 eflags;
- void reset_ip() { eip = 0; }
+ void reset_ip() { eip = 0; }
void* get_ip() { return (void*)eip; }
- void set_ip(void* src_ip) { eip = (uint32)src_ip; }
+ void set_ip(void* src_ip) { eip = (uint32)src_ip; }
+ void* get_sp() { return (void*)esp; }
+ void set_sp(void* src_sp) { esp = (uint32)src_sp; }
}; //Registers
#endif // _EM64T_
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_stack.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_stack.cpp?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_stack.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_stack.cpp Tue Feb 12 09:30:49 2008
@@ -153,8 +153,14 @@
vm_thread = jthread_get_vm_thread(thread);
}
- *pcount = walk_native_stack_registers(®s,
+ WalkContext context;
+ if (!native_init_walk_context(&context, NULL, ®s))
+ return NCAI_ERROR_INTERNAL;
+
+ *pcount = walk_native_stack_registers(&context, ®s,
vm_thread, max_depth, frame_array);
+
+ native_clean_walk_context(&context);
return NCAI_ERROR_NONE;
}
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp Tue Feb 12 09:30:49 2008
@@ -474,26 +474,31 @@
// walk_native_stack_registers cannot unwind frames in release build),
// we will use JIT/interpreter stack iterator to complete stack trace.
- jint num_frames =
- walk_native_stack_registers(regs, thread, -1, NULL);
+ WalkContext context;
+
+ if (native_init_walk_context(&context, g_modules, regs))
+ {
+ jint num_frames =
+ walk_native_stack_registers(&context, regs, thread, -1, NULL);
- if (num_frames)
- frames = (native_frame_t*)STD_ALLOCA(sizeof(native_frame_t)*num_frames);
+ if (num_frames)
+ frames = (native_frame_t*)STD_ALLOCA(sizeof(native_frame_t)*num_frames);
- if (num_frames && frames)
- walk_native_stack_registers(regs, thread, num_frames, frames);
- else
- num_frames = 0; // Consider native stack trace empty
+ if (num_frames && frames)
+ walk_native_stack_registers(&context, regs, thread, num_frames, frames);
+ else
+ num_frames = 0; // Consider native stack trace empty
- fprintf(stderr, "\nStack trace:\n");
+ fprintf(stderr, "\nStack trace:\n");
- if(interpreter_enabled() && thread)
- sd_print_stack_interpreter(thread, frames, num_frames);
- else // It should be used also for threads without VM_thread structure
- sd_print_stack_jit(thread, frames, num_frames);
+ if (interpreter_enabled() && thread)
+ sd_print_stack_interpreter(thread, frames, num_frames);
+ else // It should be used also for threads without VM_thread structure
+ sd_print_stack_jit(thread, frames, num_frames);
- fprintf(stderr, "<end of stack trace>\n");
- fflush(stderr);
+ fprintf(stderr, "<end of stack trace>\n");
+ fflush(stderr);
+ }
if (thread)
set_unwindable(unwindable);
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp Tue Feb 12 09:30:49 2008
@@ -20,175 +20,141 @@
*/
#include "method_lookup.h"
+#include "dec_base.h"
+#include "native_modules.h"
#include "native_stack.h"
-void native_get_frame_info(Registers* regs, void** ip, void** bp, void** sp)
+
+bool native_is_frame_exists(WalkContext* context, Registers* regs)
{
- *ip = (void*)regs->rip;
- *bp = (void*)regs->rbp;
- *sp = (void*)regs->rsp;
+ // Check for frame layout and stack values
+ if ((regs->rbp < regs->rsp) || !native_is_in_stack(context, (void*)regs->rbp))
+ return false; // Invalid frame
+
+ void** frame_ptr = (void**)regs->rbp;
+ void* rip = frame_ptr[1]; // Return address
+
+ // Check return address for meaning
+ return (native_is_in_code(context, rip) || native_is_ip_stub(rip));
}
-bool native_unwind_bp_based_frame(void* frame, void** ip, void** bp, void** sp)
+bool native_unwind_stack_frame(WalkContext* context, Registers* regs)
{
- void** frame_ptr = (void**)frame;
+ void** frame = (void**)regs->rbp;
- *ip = frame_ptr[1];
- *bp = frame_ptr[0];
+ void* rbp = frame[0];
+ void* rip = frame[1];
+// void* rsp = (void*)(frame + 2);
+ void* rsp = &frame[2];
- *sp = (void*)((POINTER_SIZE_INT)frame + 2*sizeof(void*));
- return (*bp != NULL && *ip != NULL);
-}
+ if (native_is_in_stack(context, rsp) &&
+ (native_is_in_code(context, rip) || native_is_ip_stub(rip)))
+ {
+ regs->rbp = (uint64)rbp;
+ regs->rsp = (uint64)rsp;
+ regs->rip = (uint64)rip;
+ return true;
+ }
-void native_get_ip_bp_from_si_jit_context(StackIterator* si, void** ip, void** bp)
-{
- JitFrameContext* jfc = si_get_jit_context(si);
- *ip = (void*)*jfc->p_rip;
- *bp = (void*)*jfc->p_rbp;
+ return false;
}
-void native_get_sp_from_si_jit_context(StackIterator* si, void** sp)
+void native_get_regs_from_jit_context(JitFrameContext* jfc, Registers* regs)
{
- *sp = (void*)si_get_jit_context(si)->rsp;
+ regs->rip = *jfc->p_rip;
+ regs->rbp = *jfc->p_rbp;
+ regs->rsp = jfc->rsp;
}
-bool native_is_out_of_stack(void* value)
+static bool fill_regs_from_sp(WalkContext* context, Registers* regs, void** sp)
{
- // FIXME: Invalid criterion
- return (value < (void*)0x10000) || (value > (void*)0x800000000000);
+ regs->rsp = (uint64)(sp + 1);
+ regs->rip = (uint64)*sp;
+ regs->rbp = native_is_in_stack(context, sp[-1]) ? (uint64)sp[-1] : regs->rsp;
+ return true;
}
-bool native_is_frame_valid(native_module_t* modules, void* bp, void* sp)
+static unsigned native_dec_instr(WalkContext* context, void* addr, void** target)
{
- // Check for frame layout and stack values
- if ((bp < sp) || native_is_out_of_stack(bp))
- return false; // Invalid frame
-
- void** dw_ptr = (void**)bp;
- void* ret_ip = *(dw_ptr + 1); // Return address for frame
-
- // Check return address for meaning
- if (!native_is_ip_in_modules(modules, ret_ip) && !native_is_ip_stub(ret_ip))
- return false;
+ Inst inst;
- return true;
-}
+ if (!native_is_in_code(context, addr))
+ return 0;
-// Searches for correct return address in the stack
-// Returns stack address pointing to return address
-static void** native_search_special_frame(native_module_t* modules, void* sp)
-{
-// Max search depth for return address
-#define MAX_SPECIAL_DEPTH 0x100
+ unsigned len = DecoderBase::decode(addr, &inst);
- POINTER_SIZE_INT sp_begin = (POINTER_SIZE_INT)sp;
- for (POINTER_SIZE_INT sp_int = sp_begin;
- sp_int < sp_begin + MAX_SPECIAL_DEPTH;
- sp_int += 8) // 8 is granularity of stack
- {
- void** sp_pointer = (void**)sp_int;
+ if (len == 0 ||
+ inst.mn != Mnemonic_CALL ||
+ inst.argc != 1)
+ return 0;
- if (native_is_ip_in_modules(modules, *sp_pointer))
- return sp_pointer;
- }
+ if (target && inst.operands[0].is_imm())
+ *target = (void*)((uint64)addr + (uint64)len + inst.operands[0].imm());
- return NULL;
+ return len;
}
-// Tests if stack contains non-BP-based frames on top
-int native_test_unwind_special(native_module_t* modules, void* sp)
+static bool native_check_caller(WalkContext* context, Registers* regs, void** sp)
{
-#define MAX_SPECIAL_COUNT 16
-
-#if (!defined PLATFORM_POSIX)
- return -1; // Because we cannot identify executable code on Windows
-#endif
-
- if (modules == NULL)
- return false;
-
- int count = 0;
- void** sp_pointer = (void**)sp;
-
- do
+ void* target = NULL;
+ char* ptr = (char*)*sp;
+
+ if (native_dec_instr(context, ptr - 2, &target) == 2 || // CALL r/m64 w/o SIB w/o disp
+ native_dec_instr(context, ptr - 3, &target) == 3 || // CALL r/m64 w/ SIB w/o disp
+ native_dec_instr(context, ptr - 4, &target) == 4 || // CALL r/m64 w/ SIB w/ disp8
+ native_dec_instr(context, ptr - 5, &target) == 5 || // CALL rel32
+ native_dec_instr(context, ptr - 6, &target) == 6 || // CALL r/m64 w/o SIB w/ disp32
+ native_dec_instr(context, ptr - 7, &target) == 7 || // CALL r/m64 w/ SIB w/ disp32
+ native_dec_instr(context, ptr - 8, &target) == 8) // CALL r/m64 w/ SIB w/ disp32 + Seg prefix
{
- if (native_is_ip_stub(sp_pointer[-1]))
- break; // We've found JNI stub
-
- // We've reached Java without native stub
- if (vm_identify_eip(sp_pointer[-1]) == VM_TYPE_JAVA)
- break;
-
- void** next_sp = native_search_special_frame(modules, sp_pointer);
-
- if (next_sp == NULL)
- break; // We cannot unwind anymore
+ if (!target)
+ return true;
- if (count > 0 && // Check BP-frame for upper frames
- sp_pointer[-2] >= sp_pointer && // Correct frame layout
- sp_pointer[-2] == next_sp - 1 && // is RBP saved correctly
- next_sp[-1] >= next_sp + 1) // Correct next frame layout
- {
- break;
- }
+ native_module_t* cur_module =
+ find_native_module(context->modules, regs->get_ip());
+ native_module_t* found_module =
+ find_native_module(context->modules, target);
- sp_pointer = next_sp + 1;
-
- } while (++count <= MAX_SPECIAL_COUNT);
+ return (cur_module == found_module);
+ }
- return count;
+ return false;
}
-bool native_unwind_special(native_module_t* modules,
- void* stack, void** ip, void** sp, void** bp, bool is_last)
-{
- if (modules == NULL)
- {
- *ip = NULL;
- return false;
- }
- void** found = NULL;
+// Max search depth for return address
+#define MAX_SPECIAL_DEPTH 0x900
+#define NATIVE_STRICT_UNWINDING 1
- POINTER_SIZE_INT sp_begin = (POINTER_SIZE_INT)stack;
- for (POINTER_SIZE_INT sp_int = sp_begin;
- sp_int < sp_begin + MAX_SPECIAL_DEPTH;
- sp_int += 8) // 8 is granularity of stack
+bool native_unwind_special(WalkContext* context, Registers* regs)
+{
+ for (void** cur_sp = (void**)regs->rsp;
+ (char*)cur_sp < ((char*)regs->rsp + MAX_SPECIAL_DEPTH) && native_is_in_stack(context, cur_sp);
+ ++cur_sp)
{
- void** sp_pointer = (void**)sp_int;
-
- if (native_is_ip_in_modules(modules, *sp_pointer))
- {
- found = sp_pointer;
- break;
- }
- }
+ if (!native_is_in_code(context, *cur_sp))
+ continue;
- if (!found)
- {
- *ip = NULL;
- return false;
+#if (!NATIVE_STRICT_UNWINDING)
+ return fill_regs_from_sp(context, regs, cur_sp);
+#else
+ if (native_check_caller(context, regs, cur_sp))
+ return fill_regs_from_sp(context, regs, cur_sp);
+#endif
}
- *ip = *found;
- *sp = found + 1;
-
- if (is_last && !native_is_ip_stub(*ip))
- *bp = found[-1];
- else
- *bp = *sp;
-
- return true;
+ return false;
}
-void native_unwind_interrupted_frame(jvmti_thread_t thread, void** p_ip, void** p_bp, void** p_sp)
+void native_fill_frame_info(Registers* regs, native_frame_t* frame, jint jdepth)
{
- if (!thread) {
+ frame->java_depth = jdepth;
+
+ if (!regs)
return;
- }
- Registers* pregs = (Registers*)(thread->jvmti_saved_exception_registers);
- *p_ip = (void*)pregs->rip;
- *p_bp = (void*)pregs->rbp;
- *p_sp = (void*)pregs->rsp;
+
+ frame->ip = (void*)regs->rip;
+ frame->frame = (void*)regs->rbp;
+ frame->stack = (void*)regs->rsp;
}
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp Tue Feb 12 09:30:49 2008
@@ -20,176 +20,141 @@
*/
#include "method_lookup.h"
+#include "dec_base.h"
+#include "native_modules.h"
#include "native_stack.h"
-void native_get_frame_info(Registers* regs, void** ip, void** bp, void** sp)
-{
- *ip = (void*)regs->eip;
- *bp = (void*)regs->ebp;
- *sp = (void*)regs->esp;
-}
-
-bool native_unwind_bp_based_frame(void* frame, void** ip, void** bp, void** sp)
-{
- void** frame_ptr = (void**)frame;
-
- *ip = frame_ptr[1];
- *bp = frame_ptr[0];
- // FIXME - wrong value, we cannot get sp anyhow
- *sp = (void*)((POINTER_SIZE_INT)frame + 2*sizeof(void*));
-
- return (*bp != NULL && *ip != NULL);
-}
-
-void native_get_ip_bp_from_si_jit_context(StackIterator* si, void** ip, void** bp)
-{
- JitFrameContext* jfc = si_get_jit_context(si);
- *ip = (void*)*jfc->p_eip;
- *bp = (void*)*jfc->p_ebp;
-}
-
-void native_get_sp_from_si_jit_context(StackIterator* si, void** sp)
-{
- *sp = (void*)si_get_jit_context(si)->esp;
-}
-bool native_is_out_of_stack(void* value)
-{
- // FIXME: Invalid criterion
- return (value < (void*)0x10000) || (value > (void*)0xC0000000);
-}
-
-bool native_is_frame_valid(native_module_t* modules, void* bp, void* sp)
+bool native_is_frame_exists(WalkContext* context, Registers* regs)
{
// Check for frame layout and stack values
- if ((bp < sp) || native_is_out_of_stack(bp))
+ if ((regs->ebp < regs->esp) || !native_is_in_stack(context, (void*)regs->ebp))
return false; // Invalid frame
- void** dw_ptr = (void**)bp;
- void* ret_ip = *(dw_ptr + 1); // Return address for frame
+ void** frame_ptr = (void**)regs->ebp;
+ void* eip = frame_ptr[1]; // Return address
// Check return address for meaning
- if (!native_is_ip_in_modules(modules, ret_ip) && !native_is_ip_stub(ret_ip))
- return false;
-
- return true;
+ return (native_is_in_code(context, eip) || native_is_ip_stub(eip));
}
-// Searches for correct return address in the stack
-// Returns stack address pointing to return address
-static void** native_search_special_frame(native_module_t* modules, void* sp)
+bool native_unwind_stack_frame(WalkContext* context, Registers* regs)
{
-// Max search depth for return address
-#define MAX_SPECIAL_DEPTH 0x40
+ void** frame = (void**)regs->ebp;
+
+ void* ebp = frame[0];
+ void* eip = frame[1];
+// void* esp = (void*)(frame + 2);
+ void* esp = &frame[2];
- POINTER_SIZE_INT sp_begin = (POINTER_SIZE_INT)sp;
- for (POINTER_SIZE_INT sp_int = sp_begin;
- sp_int < sp_begin + MAX_SPECIAL_DEPTH;
- sp_int +=2) // 2 is minimum stack item for ia32
- {
- void** sp_pointer = (void**)sp_int;
- if (native_is_ip_in_modules(modules, *sp_pointer))
- return sp_pointer;
+ if (native_is_in_stack(context, esp) &&
+ (native_is_in_code(context, eip) || native_is_ip_stub(eip)))
+ {
+ regs->ebp = (uint32)ebp;
+ regs->esp = (uint32)esp;
+ regs->eip = (uint32)eip;
+ return true;
}
- return NULL;
+ return false;
}
-// Tests if stack contains non-BP-based frames on top
-int native_test_unwind_special(native_module_t* modules, void* sp)
+void native_get_regs_from_jit_context(JitFrameContext* jfc, Registers* regs)
{
-#define MAX_SPECIAL_COUNT 16
-
-#if (!defined PLATFORM_POSIX)
- return -1; // Because we cannot identify executable code on Windows
-#endif
-
- if (modules == NULL)
- return false;
-
- int count = 0;
- void** sp_pointer = (void**)sp;
-
- do
- {
- if (native_is_ip_stub(sp_pointer[-1]))
- break; // We've found JNI stub
+ regs->eip = *jfc->p_eip;
+ regs->ebp = *jfc->p_ebp;
+ regs->esp = jfc->esp;
+}
- // We've reached Java without native stub
- if (vm_identify_eip(sp_pointer[-1]) == VM_TYPE_JAVA)
- break;
+static bool fill_regs_from_sp(WalkContext* context, Registers* regs, void** sp)
+{
+ regs->esp = (uint32)(sp + 1);
+ regs->eip = (uint32)*sp;
+ regs->ebp = native_is_in_stack(context, sp[-1]) ? (uint32)sp[-1] : regs->esp;
+ return true;
+}
- void** next_sp = native_search_special_frame(modules, sp_pointer);
+static unsigned native_dec_instr(WalkContext* context, void* addr, void** target)
+{
+ Inst inst;
- if (next_sp == NULL)
- break; // We cannot unwind anymore
+ if (!native_is_in_code(context, addr))
+ return 0;
- if (count > 0 && // Check BP-frame for upper frames
- sp_pointer[-2] >= sp_pointer && // Correct frame layout
- sp_pointer[-2] == next_sp - 1 && // is BP saved correctly
- next_sp[-1] >= next_sp + 1) // Correct next frame layout
- {
- break;
- }
+ uint32 len = DecoderBase::decode(addr, &inst);
- sp_pointer = next_sp + 1;
+ if (len == 0 ||
+ inst.mn != Mnemonic_CALL ||
+ inst.argc != 1)
+ return 0;
- } while (++count <= MAX_SPECIAL_COUNT);
+ if (target && inst.operands[0].is_imm())
+ *target = (void*)((uint32)addr + len + inst.operands[0].imm());
- return count;
+ return len;
}
-// Tries to unwind non-BP-based frame
-bool native_unwind_special(native_module_t* modules,
- void* stack, void** ip, void** sp, void** bp, bool is_last)
+static bool native_check_caller(WalkContext* context, Registers* regs, void** sp)
{
- if (modules == NULL)
+ void* target = NULL;
+ char* ptr = (char*)*sp;
+
+ if (native_dec_instr(context, ptr - 2, &target) == 2 || // CALL r/m32 w/o SIB w/o disp
+ native_dec_instr(context, ptr - 3, &target) == 3 || // CALL r/m32 w/ SIB w/o disp
+ native_dec_instr(context, ptr - 4, &target) == 4 || // CALL r/m32 w/ SIB w/ disp8
+ native_dec_instr(context, ptr - 5, &target) == 5 || // CALL rel32
+ native_dec_instr(context, ptr - 6, &target) == 6 || // CALL r/m32 w/o SIB w/ disp32
+ native_dec_instr(context, ptr - 7, &target) == 7 || // CALL r/m32 w/ SIB w/ disp32
+ native_dec_instr(context, ptr - 8, &target) == 8) // CALL r/m32 w/ SIB w/ disp32 + Seg prefix
{
- *ip = NULL;
- return false;
+ if (!target)
+ return true;
+
+ native_module_t* cur_module =
+ find_native_module(context->modules, regs->get_ip());
+ native_module_t* found_module =
+ find_native_module(context->modules, target);
+
+ return (cur_module == found_module);
}
- void** found = NULL;
+ return false;
+}
- POINTER_SIZE_INT sp_begin = (POINTER_SIZE_INT)stack;
- for (POINTER_SIZE_INT sp_int = sp_begin;
- sp_int < sp_begin + MAX_SPECIAL_DEPTH;
- sp_int +=2) // 2 is minimum stack item for ia32
- {
- void** sp_pointer = (void**)sp_int;
- if (native_is_ip_in_modules(modules, *sp_pointer))
- {
- found = sp_pointer;
- break;
- }
- }
+// Max search depth for return address
+#define MAX_SPECIAL_DEPTH 0x400
+#define NATIVE_STRICT_UNWINDING 1
- if (!found)
+bool native_unwind_special(WalkContext* context, Registers* regs)
+{
+ for (void** cur_sp = (void**)regs->esp;
+ (char*)cur_sp < ((char*)regs->esp + MAX_SPECIAL_DEPTH) && native_is_in_stack(context, cur_sp);
+ ++cur_sp)
{
- *ip = NULL;
- return false;
- }
+ if (!native_is_in_code(context, *cur_sp))
+ continue;
- *ip = *found;
- *sp = found + 1;
-
- if (is_last && !native_is_ip_stub(*ip))
- *bp = found[-1];
- else
- *bp = *sp;
+#if (!NATIVE_STRICT_UNWINDING)
+ return fill_regs_from_sp(context, regs, cur_sp);
+#else
+ if (native_check_caller(context, regs, cur_sp))
+ return fill_regs_from_sp(context, regs, cur_sp);
+#endif
+ }
- return true;
+ return false;
}
-void native_unwind_interrupted_frame(jvmti_thread_t thread, void** p_ip, void** p_bp, void** p_sp)
+void native_fill_frame_info(Registers* regs, native_frame_t* frame, jint jdepth)
{
- if (!thread) {
+ frame->java_depth = jdepth;
+
+ if (!regs)
return;
- }
- Registers* pregs = (Registers*)(thread->jvmti_saved_exception_registers);
- *p_ip = (void*)pregs->eip;
- *p_bp = (void*)pregs->ebp;
- *p_sp = (void*)pregs->esp;
+
+ frame->ip = (void*)regs->eip;
+ frame->frame = (void*)regs->ebp;
+ frame->stack = (void*)regs->esp;
}
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/native_stack_ipf.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/native_stack_ipf.cpp?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/native_stack_ipf.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/native_stack_ipf.cpp Tue Feb 12 09:30:49 2008
@@ -21,55 +21,26 @@
#include "native_stack.h"
-void native_get_frame_info(Registers* regs, void** ip, void** bp, void** sp)
-{
- // FIXME: not implemented
-}
-bool native_unwind_bp_based_frame(void* frame, void** ip, void** bp, void** sp)
+bool native_is_frame_exists(WalkContext* UNREF context, Registers* UNREF regs)
{
- return false; // Not implemented
-}
-
-void native_get_ip_bp_from_si_jit_context(StackIterator* si, void** ip, void** bp)
-{ // Not implemented
-}
-
-void native_get_sp_from_si_jit_context(StackIterator* si, void** sp)
-{ // Not implemented
+ return false;
}
-bool native_is_out_of_stack(void* value)
+bool native_unwind_stack_frame(WalkContext* UNREF context, Registers* UNREF regs)
{
- return true; // Not implemented
+ return false;
}
-bool native_is_frame_valid(native_module_t* modules, void* bp, void* sp)
+void native_get_regs_from_jit_context(JitFrameContext* UNREF jfc, Registers* UNREF regs)
{
- return false; // Not implemented
}
-int native_test_unwind_special(native_module_t* modules, void* sp)
+bool native_unwind_special(WalkContext* UNREF context, Registers* UNREF regs)
{
- return false; // Not implemented
+ return false;
}
-bool native_unwind_special(native_module_t* modules,
- void* stack, void** ip, void** sp, void** bp, bool is_last)
+void native_fill_frame_info(Registers* UNREF regs, native_frame_t* UNREF frame, jint UNREF jdepth)
{
- return false; // Not implemented
}
-
-void native_unwind_interrupted_frame(jvmti_thread_t thread, void** p_ip, void** p_bp, void** p_sp)
-{ // Not implemented yet
- *p_ip = NULL;
- *p_bp = NULL;
- *p_sp = NULL;
-}
-
-void si_set_callbak(StackIterator* si, NativeCodePtr* callback) {
- // FIXME: not implemented
- assert(0);
- abort();
-}
-
Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_stack_os.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_stack_os.cpp?rev=620872&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_stack_os.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_stack_os.cpp Tue Feb 12 09:30:49 2008
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <pthread.h>
+#include "native_modules.h"
+#include "native_stack.h"
+
+
+bool native_is_in_code(WalkContext* context, void* ip)
+{
+ if (!ip)
+ return false;
+
+ for (native_module_t* module = context->modules; module; module = module->next)
+ {
+ for (size_t i = 0; i < module->seg_count; i++)
+ {
+ char* base = (char*)module->segments[i].base;
+
+ if (ip >= base &&
+ ip < (base + module->segments[i].size))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool native_get_stack_range(WalkContext* context, Registers* regs, native_segment_t* seg)
+{
+ int err;
+ pthread_attr_t pthread_attr;
+
+ pthread_t thread = pthread_self();
+ void* sp = regs->get_sp();
+
+ if (pthread_attr_init(&pthread_attr) != 0)
+ return false;
+
+#if defined(FREEBSD)
+ err = pthread_attr_get_np(thread, &pthread_attr);
+#else
+ err = pthread_getattr_np(thread, &pthread_attr);
+#endif
+
+ if (err != 0)
+ return false;
+
+ if (pthread_attr_getstack(&pthread_attr, &seg->base, &seg->size))
+ return false;
+
+ pthread_attr_destroy(&pthread_attr);
+ return true;
+
+/* for (native_module_t* module = context->modules; module; module = module->next)
+ {
+ for (size_t i = 0; i < module->seg_count; i++)
+ {
+ char* base = (char*)module->segments[i].base;
+
+ if (sp >= base &&
+ sp < (base + module->segments[i].size))
+ {
+ *seg = module->segments[i];
+ return true;
+ }
+ }
+ }
+
+ return false;
+*/
+}
Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_stack_os.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp Tue Feb 12 09:30:49 2008
@@ -33,52 +33,9 @@
#include "native_stack.h"
-
-// Global lock used for locking module list access
-static Lock_Manager g_list_lock;
-
-
//////////////////////////////////////////////////////////////////////////////
/// Helper functions
-static bool get_modules(native_module_t** pmodules)
-{
- assert(pmodules);
-
- if (*pmodules != NULL)
- return true;
-
- int mod_count;
- native_module_t* mod_list = NULL;
-
- LMAutoUnlock aulock(&g_list_lock);
-
- bool result = get_all_native_modules(&mod_list, &mod_count);
-
- if (!result)
- return false;
-
- *pmodules = mod_list;
- return true;
-}
-
-bool native_is_ip_in_modules(native_module_t* modules, void* ip)
-{
- for (native_module_t* module = modules; module; module = module->next)
- {
- for (size_t i = 0; i < module->seg_count; i++)
- {
- char* base = (char*)module->segments[i].base;
-
- if (ip >= base &&
- ip < (base + module->segments[i].size))
- return true;
- }
- }
-
- return false;
-}
-
static DynamicCode* native_find_stub(void* ip)
{
for (DynamicCode *dcList = compile_get_dynamic_code_list();
@@ -111,6 +68,12 @@
return buf;
}
+bool native_is_in_stack(WalkContext* context, void* sp)
+{
+ return (sp >= context->stack.base &&
+ sp < (char*)context->stack.base + context->stack.size);
+}
+
bool native_is_ip_stub(void* ip)
{
// Synchronizing access to dynamic code list
@@ -131,54 +94,108 @@
//////////////////////////////////////////////////////////////////////////////
//
-static int walk_native_stack_jit(Registers* pregs, VM_thread* pthread,
+bool native_init_walk_context(WalkContext* context, native_module_t* modules, Registers* regs)
+{
+ if (!context)
+ return false;
+
+ if (!modules)
+ {
+ int mod_count;
+ native_module_t* mod_list = NULL;
+
+ if (!get_all_native_modules(&mod_list, &mod_count))
+ return false;
+
+ context->clean_modules = true;
+ context->modules = mod_list;
+ }
+ else
+ {
+ context->clean_modules = false;
+ context->modules = modules;
+ }
+
+ if (!native_get_stack_range(context, regs, &context->stack))
+ {
+ if (context->clean_modules)
+ clear_native_modules(&context->modules);
+ return false;
+ }
+
+ return true;
+}
+
+void native_clean_walk_context(WalkContext* context)
+{
+ if (!context)
+ return;
+
+ if (context->modules && context->clean_modules)
+ {
+ clear_native_modules(&context->modules);
+ }
+
+ context->modules = NULL;
+}
+
+
+static int walk_native_stack_jit(
+ WalkContext* context,
+ Registers* pregs, VM_thread* pthread,
int max_depth, native_frame_t* frame_array);
-static int walk_native_stack_pure(Registers* pregs,
+static int walk_native_stack_pure(
+ WalkContext* context, Registers* pregs,
int max_depth, native_frame_t* frame_array);
-static int walk_native_stack_interpreter(Registers* pregs, VM_thread* pthread,
+static int walk_native_stack_interpreter(
+ WalkContext* context,
+ Registers* pregs, VM_thread* pthread,
int max_depth, native_frame_t* frame_array);
-int walk_native_stack_registers(Registers* pregs,
+int walk_native_stack_registers(WalkContext* context, Registers* pregs,
VM_thread* pthread, int max_depth, native_frame_t* frame_array)
{
if (pthread == NULL) // Pure native thread
- return walk_native_stack_pure(pregs, max_depth, frame_array);
+ return walk_native_stack_pure(context, pregs, max_depth, frame_array);
if (interpreter_enabled())
- return walk_native_stack_interpreter(pregs, pthread, max_depth, frame_array);
+ return walk_native_stack_interpreter(context, pregs,
+ pthread, max_depth, frame_array);
- return walk_native_stack_jit(pregs, pthread, max_depth, frame_array);
+ return walk_native_stack_jit(context, pregs, pthread, max_depth, frame_array);
+ return 0;
}
-static int walk_native_stack_jit(Registers* pregs, VM_thread* pthread,
+static int walk_native_stack_jit(
+ WalkContext* context,
+ Registers* pregs, VM_thread* pthread,
int max_depth, native_frame_t* frame_array)
{
- // These vars store current frame context for each iteration
- void *ip, *bp, *sp;
- // To translate platform-dependant info; we will use ip from here
- native_get_frame_info(pregs, &ip, &bp, &sp);
+ // Register context for current frame
+ Registers regs = *pregs;
int frame_count = 0;
// Search for method containing corresponding address
- VM_Code_Type code_type = vm_identify_eip(ip);
+ VM_Code_Type code_type = vm_identify_eip(regs.get_ip());
bool flag_dummy_frame = false;
jint java_depth = 0;
StackIterator* si = NULL;
bool is_java = false;
- native_module_t* modules = NULL;
if (code_type == VM_TYPE_JAVA)
{ // We must add dummy M2N frame to start SI iteration
- assert(pthread);
+ if (!pthread)
+ return 0;
+
is_java = true;
M2nFrame* lm2n = m2n_get_last_frame(pthread);
- if (!m2n_is_suspended_frame(lm2n) || m2n_get_ip(lm2n) != ip)
+ if (!m2n_is_suspended_frame(lm2n) || m2n_get_ip(lm2n) != regs.get_ip())
{ // We should not push frame if it was pushed by breakpoint handler
- m2n_push_suspended_frame(pthread, pregs);
+ m2n_push_suspended_frame(pthread, ®s);
flag_dummy_frame = true;
}
}
@@ -206,12 +223,8 @@
if (frame_array)
{ // If frames requested, store current frame
- frame_array[frame_count].java_depth =
- is_java ? java_depth : -1;
-
- frame_array[frame_count].ip = ip;
- frame_array[frame_count].frame = bp;
- frame_array[frame_count].stack = sp;
+ native_fill_frame_info(®s, &frame_array[frame_count],
+ is_java ? java_depth : -1);
}
++frame_count;
@@ -221,7 +234,8 @@
if (is_java) //code_type == VM_TYPE_JAVA
{ // Go to previous frame using StackIterator
cci = si_get_code_chunk_info(si);
- assert(cci); // Java method should contain cci
+ if (!cci) // Java method should contain cci
+ break;
// if (inline_index < 0) we have new si
// (inline_index < inline_count) we must process inline
@@ -246,22 +260,22 @@
inline_index = -1;
// 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);
+ native_get_regs_from_jit_context(si_get_jit_context(si), ®s);
}
- code_type = vm_identify_eip(ip);
+ code_type = vm_identify_eip(regs.get_ip());
is_java = (code_type == VM_TYPE_JAVA);
continue;
}
// ^^ Java ^^
/////////////////////////
// vv Native vv
- is_stub = native_is_ip_stub(ip);
+ is_stub = native_is_ip_stub(regs.get_ip());
if (is_stub)
{ // Native stub, previous frame is Java frame
- assert(si_is_native(si));
+ if (!si_is_native(si))
+ break;
if (si_get_method(si)) // Frame represents JNI frame
{
@@ -278,60 +292,38 @@
// Ge to previous stack frame from StackIterator
si_goto_previous(si);
// Let's get context from si
- native_get_ip_bp_from_si_jit_context(si, &ip, &bp);
- native_get_sp_from_si_jit_context(si, &sp);
+ native_get_regs_from_jit_context(si_get_jit_context(si), ®s);
}
else
{
- if (!modules && !get_modules(&modules))
- break;
-
- if (native_is_frame_valid(modules, bp, sp))
- { // Simply bp-based frame, let's unwind it
- 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->jvmti_thread, &ip, &bp, &sp);
- flag_breakpoint = true;
- }
- else
- {
- ip = tmp_ip;
- bp = tmp_bp;
- sp = tmp_sp;
- }
+ Registers tmp_regs = regs;
- vm_breaks->unlock();
+ if (native_is_frame_exists(context, &tmp_regs))
+ { // Stack frame (x86)
+ if (!native_unwind_stack_frame(context, &tmp_regs))
+ break;
}
else
- { // Is not bp-based frame
- if (frame_count == 1)
- { // For first frame, test special unwinding possibility
- special_count = native_test_unwind_special(modules, sp);
- if (special_count <= 0)
- ip = NULL;
- }
-
- if (frame_count <= special_count)
- { // Specially unwind first native frames
- bool res = native_unwind_special(modules,
- sp, &ip, &sp, &bp,
- frame_count == special_count);
-
- if (!res)
- break; // Unwinding failed
- }
- else
- break; // There is another invalid frame in the stack
+ { // Stack frame does not exist, try using heuristics
+ if (!native_unwind_special(context, &tmp_regs))
+ break;
}
+
+ VMBreakPoints* vm_breaks = VM_Global_State::loader_env->TI->vm_brpt;
+ vm_breaks->lock();
+
+ if (native_is_ip_in_breakpoint_handler(tmp_regs.get_ip()))
+ {
+ regs = *pthread->jvmti_thread.jvmti_saved_exception_registers;
+ flag_breakpoint = true;
+ }
+ else
+ regs = tmp_regs;
+
+ vm_breaks->unlock();
}
- code_type = vm_identify_eip(ip);
+ code_type = vm_identify_eip(regs.get_ip());
is_java = (code_type == VM_TYPE_JAVA);
// If we've reached Java without native stub (or breakpoint handler frame)
@@ -355,18 +347,16 @@
}
-static int walk_native_stack_pure(Registers* pregs,
+static int walk_native_stack_pure(
+ WalkContext* context, Registers* pregs,
int max_depth, native_frame_t* frame_array)
{
- // These vars store current frame context for each iteration
- void *ip, *bp, *sp;
- // To translate platform-dependant info; we will use ip from here
- native_get_frame_info(pregs, &ip, &bp, &sp);
- assert(vm_identify_eip(ip) != VM_TYPE_JAVA);
+ // Register context for current frame
+ Registers regs = *pregs;
+ if (vm_identify_eip(regs.get_ip()) == VM_TYPE_JAVA)
+ return 0;
int frame_count = 0;
- int special_count = 0;
- native_module_t* modules = NULL;
while (1)
{
@@ -375,40 +365,22 @@
if (frame_array)
{ // If frames requested, store current frame
- frame_array[frame_count].java_depth = -1;
- frame_array[frame_count].ip = ip;
- frame_array[frame_count].frame = bp;
- frame_array[frame_count].stack = sp;
+ native_fill_frame_info(®s, &frame_array[frame_count], -1);
}
++frame_count;
- if (!modules && !get_modules(&modules))
- break;
-
- // Simply bp-based frame, let's unwind it
- if (native_is_frame_valid(modules, bp, sp))
- {
+ if (native_is_frame_exists(context, ®s))
+ { // Stack frame (x86)
// Here must be special processing for breakpoint handler frames
// But it requires VM_thread structure attached to thread
// TODO: Investigate possibility
- native_unwind_bp_based_frame(bp, &ip, &bp, &sp);
+ if (!native_unwind_stack_frame(context, ®s))
+ break;
}
else
- { // Wrong frame
- if (frame_count == 1)
- { // For first frame, test special unwinding possibility
- special_count = native_test_unwind_special(modules, sp);
- if (special_count <= 0)
- break;
- }
-
- if (frame_count <= special_count)
- { // Specially unwind first native frames
- native_unwind_special(modules, sp, &ip, &sp, &bp,
- frame_count == special_count);
- }
- else // There is another invalid frame in the stack
+ { // Stack frame does not exist, try using heuristics
+ if (!native_unwind_special(context, ®s))
break;
}
}
@@ -417,13 +389,13 @@
}
-static int walk_native_stack_interpreter(Registers* pregs, VM_thread* pthread,
+static int walk_native_stack_interpreter(
+ WalkContext* context,
+ Registers* pregs, VM_thread* pthread,
int max_depth, native_frame_t* frame_array)
{
- // These vars store current frame context for each iteration
- void *ip, *bp, *sp;
- // To translate platform-dependant info; we will use ip from here
- native_get_frame_info(pregs, &ip, &bp, &sp);
+ // Register context for current frame
+ Registers regs = *pregs;
assert(pthread);
FrameHandle* last_frame = interpreter.interpreter_get_last_frame(pthread);
@@ -431,8 +403,6 @@
int frame_count = 0;
jint java_depth = 0;
- int special_count = 0;
- native_module_t* modules = NULL;
while (1)
{
@@ -441,60 +411,37 @@
if (frame_array)
{ // If frames requested, store current frame
- frame_array[frame_count].java_depth = -1;
- frame_array[frame_count].ip = ip;
- frame_array[frame_count].frame = bp;
- frame_array[frame_count].stack = sp;
+ native_fill_frame_info(®s, &frame_array[frame_count], -1);
}
++frame_count;
// Store previous value to identify frame range later
- void* prev_sp = sp;
+ void* prev_sp = regs.get_sp();
+ Registers tmp_regs = regs;
- if (!modules && !get_modules(&modules))
- break;
-
- if (native_is_frame_valid(modules, bp, sp))
- { // Simply bp-based frame, let's unwind it
- void *tmp_ip, *tmp_bp, *tmp_sp;
- native_unwind_bp_based_frame(bp, &tmp_ip, &tmp_bp, &tmp_sp);
+ if (native_is_frame_exists(context, &tmp_regs))
+ { // Stack frame (x86)
+ if (!native_unwind_stack_frame(context, &tmp_regs))
+ break;
+ }
+ else
+ { // Stack frame does not exist, try using heuristics
+ if (!native_unwind_special(context, &tmp_regs))
+ break;
+ }
- VMBreakPoints* vm_breaks = VM_Global_State::loader_env->TI->vm_brpt;
- vm_breaks->lock();
+ 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->jvmti_thread, &ip, &bp, &sp);
- }
- else
- {
- ip = tmp_ip;
- bp = tmp_bp;
- sp = tmp_sp;
- }
-
- vm_breaks->unlock();
- }
+ if (native_is_ip_in_breakpoint_handler(tmp_regs.get_ip()))
+ regs = *pthread->jvmti_thread.jvmti_saved_exception_registers;
else
- { // Is not bp-based frame
- if (frame_count == 1)
- { // For first frame, test special unwinding possibility
- special_count = native_test_unwind_special(modules, sp);
- if (special_count <= 0)
- break;
- }
+ regs = tmp_regs;
- if (frame_count <= special_count)
- { // Specially unwind first native frames
- native_unwind_special(modules, sp, &ip, &sp, &bp,
- frame_count == special_count);
- }
- else
- break; // There is another invalid frame in the stack
- }
+ vm_breaks->unlock();
- bool is_java = interpreter.is_frame_in_native_frame(frame, prev_sp, sp);
+ bool is_java = interpreter.is_frame_in_native_frame(frame, prev_sp, regs.get_sp());
if (is_java)
{
Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_stack_os.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_stack_os.cpp?rev=620872&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_stack_os.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_stack_os.cpp Tue Feb 12 09:30:49 2008
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "native_modules.h"
+#include "native_stack.h"
+
+
+bool native_is_in_code(WalkContext* context, void* ip)
+{
+ if (!ip)
+ return false;
+
+ MEMORY_BASIC_INFORMATION mem_info;
+
+ if (VirtualQuery(ip, &mem_info, sizeof(mem_info)) == 0)
+ return false;
+
+ if (mem_info.State != MEM_COMMIT)
+ return false;
+
+ return ((mem_info.Protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ |
+ PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) != 0);
+}
+
+bool native_get_stack_range(WalkContext* context, Registers* regs, native_segment_t* seg)
+{
+ MEMORY_BASIC_INFORMATION mem_info;
+
+ if (VirtualQuery(regs->get_sp(), &mem_info, sizeof(mem_info)) == 0)
+ return false;
+
+ if (mem_info.State != MEM_COMMIT)
+ return false;
+
+ seg->base = mem_info.BaseAddress;
+ seg->size = mem_info.RegionSize;
+ return true;
+}
Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_stack_os.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Re: [drlvm][signals] New heuristics for crash handler
Posted by Ilya Berezhniuk <il...@gmail.com>.
Tim,
As an author of the patch, I confirm that these changes affect the
code working in case of crash.
The only change affecting general VM code is the following one-line change:
- {OpcodeInfo::em64t, {REX_W, 0xFF, _2}, {r_m64}, U },
+ {OpcodeInfo::em64t, {0xFF, _2}, {r_m64}, U },
Both Intel and AMD specs say that REX prefix is not required here - so
I hope this change is harmless too.
Thanks,
Ilya.
2008/2/12, Tim Ellison <t....@gmail.com>:
> Gregory Shimansky wrote:
> > Tim Ellison said the following on 12.02.2008 22:32:
> >> Gregory,
> >>
> >> Is this appropriate during feature freeze? Looks like significant new
> >> functionality.
> >
> > Oh. I didn't realize the _feature_ freeze started up already! I only
> > remembered the date 15th of February from your email. I must have not
> > read it carefully enough. The good thing is that this is not a _feature_
> > per say since crash handler had problems printing good stack traces on
> > x86_64, so it could be called a bug to some extent. On the other hand,
> > if I was aware about the freeze, I'd hold on committing such big change.
> >
> >> Do you guarantee all this code going to work perfectly ?! <g>
> >
> > Well, the code in question is targeted to work only in case of a crash
> > which shouldn't happen in the first place. So I hope it is not critical
> > for general stability. If any regression is noticed, I'll revert this
> > commit.
>
> np -- at least you know there is a feature freeze on now. Sorry for not
> making it clear.
>
> Regards,
> Tim
>
Re: [drlvm][signals] New heuristics for crash handler
Posted by Tim Ellison <t....@gmail.com>.
Gregory Shimansky wrote:
> Tim Ellison said the following on 12.02.2008 22:32:
>> Gregory,
>>
>> Is this appropriate during feature freeze? Looks like significant new
>> functionality.
>
> Oh. I didn't realize the _feature_ freeze started up already! I only
> remembered the date 15th of February from your email. I must have not
> read it carefully enough. The good thing is that this is not a _feature_
> per say since crash handler had problems printing good stack traces on
> x86_64, so it could be called a bug to some extent. On the other hand,
> if I was aware about the freeze, I'd hold on committing such big change.
>
>> Do you guarantee all this code going to work perfectly ?! <g>
>
> Well, the code in question is targeted to work only in case of a crash
> which shouldn't happen in the first place. So I hope it is not critical
> for general stability. If any regression is noticed, I'll revert this
> commit.
np -- at least you know there is a feature freeze on now. Sorry for not
making it clear.
Regards,
Tim
Re: [drlvm][signals] New heuristics for crash handler
Posted by Gregory Shimansky <gs...@apache.org>.
Tim Ellison said the following on 12.02.2008 22:32:
> Gregory,
>
> Is this appropriate during feature freeze? Looks like significant new
> functionality.
Oh. I didn't realize the _feature_ freeze started up already! I only
remembered the date 15th of February from your email. I must have not
read it carefully enough. The good thing is that this is not a _feature_
per say since crash handler had problems printing good stack traces on
x86_64, so it could be called a bug to some extent. On the other hand,
if I was aware about the freeze, I'd hold on committing such big change.
> Do you guarantee all this code going to work perfectly ?! <g>
Well, the code in question is targeted to work only in case of a crash
which shouldn't happen in the first place. So I hope it is not critical
for general stability. If any regression is noticed, I'll revert this
commit.
> gshimansky@apache.org wrote:
>> Author: gshimansky
>> Date: Tue Feb 12 09:30:49 2008
>> New Revision: 620872
>>
>> URL: http://svn.apache.org/viewvc?rev=620872&view=rev
>> Log:
>> Applied patch from HARMONY-5490
>> [drlvm][signals] New heuristics for crash handler
>>
>>
>> Added:
>>
>> harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_stack_os.cpp
>> (with props)
>>
>> harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_stack_os.cpp
>> (with props)
>> Modified:
>>
>> harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.cpp
>>
>> harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp
>>
>> harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp
>>
>> harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_stack.h
>> harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_internal.h
>> harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h
>> harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_stack.cpp
>> harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp
>>
>> harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp
>>
>>
>> harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp
>>
>>
>> harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/native_stack_ipf.cpp
>>
>> harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp
[drlvm][signals] New heuristics for crash handler
Posted by Tim Ellison <t....@gmail.com>.
Gregory,
Is this appropriate during feature freeze? Looks like significant new
functionality.
Do you guarantee all this code going to work perfectly ?! <g>
Regards,
Tim
gshimansky@apache.org wrote:
> Author: gshimansky
> Date: Tue Feb 12 09:30:49 2008
> New Revision: 620872
>
> URL: http://svn.apache.org/viewvc?rev=620872&view=rev
> Log:
> Applied patch from HARMONY-5490
> [drlvm][signals] New heuristics for crash handler
>
>
> Added:
> harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_stack_os.cpp (with props)
> harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_stack_os.cpp (with props)
> Modified:
> harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.cpp
> harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp
> harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp
> harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_stack.h
> harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_internal.h
> harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h
> harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_stack.cpp
> harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp
> harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp
> harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp
> harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/native_stack_ipf.cpp
> harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp