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/18 12:31:10 UTC

svn commit: r638327 [4/5] - in /harmony/enhanced/drlvm/trunk: make/vm/ vm/em/src/ vm/gc_gen/src/common/ vm/include/open/ vm/interpreter/src/ vm/port/include/ vm/port/src/crash_handler/ vm/port/src/crash_handler/em64t/ vm/port/src/crash_handler/ia32/ vm...

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp?rev=638327&r1=638326&r2=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp Tue Mar 18 04:31:02 2008
@@ -24,6 +24,7 @@
 
 #define LOG_DOMAIN "jvmti"
 #include "cxxlog.h"
+#include "port_mutex.h"
 
 #include "open/gc.h"
 #include "jvmti_direct.h"
@@ -87,14 +88,14 @@
     TIEventThread *et = p_env->event_threads[event_type - JVMTI_MIN_EVENT_TYPE_VAL];
 
     // protect event_threads collection
-    hymutex_lock(&(p_env->environment_data_lock));
+    port_mutex_lock(&(p_env->environment_data_lock));
 
     // Find out if this environment is already registered on this thread on this event type
     while (NULL != et)
     {
         if (et->thread == p_thread)
         {
-            hymutex_unlock(&(p_env->environment_data_lock));
+            port_mutex_unlock(&(p_env->environment_data_lock));
             return JVMTI_ERROR_NONE;
         }
         et = et->next;
@@ -104,7 +105,7 @@
     jvmtiError errorCode = _allocate(sizeof(TIEventThread), (unsigned char **)&newet);
     if (JVMTI_ERROR_NONE != errorCode)
     {
-        hymutex_unlock(&(p_env->environment_data_lock));
+        port_mutex_unlock(&(p_env->environment_data_lock));
         return errorCode;
     }
     newet->thread = p_thread;
@@ -116,7 +117,7 @@
     p_env->event_threads[event_type - JVMTI_MIN_EVENT_TYPE_VAL] = newet;
 
     // free environment lock
-    hymutex_unlock(&(p_env->environment_data_lock));
+    port_mutex_unlock(&(p_env->environment_data_lock));
     return JVMTI_ERROR_NONE;
 }
 
@@ -130,14 +131,14 @@
         return;
 
     // protect event_threads collection
-    hymutex_lock(&(p_env->environment_data_lock));
+    port_mutex_lock(&(p_env->environment_data_lock));
 
     if (et->thread == p_thread)
     {
         VM_Global_State::loader_env->TI->removeEventSubscriber(event_type);
         p_env->event_threads[event_type - JVMTI_MIN_EVENT_TYPE_VAL] = et->next;
         _deallocate((unsigned char *)et);
-        hymutex_unlock(&(p_env->environment_data_lock));
+        port_mutex_unlock(&(p_env->environment_data_lock));
         return;
     }
 
@@ -150,36 +151,36 @@
             TIEventThread *oldet = et->next;
             et->next = oldet->next;
             _deallocate((unsigned char *)oldet);
-            hymutex_unlock(&(p_env->environment_data_lock));
+            port_mutex_unlock(&(p_env->environment_data_lock));
             return;
         }
         et = et->next;
     }
 
     // release protection
-    hymutex_unlock(&(p_env->environment_data_lock));
+    port_mutex_unlock(&(p_env->environment_data_lock));
 }
 
 void add_event_to_global(jvmtiEnv *env, jvmtiEvent event_type)
 {
     TIEnv *p_env = (TIEnv *)env;
-    hymutex_lock(&(p_env->environment_data_lock));
+    port_mutex_lock(&(p_env->environment_data_lock));
     if(!p_env->global_events[event_type - JVMTI_MIN_EVENT_TYPE_VAL]) {
         VM_Global_State::loader_env->TI->addEventSubscriber(event_type);
     }
     p_env->global_events[event_type - JVMTI_MIN_EVENT_TYPE_VAL] = true;
-    hymutex_unlock(&(p_env->environment_data_lock));
+    port_mutex_unlock(&(p_env->environment_data_lock));
 }
 
 void remove_event_from_global(jvmtiEnv *env, jvmtiEvent event_type)
 {
     TIEnv *p_env = (TIEnv *)env;
-    hymutex_lock(&(p_env->environment_data_lock));
+    port_mutex_lock(&(p_env->environment_data_lock));
     if(p_env->global_events[event_type - JVMTI_MIN_EVENT_TYPE_VAL]) {
         VM_Global_State::loader_env->TI->removeEventSubscriber(event_type);
     }
     p_env->global_events[event_type - JVMTI_MIN_EVENT_TYPE_VAL] = false;
-    hymutex_unlock(&(p_env->environment_data_lock));
+    port_mutex_unlock(&(p_env->environment_data_lock));
 }
 
 // disable all events except VM_DEATH
@@ -2363,17 +2364,17 @@
     assert(hythread_is_suspend_enabled());
 
     // create wait loop environment
-    hymutex_t event_mutex;
-    UNREF IDATA stat = hymutex_create(&event_mutex, TM_MUTEX_NESTED);
+    osmutex_t event_mutex;
+    UNREF IDATA stat = port_mutex_create(&event_mutex, APR_THREAD_MUTEX_NESTED);
     assert(stat == TM_ERROR_NONE);
     stat = hycond_create(&ti->event_cond);
     assert(stat == TM_ERROR_NONE);
 
     // event thread loop
     while(true) {
-        hymutex_lock(&event_mutex);
+        port_mutex_lock(&event_mutex);
         hycond_wait(&ti->event_cond, &event_mutex);
-        hymutex_unlock(&event_mutex);
+        port_mutex_unlock(&event_mutex);
 
         if(!ti->event_thread) {
             // event thread is NULL,
@@ -2386,7 +2387,7 @@
     }
 
     // release wait loop environment
-    stat = hymutex_destroy(&event_mutex);
+    stat = port_mutex_destroy(&event_mutex);
     assert(stat == TM_ERROR_NONE);
     stat = hycond_destroy(&ti->event_cond);
     assert(stat == TM_ERROR_NONE);

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_heap.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_heap.cpp?rev=638327&r1=638326&r2=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_heap.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_heap.cpp Tue Mar 18 04:31:02 2008
@@ -23,6 +23,7 @@
  */
 
 #include "cxxlog.h"
+#include "port_mutex.h"
 
 #include "jvmti_direct.h"
 #include "jvmti_utils.h"
@@ -124,11 +125,11 @@
         return JVMTI_ERROR_INVALID_OBJECT;
 
     if (ti_env->tags == NULL) {
-        hymutex_lock(&ti_env->environment_data_lock);
+        port_mutex_lock(&ti_env->environment_data_lock);
         if (ti_env->tags == NULL) {
             ti_env->tags = new TITags;
         }
-        hymutex_unlock(&ti_env->environment_data_lock);
+        port_mutex_unlock(&ti_env->environment_data_lock);
     }
 
     if (ti_env->tags == NULL) {

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp?rev=638327&r1=638326&r2=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp Tue Mar 18 04:31:02 2008
@@ -19,6 +19,7 @@
  * @version $Revision: $
  */
 
+#include "port_crash_handler.h"
 #include "jvmti.h"
 #include "Class.h"
 #include "cxxlog.h"
@@ -104,8 +105,7 @@
         // Another thread could have instrumented this location for
         // prediction of invokevirtual or invokeinterface, so it is
         // necessary to check that location may be instrumented
-        uint8 b = *((uint8 *)ip);
-        if (b == INSTRUMENTATION_BYTE)
+        if (port_is_breakpoint_set(ip))
         {
             bp = vm_brpt->find_breakpoint(ip);
             assert(bp);

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_memory.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_memory.cpp?rev=638327&r1=638326&r2=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_memory.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_memory.cpp Tue Mar 18 04:31:02 2008
@@ -4,6 +4,7 @@
  */
 #define LOG_DOMAIN "ncai.memory"
 #include "cxxlog.h"
+#include "port_memaccess.h"
 #include "jvmti_break_intf.h"
 #include "environment.h"
 #include "jvmti_internal.h"
@@ -36,10 +37,10 @@
     if (!env)
         return NCAI_ERROR_INVALID_ENVIRONMENT;
 
-    ncaiError err = ncai_read_memory(addr, size, buf);
+    int err = port_read_memory(addr, size, buf);
 
-    if (err != NCAI_ERROR_NONE)
-        return err;
+    if (err != 0)
+        return NCAI_ERROR_ACCESS_DENIED;
 
     // Restore bytes changed by JVMTI/NCAI breakpoints
     VMBreakPoints* vm_breaks = VM_Global_State::loader_env->TI->vm_brpt;
@@ -86,7 +87,12 @@
 
     // Simple case: there are no breakpoints in specified address range
     if (rewrite_count == 0)
-        return ncai_write_memory(addr, size, buf);
+    {
+        if (port_write_memory(addr, size, buf) == 0)
+            return NCAI_ERROR_NONE;
+        else
+            return NCAI_ERROR_ACCESS_DENIED;
+    }
 
     // Allocate array for address sorting
     RewriteArray rwa;
@@ -114,7 +120,7 @@
     assert(cur_bla);
     jbyte* cbuf = (jbyte*)buf;
     jbyte* cur_addr = (jbyte*)addr;
-    ncaiError err = NCAI_ERROR_NONE;
+    int err = 0;
 
     while (remain)
     {
@@ -123,9 +129,9 @@
             size_t offset = (size_t)cur_addr - (size_t)addr;
             size_t chunk_size = cur_bla ? ((jbyte*)cur_bla->bp->addr - cur_addr)
                                         : (end_addr - cur_addr);
-            err = ncai_write_memory(cur_addr, chunk_size, cbuf + offset);
+            err = port_write_memory(cur_addr, chunk_size, cbuf + offset);
 
-            if (err != NCAI_ERROR_NONE)
+            if (err != 0)
                 break;
 
             cur_addr += chunk_size;
@@ -145,7 +151,7 @@
     }
 
     STD_FREE(rwa.array);
-    return err;
+    return (err == 0) ? NCAI_ERROR_NONE : NCAI_ERROR_ACCESS_DENIED;
 }
 
 // Adding sorted item into rewrite list

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_modules.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_modules.cpp?rev=638327&r1=638326&r2=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_modules.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_modules.cpp Tue Mar 18 04:31:02 2008
@@ -11,7 +11,7 @@
 #include "cxxlog.h"
 #include "environment.h"
 #include "natives_support.h"
-#include "native_modules.h"
+#include "port_modules.h"
 #include "open/hythread_ext.h"
 #include "ncai_utils.h"
 #include "ncai_direct.h"
@@ -459,7 +459,7 @@
 static bool
 compare_modules_by_short_name(ncaiModule module, const char* sh_name)
 {
-    char buf[_MAX_PATH + 1];
+    char buf[PORT_PATH_MAX + 1];
 
     if (short_name(module->info->filename, buf) == NULL)
         return false; // Error case
@@ -471,7 +471,7 @@
 // Must be called under modules lock
 static ncaiModule find_module_by_name(ncaiModule modules, const char* name)
 {
-    char name_buf[_MAX_PATH + 1];
+    char name_buf[PORT_PATH_MAX + 1];
 
     if (short_name(name, name_buf) == NULL)
         return NULL;

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_signals.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_signals.cpp?rev=638327&r1=638326&r2=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_signals.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_signals.cpp Tue Mar 18 04:31:02 2008
@@ -8,12 +8,29 @@
 #include "suspend_checker.h"
 #include "jvmti_internal.h"
 #include "environment.h"
+#include "port_crash_handler.h"
 
 #include "ncai_utils.h"
 #include "ncai_direct.h"
 #include "ncai_internal.h"
 
 
+struct st_signal_info
+{
+    jint    signal;
+    char*   name;
+    size_t  name_size;
+};
+
+static size_t ncai_get_signal_count();
+static st_signal_info* find_signal(jint sig);
+static jint ncai_get_min_signal();
+static jint ncai_get_max_signal();
+static char* ncai_get_signal_name(jint signal);
+static size_t ncai_get_signal_name_size(jint signal);
+bool ncai_is_signal_in_range(jint signal);
+
+
 ncaiError JNICALL
 ncaiGetSignalCount(ncaiEnv *env, jint* count_ptr)
 {
@@ -130,4 +147,89 @@
             }
         }
     }
+}
+
+
+
+#define STR_AND_SIZE(_x_) _x_, (strlen(_x_) + 1)
+
+static st_signal_info sig_table[] = {
+    {PORT_SIGNAL_GPF,           STR_AND_SIZE("PORT_SIGNAL_GPF")},
+    {PORT_SIGNAL_STACK_OVERFLOW,STR_AND_SIZE("PORT_SIGNAL_STACK_OVERFLOW")},
+    {PORT_SIGNAL_ABORT,         STR_AND_SIZE("PORT_SIGNAL_ABORT")},
+    {PORT_SIGNAL_QUIT,          STR_AND_SIZE("PORT_SIGNAL_QUIT")},
+    {PORT_SIGNAL_CTRL_BREAK,    STR_AND_SIZE("PORT_SIGNAL_CTRL_BREAK")},
+    {PORT_SIGNAL_CTRL_C,        STR_AND_SIZE("PORT_SIGNAL_CTRL_C")},
+    {PORT_SIGNAL_BREAKPOINT,    STR_AND_SIZE("PORT_SIGNAL_BREAKPOINT")},
+    {PORT_SIGNAL_ARITHMETIC,    STR_AND_SIZE("PORT_SIGNAL_ARITHMETIC")},
+};
+
+static size_t ncai_get_signal_count()
+{
+    return sizeof(sig_table)/sizeof(sig_table[0]);
+}
+
+static st_signal_info* find_signal(jint sig)
+{
+    for (size_t i = 0; i < ncai_get_signal_count(); i++)
+    {
+        if (sig_table[i].signal == sig)
+            return &sig_table[i];
+    }
+
+    return NULL;
+}
+
+static jint ncai_get_min_signal()
+{
+    static int min_sig_value = sig_table[1].signal;
+
+    if (min_sig_value != sig_table[1].signal)
+        return min_sig_value;
+
+    min_sig_value = sig_table[0].signal;
+
+    for (size_t i = 1; i < ncai_get_signal_count(); i++)
+    {
+        if (sig_table[i].signal < min_sig_value)
+            min_sig_value = sig_table[i].signal;
+    }
+
+    return min_sig_value;
+}
+
+static jint ncai_get_max_signal()
+{
+    static int max_sig_value = -1;
+
+    if (max_sig_value != -1)
+        return max_sig_value;
+
+    max_sig_value = sig_table[0].signal;
+
+    for (size_t i = 1; i < ncai_get_signal_count(); i++)
+    {
+        if (sig_table[i].signal > max_sig_value)
+            max_sig_value = sig_table[i].signal;
+    }
+
+    return max_sig_value;
+}
+
+static char* ncai_get_signal_name(jint signal)
+{
+    st_signal_info* psig = find_signal(signal);
+    return psig ? psig->name : NULL;
+}
+
+static size_t ncai_get_signal_name_size(jint signal)
+{
+    st_signal_info* psig = find_signal(signal);
+    return psig ? psig->name_size : 0;
+}
+
+bool ncai_is_signal_in_range(jint signal)
+{
+    return (signal >= ncai_get_min_signal() ||
+            signal <= ncai_get_max_signal());
 }

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=638327&r1=638326&r2=638327&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 Mar 18 04:31:02 2008
@@ -153,14 +153,14 @@
         vm_thread = jthread_get_vm_thread(thread);
     }
 
-    WalkContext context;
-    if (!native_init_walk_context(&context, NULL, &regs))
+    UnwindContext context;
+    if (!port_init_unwind_context(&context, NULL, &regs))
         return NCAI_ERROR_INTERNAL;
 
     *pcount = walk_native_stack_registers(&context, &regs,
                     vm_thread, max_depth, frame_array);
 
-    native_clean_walk_context(&context);
+    port_clean_unwind_context(&context);
 
     return NCAI_ERROR_NONE;
 }

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_step_ia32.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_step_ia32.cpp?rev=638327&r1=638326&r2=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_step_ia32.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_step_ia32.cpp Tue Mar 18 04:31:02 2008
@@ -5,6 +5,7 @@
 
 #define LOG_DOMAIN "ncai.step"
 #include "cxxlog.h"
+#include "port_crash_handler.h"
 #include "jvmti_break_intf.h"
 
 #include "ncai_utils.h"
@@ -301,10 +302,9 @@
 static InstructionDisassembler* get_local_disasm(void* addr)
 {
     VMBreakPoints* vm_brpt = VM_Global_State::loader_env->TI->vm_brpt;
-    uint8* bptr = (uint8*)addr;
     InstructionDisassembler* pdasm;
 
-    if (*bptr == INSTRUMENTATION_BYTE)
+    if (port_is_breakpoint_set(addr))
     { // Address was instrumented by another thread or by breakpoint
         VMBreakPoint* bp = vm_brpt->find_breakpoint(addr);
         assert(bp && bp->disasm);

Copied: harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/native_stack.cpp (from r637971, harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp)
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/native_stack.cpp?p2=harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/native_stack.cpp&p1=harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp&r1=637971&r2=638327&rev=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/native_stack.cpp Tue Mar 18 04:31:02 2008
@@ -19,16 +19,14 @@
  * @version $Revision: 1.1.2.1 $
  */
 
-#include <string.h>
 #include "lock_manager.h"
 #include "m2n.h"
-#include "stack_trace.h"
+#include "compile.h"
 #include "interpreter.h"
 #include "interpreter_exports.h"
-#include "compile.h"
-#include "jvmti_break_intf.h"
 #include "environment.h"
-#include "native_modules.h"
+#include "port_modules.h"
+#include "port_unwind.h"
 #include "native_stack.h"
 
 
@@ -67,10 +65,17 @@
     return buf;
 }
 
-bool native_is_in_stack(WalkContext* context, void* sp)
+const char* native_get_stub_name_nocpy(void* ip)
 {
-    return (sp >= context->stack.base &&
-            sp < (char*)context->stack.base + context->stack.size);
+    // Synchronizing access to dynamic code list
+    LMAutoUnlock dcll(VM_Global_State::loader_env->p_dclist_lock);
+
+    DynamicCode* code = native_find_stub(ip);
+
+    if (!code)
+        return NULL;
+
+    return code->name;
 }
 
 bool native_is_ip_stub(void* ip)
@@ -81,6 +86,41 @@
     return (native_find_stub(ip) != NULL);
 }
 
+static void native_fill_frame_info(Registers* UNREF regs, native_frame_t* UNREF frame, jint UNREF jdepth)
+{
+    frame->java_depth = jdepth;
+
+    if (!regs)
+        return;
+
+#if defined(_IPF_)
+    // Nothing
+#elif defined(_EM64T_)
+    frame->ip = (void*)regs->rip;
+    frame->frame = (void*)regs->rbp;
+    frame->stack = (void*)regs->rsp;
+#else // IA-32
+    frame->ip = (void*)regs->eip;
+    frame->frame = (void*)regs->ebp;
+    frame->stack = (void*)regs->esp;
+#endif
+}
+
+void native_get_regs_from_jit_context(JitFrameContext* jfc, Registers* regs)
+{
+#if defined(_IPF_)
+    // Nothing
+#elif defined(_EM64T_)
+    regs->rsp = jfc->rsp;
+    regs->rip = *jfc->p_rip;
+    regs->rbp = (jfc->p_rbp) ? *jfc->p_rbp : regs->rbp;
+#else // IA-32
+    regs->esp = jfc->esp;
+    regs->eip = *jfc->p_eip;
+    regs->ebp = (jfc->p_ebp) ? *jfc->p_ebp : regs->ebp;
+#endif
+}
+
 /*
 Now the technique for calling C handler from a signal/exception context
 guarantees that all needed return addresses are present in stack, so
@@ -97,65 +137,20 @@
 //////////////////////////////////////////////////////////////////////////////
 //
 
-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 (!port_get_all_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)
-            port_clear_modules(&context->modules);
-        return false;
-    }
-
-    return true;
-}
-
-void native_clean_walk_context(WalkContext* context)
-{
-    if (!context)
-        return;
-
-    if (context->modules && context->clean_modules)
-    {
-        port_clear_modules(&context->modules);
-    }
-
-    context->modules = NULL;
-}
-
 
 static int walk_native_stack_jit(
-    WalkContext* context,
+    UnwindContext* context,
     Registers* pregs, VM_thread* pthread,
     int max_depth, native_frame_t* frame_array);
 static int walk_native_stack_pure(
-    WalkContext* context, Registers* pregs,
+    UnwindContext* context, Registers* pregs,
     int max_depth, native_frame_t* frame_array);
 static int walk_native_stack_interpreter(
-    WalkContext* context,
+    UnwindContext* context,
     Registers* pregs, VM_thread* pthread,
     int max_depth, native_frame_t* frame_array);
 
-int walk_native_stack_registers(WalkContext* context, Registers* pregs,
+int walk_native_stack_registers(UnwindContext* context, Registers* pregs,
     VM_thread* pthread, int max_depth, native_frame_t* frame_array)
 {
     if (pthread == NULL) // Pure native thread
@@ -171,7 +166,7 @@
 
 
 static int walk_native_stack_jit(
-    WalkContext* context,
+    UnwindContext* context,
     Registers* pregs, VM_thread* pthread,
     int max_depth, native_frame_t* frame_array)
 {
@@ -301,20 +296,12 @@
         {
             Registers tmp_regs = regs;
 
-            if (native_is_frame_exists(context, &tmp_regs))
-            { // Stack frame (x86)
-                if (!native_unwind_stack_frame(context, &tmp_regs))
+            if (!port_unwind_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();
-/*
+
 Now the technique for calling C handler from a signal/exception context
 guarantees that all needed return addresses are present in stack, so
 there is no need in special processing
@@ -326,7 +313,7 @@
             else*/
                 regs = tmp_regs;
 
-            vm_breaks->unlock();
+//            vm_breaks->unlock();
         }
             
         code_type = vm_identify_eip(regs.get_ip());
@@ -354,7 +341,7 @@
 
 
 static int walk_native_stack_pure(
-    WalkContext* context, Registers* pregs,
+    UnwindContext* context, Registers* pregs,
     int max_depth, native_frame_t* frame_array)
 {
     // Register context for current frame
@@ -376,19 +363,8 @@
 
         ++frame_count;
 
-        if (native_is_frame_exists(context, &regs))
-        { // Stack frame (x86)
-            // Here must be special processing for breakpoint handler frames
-            // But it requires VM_thread structure attached to thread
-            // TODO: Investigate possibility
-            if (!native_unwind_stack_frame(context, &regs))
-                break;
-        }
-        else
-        { // Stack frame does not exist, try using heuristics
-            if (!native_unwind_special(context, &regs))
+        if (port_unwind_frame(context, &regs))
                 break;
-        }
     }
 
     return frame_count;
@@ -396,7 +372,7 @@
 
 
 static int walk_native_stack_interpreter(
-    WalkContext* context,
+    UnwindContext* context,
     Registers* pregs, VM_thread* pthread,
     int max_depth, native_frame_t* frame_array)
 {
@@ -426,20 +402,12 @@
         void* prev_sp = regs.get_sp();
         Registers tmp_regs = regs;
 
-        if (native_is_frame_exists(context, &tmp_regs))
-        { // Stack frame (x86)
-            if (!native_unwind_stack_frame(context, &tmp_regs))
+        if (port_unwind_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();
-/*
+
 Now the technique for calling C handler from a signal/exception context
 guarantees that all needed return addresses are present in stack, so
 there is no need in special processing
@@ -448,7 +416,7 @@
         else*/
             regs = tmp_regs;
 
-        vm_breaks->unlock();
+//        vm_breaks->unlock();
 
         bool is_java = interpreter.is_frame_in_native_frame(frame, prev_sp, regs.get_sp());
 

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/lock_manager.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/lock_manager.cpp?rev=638327&r1=638326&r2=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/lock_manager.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/lock_manager.cpp Tue Mar 18 04:31:02 2008
@@ -20,37 +20,38 @@
  */  
 
 
+#include "port_mutex.h"
 #include "lock_manager.h"
 #include "vm_threads.h"
 #include "exceptions.h"
 
 Lock_Manager::Lock_Manager()
 {
-    UNREF IDATA stat = hymutex_create (&lock, TM_MUTEX_NESTED);
+    UNREF IDATA stat = port_mutex_create (&lock, APR_THREAD_MUTEX_NESTED);
     assert(stat==TM_ERROR_NONE);
 }
 
 Lock_Manager::~Lock_Manager()
 {
-    UNREF IDATA stat = hymutex_destroy (&lock);
+    UNREF IDATA stat = port_mutex_destroy (&lock);
     assert(stat==TM_ERROR_NONE);
 }
 
 void Lock_Manager::_lock()
 {
-    UNREF IDATA stat = hymutex_lock(&lock);
+    UNREF IDATA stat = port_mutex_lock(&lock);
     assert(stat==TM_ERROR_NONE);
 }
 
 bool Lock_Manager::_tryLock()
 {     
-    IDATA stat = hymutex_trylock(&lock);
+    IDATA stat = port_mutex_trylock(&lock);
     return stat==TM_ERROR_NONE;    
 }
 
 void Lock_Manager::_unlock()
 {
-    UNREF IDATA stat = hymutex_unlock(&lock);
+    UNREF IDATA stat = port_mutex_unlock(&lock);
     assert(stat==TM_ERROR_NONE);
 }
 
@@ -93,6 +94,6 @@
 
 bool Lock_Manager::_lock_enum_or_null(bool UNREF return_null_on_fail)
 {
-    IDATA stat = hymutex_lock(&lock);
+    IDATA stat = port_mutex_lock(&lock);
     return stat==TM_ERROR_NONE;
 }

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp?rev=638327&r1=638326&r2=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp Tue Mar 18 04:31:02 2008
@@ -62,7 +62,6 @@
 #include "m2n.h"
 #include "exceptions.h"
 #include "jit_intf.h"
-#include "exception_filter.h"
 #include "vm_threads.h"
 #include "jni_utils.h"
 #include "object.h"

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_manager.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_manager.cpp?rev=638327&r1=638326&r2=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_manager.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_manager.cpp Tue Mar 18 04:31:02 2008
@@ -192,7 +192,7 @@
 } // vm_set_exception_registers
 
 /**
- * Gets IP from exception registers
+ * Gets IP from exception registers for current thread
  */
 void *vm_get_ip_from_regs(vm_thread_t vm_thread)
 {

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_ti_monitors.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_ti_monitors.cpp?rev=638327&r1=638326&r2=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_ti_monitors.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_ti_monitors.cpp Tue Mar 18 04:31:02 2008
@@ -21,6 +21,7 @@
  */
 
 #include <open/hythread_ext.h>
+#include "port_mutex.h"
 #include "vm_threads.h"
 
 typedef struct ResizableArrayEntry *array_entry_t;
@@ -120,7 +121,7 @@
 } // array_get
 
 static array_t jvmti_monitor_table = 0;
-static hymutex_t jvmti_monitor_table_lock;
+static osmutex_t jvmti_monitor_table_lock;
 
 static IDATA jthread_init_jvmti_monitor_table()
 {
@@ -133,7 +134,7 @@
             hythread_global_unlock();
             return TM_ERROR_OUT_OF_MEMORY;
         }
-        status = hymutex_create(&jvmti_monitor_table_lock, TM_MUTEX_NESTED);
+        status = port_mutex_create(&jvmti_monitor_table_lock, APR_THREAD_MUTEX_NESTED);
         if (status != TM_ERROR_NONE) {
             hythread_global_unlock();
             return status;
@@ -171,17 +172,17 @@
         }
     }
 
-    status = hymutex_lock(&jvmti_monitor_table_lock);
+    status = port_mutex_lock(&jvmti_monitor_table_lock);
     if (status != TM_ERROR_NONE) {
         return status;
     }
     *mon_ptr = (jrawMonitorID)array_add(jvmti_monitor_table, monitor);
     if (!(*mon_ptr)) {
-        hymutex_unlock(&jvmti_monitor_table_lock);
+        port_mutex_unlock(&jvmti_monitor_table_lock);
         return TM_ERROR_OUT_OF_MEMORY;
     }
 
-    status = hymutex_unlock(&jvmti_monitor_table_lock);
+    status = port_mutex_unlock(&jvmti_monitor_table_lock);
     return status;
 } // jthread_raw_monitor_create
 
@@ -206,12 +207,12 @@
         }
     }
 
-    IDATA status = hymutex_lock(&jvmti_monitor_table_lock);
+    IDATA status = port_mutex_lock(&jvmti_monitor_table_lock);
     if (status != TM_ERROR_NONE) {
         return status;
     }
     array_delete(jvmti_monitor_table, (UDATA) mon_ptr);
-    status = hymutex_unlock(&jvmti_monitor_table_lock);
+    status = port_mutex_unlock(&jvmti_monitor_table_lock);
     return status;
 } // jthread_raw_monitor_destroy
 

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/crash_dump.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/crash_dump.cpp?rev=638327&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/crash_dump.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/crash_dump.cpp Tue Mar 18 04:31:02 2008
@@ -0,0 +1,509 @@
+/*
+ *  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 <ctype.h>
+
+#include "port_dso.h"
+#include "port_modules.h"
+#include "port_crash_handler.h"
+#include "port_frame_info.h"
+#include "m2n.h"
+#include "stack_iterator.h"
+#include "environment.h"
+#include "vm_threads.h"
+#include "exceptions.h"
+#include "natives_support.h"
+#include "stack_trace.h"
+#include "signals.h"
+#include "interpreter.h"
+#include "compile.h"
+#include "cci.h"
+#include "jit_intf_cpp.h"
+#include "native_stack.h"
+#include "crash_dump.h"
+
+
+#ifdef PLATFORM_POSIX
+#include <strings.h>
+#define strcmp_case strcasecmp
+#else /* Windows */
+#include <string.h>
+#define strcmp_case _stricmp
+#endif
+
+
+static void cd_init_crash_sequence();
+static void cd_cleanup_crash_sequence();
+static void cd_fill_java_method_info(Method* m, void* ip, bool is_ip_past,
+                                     int inl_depth, port_stack_frame_info* sfi);
+static void cd_print_module_info(Registers* regs);
+static void cd_print_threads_info();
+
+
+struct st_int_uwinfo
+{
+    bool filled;
+    FrameHandle* frame;
+    void* prev_sp;
+};
+
+struct st_jit_uwinfo
+{
+    bool filled;
+    CodeChunkInfo* cci;
+    int inline_index;
+    M2nFrame* lm2n;
+    bool is_first; // For setting is_ip_past
+};
+
+static uint32 cci_get_inlined_depth(CodeChunkInfo* cci, uint32 offset)
+{
+    ASSERT_NO_INTERPRETER
+
+    if (!cci || !cci->has_inline_info())
+        return 0;
+
+    return cci->get_jit()->get_inline_depth(cci->get_inline_info(), offset);
+}
+
+static Method* get_jit_method(CodeChunkInfo* cci, void* ip, uint32 index, bool is_first)
+{
+    Method* method = cci->get_method();
+
+    if (index == 0)
+        return method;
+
+    uint32 offset = (uint32)((POINTER_SIZE_INT)ip -
+        (POINTER_SIZE_INT)cci->get_code_block_addr());
+    uint32 inlined_depth = cci_get_inlined_depth(cci, offset);
+    bool is_ip_past = !is_first; // || (index != inlined_depth);
+
+    if (index > inlined_depth)
+        return method; // Error
+
+    Method* inl_method =
+        cci->get_jit()->get_inlined_method(cci->get_inline_info(), offset, index);
+
+    return inl_method;
+}
+
+
+static void cd_unwind_from_java(vm_thread_t vmthread,
+                CodeChunkInfo* cci, Registers* regs, bool is_ip_past, M2nFrame* m2n)
+{
+    StackIterator* si = (StackIterator*)STD_ALLOCA(si_size());
+
+    M2nFrame* last_m2n = m2n ? m2n : m2n_get_last_frame(vmthread);
+    si_fill_from_registers(si, regs, is_ip_past, last_m2n);
+
+    while (!si_is_past_end(si))
+    {
+        CodeChunkInfo* curcci = si_get_code_chunk_info(si);
+
+        if (curcci && curcci == cci &&
+            si_get_ip(si) == regs->get_ip())
+            break; // Method is found in stack iterator
+
+        si_goto_previous(si);
+    }
+
+    if (si_is_past_end(si)) // Error: method not found
+        return;
+
+    si_goto_previous(si);
+    si_copy_to_registers(si, regs);
+}
+
+static void cd_unwind_from_stub(M2nFrame* lm2n, Registers* regs)
+{
+    StackIterator* si = (StackIterator*)STD_ALLOCA(si_size());
+    si_fill_from_registers(si, regs, true, lm2n);
+    si_goto_previous(si);
+    si_copy_to_registers(si, regs);
+}
+
+
+static int unwind_compiled_frame(Registers *regs, port_stack_frame_info *sfi)
+{
+    // Suppose this callback is called by PORT for crash reasons only
+    cd_init_crash_sequence();
+
+    if (!sfi->iteration_state)
+        return (int)(interpreter_enabled() ? sizeof(st_int_uwinfo)
+                                           : sizeof(st_jit_uwinfo));
+
+    void* cur_ip = regs->get_ip();
+    void* cur_sp = regs->get_sp();
+
+    // For interpreter - only return additional info
+    if (interpreter_enabled())
+    {
+        vm_thread_t vmthread = get_thread_ptr();
+        st_int_uwinfo* uwinfo = (st_int_uwinfo*)sfi->iteration_state;
+
+        if (!vmthread)
+            return -1;
+
+        if (!uwinfo->filled)
+        {
+            uwinfo->frame = interpreter.interpreter_get_last_frame(vmthread);
+            uwinfo->prev_sp = cur_sp;
+            uwinfo->filled = true;
+        }
+
+        bool is_java = interpreter.is_frame_in_native_frame(uwinfo->frame, uwinfo->prev_sp, cur_sp);
+        if (is_java)
+        {
+            Method* method = (Method*)interpreter.interpreter_get_frame_method(uwinfo->frame);
+            uint8* bc_ptr = interpreter.interpreter_get_frame_bytecode_ptr(uwinfo->frame);
+            cd_fill_java_method_info(method, (void*)bc_ptr, false, -1, sfi);
+            uwinfo->frame = interpreter.interpreter_get_prev_frame(uwinfo->frame);
+        }
+
+        uwinfo->prev_sp = cur_sp;
+        return -1;
+    }
+
+    // JIT-frames
+    vm_thread_t vmthread = get_thread_ptr();
+    st_jit_uwinfo* uwinfo = (st_jit_uwinfo*)sfi->iteration_state;
+
+    if (!vmthread)
+        return -1;
+
+    if (!uwinfo->filled)
+    {
+        uwinfo->cci = NULL;
+        uwinfo->inline_index = -1;
+        uwinfo->is_first = true;
+        uwinfo->filled = true;
+        uwinfo->lm2n = NULL;
+    }
+
+    Global_Env* env = VM_Global_State::loader_env;
+    bool ip_past = !uwinfo->is_first;
+    uwinfo->is_first = false; // For the next iterations
+
+    // Stubs - return stub name as additional info
+    if (native_is_ip_stub(cur_ip))
+    {
+        sfi->method_class_name = "stub";
+        sfi->method_name = native_get_stub_name_nocpy(cur_ip);
+
+        if (uwinfo->lm2n == NULL) // Initialize
+            uwinfo->lm2n = m2n_get_last_frame(vmthread);
+
+        cd_unwind_from_stub(uwinfo->lm2n, regs);
+        uwinfo->lm2n = m2n_get_previous_frame(uwinfo->lm2n);
+
+        return 0; // Regs now contain a context for previous Java frame
+    }
+
+    CodeChunkInfo* cci = NULL;
+    Method_Handle mh = env->em_interface->LookupCodeChunk(cur_ip,
+                                        ip_past, NULL, NULL, (void**)&cci);
+
+    if (!mh)
+    {
+        //assert(uwinfo->inline_index == 0);// we should not miss first JITted frame
+        uwinfo->cci = NULL;
+        return -1;
+    }
+
+    if (cci == uwinfo->cci) // Continue reporting inlined methods
+    {
+        if (uwinfo->inline_index <= 0)
+            return -1; // Error: should be unwound earlier
+
+        --uwinfo->inline_index;
+        Method* m = get_jit_method(cci, cur_ip, uwinfo->inline_index, ip_past);
+        cd_fill_java_method_info(m, cur_ip, ip_past, uwinfo->inline_index, sfi);
+
+        if (uwinfo->inline_index > 0) // Simply return info from inlined method
+            return 0;
+
+        // Need to unwind JITted Java frame and update registers
+        cd_unwind_from_java(vmthread, cci, regs, ip_past, uwinfo->lm2n);
+        return 0;
+    }
+
+    // New cci
+    uint32 offset = (uint32)((POINTER_SIZE_INT)cur_ip -
+                        (POINTER_SIZE_INT)cci->get_code_block_addr());
+    uint32 inlined_depth = cci_get_inlined_depth(cci, offset);
+
+    uwinfo->cci = cci;
+    uwinfo->inline_index = (int)inlined_depth;
+
+    Method* m = get_jit_method(cci, cur_ip, inlined_depth, ip_past);
+    cd_fill_java_method_info(m, cur_ip, ip_past, inlined_depth, sfi);
+
+    if (inlined_depth == 0) // Unwind right now if not inlined
+        cd_unwind_from_java(vmthread, cci, regs, ip_past, uwinfo->lm2n);
+
+    return 0;
+}
+
+
+static void crash_action(port_sigtype UNREF signum, Registers* regs, void* UNREF fault_addr)
+{
+    if (!regs) // No regs info - do not print anything
+        return;
+
+    // For the case when unwind callback was not called before
+    cd_init_crash_sequence();
+
+    // Print crashed modile info
+    cd_print_module_info(regs);
+    // Print threads info
+    cd_print_threads_info();
+
+        fflush(stderr);
+    cd_cleanup_crash_sequence();
+}
+
+
+static port_signal_handler_registration registrations[] =
+{
+    {PORT_SIGNAL_GPF,             null_reference_handler},
+    {PORT_SIGNAL_STACK_OVERFLOW,  stack_overflow_handler},
+    {PORT_SIGNAL_ABORT,           abort_handler},
+    {PORT_SIGNAL_QUIT,            ctrl_backslash_handler},
+    {PORT_SIGNAL_CTRL_BREAK,      ctrl_break_handler},
+    {PORT_SIGNAL_CTRL_C,          ctrl_c_handler},
+    {PORT_SIGNAL_BREAKPOINT,      native_breakpoint_handler},
+    {PORT_SIGNAL_ARITHMETIC,      arithmetic_handler}
+};
+
+int vm_initialize_signals()
+{
+    Boolean result = port_init_crash_handler(
+                        registrations,
+                        sizeof(registrations)/sizeof(registrations[0]),
+                        unwind_compiled_frame);
+
+    if (!result)
+        return -1;
+
+    result = port_crash_handler_add_action(crash_action);
+
+    if (!result)
+        return -1;
+
+    unsigned flags = port_crash_handler_get_capabilities();
+
+#ifdef PLATFORM_POSIX
+    bool call_dbg = (VM_Global_State::loader_env == NULL) ||
+            get_boolean_property("vm.crash_handler", FALSE, VM_PROPERTIES);
+#else // WIN
+    bool call_dbg = (VM_Global_State::loader_env == NULL) ||
+            get_boolean_property("vm.assert_dialog", TRUE, VM_PROPERTIES);
+#endif
+    if (!call_dbg)
+        flags &= ~PORT_CRASH_CALL_DEBUGGER;
+
+    port_crash_handler_set_flags(flags);
+
+    return 0;
+}
+
+
+int vm_shutdown_signals()
+{
+    Boolean result = port_shutdown_crash_handler();
+    if (!result)
+        return -1;
+
+    return 0;
+}
+
+
+
+// Crash sequence is single-threaded, it's provided by the PORT
+static bool g_crash_initialized = false;
+static int g_disable_count;
+static bool g_unwindable;
+static native_module_t* g_modules = NULL;
+
+static void cd_init_crash_sequence()
+{
+    if (g_crash_initialized)
+        return;
+
+    VM_thread* thread = get_thread_ptr(); // Can be NULL for pure native thread
+
+    if (thread)
+    {
+        // Enable suspend to allow working with threads
+        g_disable_count = hythread_reset_suspend_disable();
+        // Acquire global lock to print threads list
+//        hythread_global_lock();
+        g_unwindable = set_unwindable(false); // To call Java code
+    }
+
+    g_crash_initialized = true;
+}
+
+static void cd_cleanup_crash_sequence()
+{
+    if (!g_crash_initialized)
+        return;
+
+    VM_thread* thread = get_thread_ptr(); // Can be NULL for pure native thread
+
+    if (thread)
+    {
+        set_unwindable(g_unwindable);
+//        hythread_global_unlock();
+        hythread_set_suspend_disable(g_disable_count);
+    }
+
+    g_crash_initialized = false;
+}
+
+
+static void cd_fill_java_method_info(Method* m, void* ip, bool is_ip_past,
+                                     int inl_depth, port_stack_frame_info* sfi)
+{
+    if (!m || !sfi)
+        return;
+
+    sfi->method_class_name = m->get_class()->get_name()->bytes;
+    sfi->method_name = m->get_name()->bytes;
+    sfi->method_signature = m->get_descriptor()->bytes;
+    sfi->source_file_name = NULL;
+    sfi->source_line_number = -1;
+
+    if (!ip)
+        return;
+
+    const char* fname = NULL;
+    int line = -1;
+
+    if (inl_depth == 0)
+        inl_depth = -1; // should pass -1 for non-inlined methods
+
+    get_file_and_line(m, ip, is_ip_past, inl_depth, &fname, &line);
+
+    if (fname)
+    {
+        sfi->source_file_name = fname;
+        sfi->source_line_number = line;
+    }
+}
+
+
+const char* cd_get_module_type(const char* short_name)
+{
+    char name[256];
+
+    if (strlen(short_name) > 255)
+        return "Too long short name";
+
+    strcpy(name, short_name);
+    char* dot = strchr(name, '.');
+
+    // Strip suffix/extension
+    if (dot)
+        *dot = 0;
+
+    // Strip prefix
+    char* nameptr = name;
+
+    if (!memcmp(short_name, PORT_DSO_PREFIX, strlen(PORT_DSO_PREFIX)))
+        nameptr += strlen(PORT_DSO_PREFIX);
+
+    char* vm_modules[] = {"java", "em", "encoder", "gc_gen", "gc_gen_uncomp", "gc_cc",
+        "harmonyvm", "hythr", "interpreter", "jitrino", "vmi"};
+
+    for (size_t i = 0; i < sizeof(vm_modules)/sizeof(vm_modules[0]); i++)
+    {
+        if (!strcmp_case(name, vm_modules[i]))
+            return "VM native code";
+    }
+
+    if (natives_is_library_loaded_slow(short_name))
+        return "JNI native library";
+
+    return "Unknown/system native module";
+}
+
+static void cd_fill_modules()
+{
+    if (g_modules)
+        return;
+
+    int count;
+    bool res = port_get_all_modules(&g_modules, &count);
+    assert(res && g_modules && count);
+}
+
+static void cd_print_module_info(Registers* regs)
+{
+    cd_fill_modules();
+
+    native_module_t* module = port_find_module(g_modules, (void*)regs->get_ip());
+    cd_parse_module_info(module, regs->get_ip());
+}
+
+
+static void cd_print_threads_info()
+{
+    VM_thread* cur_thread = get_thread_ptr();
+
+    if (!cur_thread)
+        fprintf(stderr, "\nCurrent thread is not attached to VM, ID: %d\n", port_gettid());
+
+    fprintf(stderr, "\nVM attached threads:\n\n");
+
+    hythread_iterator_t it = hythread_iterator_create(NULL);
+    int count = (int)hythread_iterator_size(it);
+
+    for (int i = 0; i < count; i++)
+    {
+        hythread_t thread = hythread_iterator_next(&it);
+        VM_thread* vm_thread = jthread_get_vm_thread(thread);
+
+        if (!vm_thread)
+            continue;
+
+        jthread java_thread = jthread_get_java_thread(thread);
+        JNIEnv* jni_env = vm_thread->jni_env;
+
+        if (cur_thread && java_thread)
+        {
+            jclass cl = GetObjectClass(jni_env, java_thread);
+            jmethodID id = jni_env->GetMethodID(cl, "getName","()Ljava/lang/String;");
+            jstring name = jni_env->CallObjectMethod(java_thread, id);
+            char* java_name = (char*)jni_env->GetStringUTFChars(name, NULL);
+
+            fprintf(stderr, "%s[%p]  '%s'\n",
+                    (cur_thread && vm_thread == cur_thread) ? "--->" : "    ",
+                    thread->os_handle, java_name);
+
+            jni_env->ReleaseStringUTFChars(name, java_name);
+        }
+        else
+        {
+            fprintf(stderr, "%s[%p]\n",
+                    (cur_thread && vm_thread == cur_thread) ? "--->" : "    ",
+                    thread->os_handle);
+        }
+    }
+
+    hythread_iterator_release(&it);
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/crash_dump.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_dump_os.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_dump_os.cpp?rev=638327&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_dump_os.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_dump_os.cpp Tue Mar 18 04:31:02 2008
@@ -0,0 +1,88 @@
+/*
+ *  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 <stdio.h>
+#include <stdlib.h>
+
+#include "open/platform_types.h"
+#include "open/hythread_ext.h"
+#include "port_filepath.h"
+#include "port_dso.h"
+#include "port_modules.h"
+#include "crash_dump.h"
+
+
+static inline bool cd_is_predefined_name(const char* name)
+{
+    if (*name != '[')
+        return false;
+
+    return true;
+//    return (!strcmp(name, "[heap]") ||
+//            !strcmp(name, "[stack]") ||
+//            !strcmp(name, "[vdso]"));
+}
+
+static inline native_segment_t* cd_find_segment(native_module_t* module, void* ip)
+{
+    for (size_t i = 0; i < module->seg_count; i++)
+    {
+        if (module->segments[i].base <= ip &&
+            (char*)module->segments[i].base + module->segments[i].size > ip)
+            return &module->segments[i];
+    }
+
+    assert(0);
+    return NULL;
+}
+
+void cd_parse_module_info(native_module_t* module, void* ip)
+{
+    fprintf(stderr, "\nCrashed module:\n");
+
+    if (!module)
+    { // Unknown address
+        fprintf(stderr, "Unknown address 0x%"W_PI_FMT"\n",
+                (POINTER_SIZE_INT)ip);
+        return;
+    }
+
+    native_segment_t* segment = cd_find_segment(module, ip);
+
+    if (!module->filename)
+    {
+        fprintf(stderr, "Unknown memory region 0x%"W_PI_FMT":0x%"W_PI_FMT"%s\n",
+                (size_t)segment->base, (size_t)segment->base + segment->size,
+                (segment->type == SEGMENT_TYPE_CODE) ? "" : " without execution rights");
+        return;
+    }
+
+    if (cd_is_predefined_name(module->filename))
+    { // Special memory region
+        fprintf(stderr, "%s memory region 0x%"W_PI_FMT":0x%"W_PI_FMT"%s\n",
+                module->filename,
+                (size_t)segment->base, (size_t)segment->base + segment->size,
+                (segment->type == SEGMENT_TYPE_CODE) ? "" : " without execution rights");
+        return;
+    }
+
+    // Common shared module
+    const char* short_name = port_filepath_basename(module->filename);
+    const char* module_type = cd_get_module_type(short_name);
+
+    fprintf(stderr, "%s\n(%s)\n", module->filename, module_type);
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_dump_os.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

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=638327&r1=638326&r2=638327&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 18 04:31:02 2008
@@ -15,25 +15,8 @@
  *  limitations under the License.
  */
 
-#define LOG_DOMAIN "signals"
-#include "cxxlog.h"
-
 #include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <stdio.h>
-#include <iostream>
-#include <fstream>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-
 #include <sys/ucontext.h>
-#include <sys/wait.h>
-
-
 #undef __USE_XOPEN
 #include <signal.h>
 
@@ -42,79 +25,19 @@
 #include <pthread_np.h>
 #endif
 #include <sys/time.h>
-#include "port_thread.h"
 
+#define LOG_DOMAIN "signals"
+#include "cxxlog.h"
+#include "open/platform_types.h"
 #include "Class.h"
+#include "interpreter.h"
 #include "environment.h"
-
-#include "open/gc.h"
-
-#include "init.h"
 #include "exceptions.h"
 #include "exceptions_jit.h"
-#include "vm_threads.h"
-#include "open/vm_util.h"
-#include "compile.h"
-#include "vm_stats.h"
-#include "sync_bits.h"
-
-#include "object_generic.h"
-#include "thread_manager.h"
-
-#include "exception_filter.h"
-#include "interpreter.h"
-#include "crash_handler.h"
-#include "stack_dump.h"
-#include "jvmti_break_intf.h"
-
 #include "signals_common.h"
+#include "signals.h"
 
 
-static void general_crash_handler(int signum, Registers* regs);
-
-
-extern "C" {
-static void DECL_CHANDLER c_exception_handler(Registers* regs, Class* exn_class, bool java_code) {
-    // this exception handler is executed *after* NT exception handler returned
-    DebugUtilsTI* ti = VM_Global_State::loader_env->TI;
-    // Create local copy for registers because registers in TLS can be changed
-    VM_thread *thread = p_TLS_vmthread;
-    assert(thread);
-    assert(exn_class);
-
-    exn_athrow_regs(regs, exn_class, java_code, true);
-}
-}
-
-static void throw_from_sigcontext(Registers* regs, Class* exc_clss)
-{
-    DebugUtilsTI* ti = VM_Global_State::loader_env->TI;
-    bool java_code = (vm_identify_eip((void*)regs->get_ip()) == VM_TYPE_JAVA);
-    VM_thread* vmthread = p_TLS_vmthread;
-
-    vm_set_exception_registers(vmthread, *regs);
-
-    assert(exc_clss);
-
-    NativeCodePtr callback = (NativeCodePtr) c_exception_handler;
-    // Set up parameters and registers
-    port_set_longjump_regs(callback, regs,
-                            3, regs, exc_clss, (POINTER_SIZE_INT)java_code);
-}
-
-static bool java_throw_from_sigcontext(Registers* regs, Class* exc_clss)
-{
-    ASSERT_NO_INTERPRETER;
-    void* ip = regs->get_ip();
-    VM_Code_Type vmct = vm_identify_eip(ip);
-    if(vmct != VM_TYPE_JAVA) {
-        return false;
-    }
-
-    throw_from_sigcontext(regs, exc_clss);
-    return true;
-}
-
 /*
  * Information about stack
  */
@@ -153,11 +76,11 @@
 }
 #endif
 
-inline size_t find_guard_stack_size() {
+static inline size_t find_guard_stack_size() {
     return 64*1024;
 }
 
-inline size_t find_guard_page_size() {
+static inline size_t find_guard_page_size() {
     int err;
     size_t guard_size;
     pthread_attr_t pthread_attr;
@@ -172,19 +95,19 @@
 static size_t common_guard_stack_size;
 static size_t common_guard_page_size;
 
-inline void* get_stack_addr() {
+static inline void* get_stack_addr() {
     return jthread_self_vm_thread_unsafe()->stack_addr;
 }
 
-inline size_t get_stack_size() {
+static inline size_t get_stack_size() {
     return jthread_self_vm_thread_unsafe()->stack_size;
 }
 
-inline size_t get_guard_stack_size() {
+static inline size_t get_guard_stack_size() {
     return common_guard_stack_size;
 }
 
-inline size_t get_guard_page_size() {
+static inline size_t get_guard_page_size() {
     return common_guard_page_size;
 }
 
@@ -361,288 +284,104 @@
 }
 
 
-
-static void stack_overflow_handler(Registers* regs)
+Boolean stack_overflow_handler(port_sigtype UNREF signum, Registers* regs, void* fault_addr)
 {
-    Global_Env *env = VM_Global_State::loader_env;
+    TRACE2("signals", ("SOE detected at ip=%p, sp=%p",
+                            regs->get_ip(), regs->get_sp()));
 
-    vm_thread_t vm_thread = p_TLS_vmthread;
-    remove_guard_stack(vm_thread);
-    vm_thread->restore_guard_page = true;
+    vm_thread_t vmthread = get_thread_ptr();
+    Global_Env* env = VM_Global_State::loader_env;
+    void* saved_ip = regs->get_ip();
+    void* new_ip = NULL;
 
-    if (java_throw_from_sigcontext(
-                regs, env->java_lang_StackOverflowError_Class)) {
-        return;
-    } else {
-        if (is_unwindable()) {
-            if (hythread_is_suspend_enabled()) {
-                tmn_suspend_disable();
-            }
-            throw_from_sigcontext(
-                regs, env->java_lang_StackOverflowError_Class);
-        } else {
-            exn_raise_by_class(env->java_lang_StackOverflowError_Class);
-        }
-    }
-}
-
-
-static void null_java_reference_handler(int signum, Registers* regs, void* fault_addr)
-{
-    VM_thread *vm_thread = p_TLS_vmthread;
-
-    if (vm_thread && vm_thread->jvmti_thread.violation_flag)
+    if (is_in_ti_handler(vmthread, saved_ip))
     {
-        vm_thread->jvmti_thread.violation_flag = 0;
-        regs->set_ip(vm_thread->jvmti_thread.violation_restart_address);
-        return;
+        new_ip = vm_get_ip_from_regs(vmthread);
+        regs->set_ip(new_ip);
     }
 
-    Global_Env *env = VM_Global_State::loader_env;
-
-    TRACE2("signals", "NPE or SOE detected at " << regs->get_ip());
+    if (!vmthread || env == NULL)
+        return FALSE; // Crash
 
-    if (check_stack_overflow(regs, fault_addr)) {
-        stack_overflow_handler(regs);
-        return;
-    }
+    remove_guard_stack(vmthread);
+    vmthread->restore_guard_page = true;
 
-    if (!interpreter_enabled()) {
-        if (java_throw_from_sigcontext(
-                    regs, env->java_lang_NullPointerException_Class)) {
-            return;
-        }
+    // Pass exception to NCAI exception handler
+    bool is_handled = 0;
+    ncai_process_signal_event((NativeCodePtr)regs->get_ip(),
+                                (jint)signum, false, &is_handled);
+    if (is_handled)
+    {
+        if (new_ip)
+            regs->set_ip(saved_ip);
+        return TRUE;
     }
 
-    general_crash_handler(signum, regs);
-}
-
-
-static void null_java_divide_by_zero_handler(int signum, Registers* regs, void* UNREF fault_addr)
-{
-    Global_Env *env = VM_Global_State::loader_env;
-
-    TRACE2("signals",
-           "ArithmeticException detected at " << regs->get_ip());
+    Class* exn_class = env->java_lang_StackOverflowError_Class;
 
-    if (!interpreter_enabled()) {
-        if (java_throw_from_sigcontext(
-                    regs, env->java_lang_ArithmeticException_Class)) {
-            return;
-        }
+    if (is_in_java(regs))
+    {
+        signal_throw_java_exception(regs, exn_class);
     }
-
-    general_crash_handler(signum, regs);
-}
-
-static void jvmti_jit_breakpoint_handler(int signum, Registers* regs, void* UNREF fault_addr)
-{
-    TRACE2("signals", "JVMTI breakpoint detected at " << (void*)regs->get_ip());
-
-    if (!interpreter_enabled())
+    else if (is_unwindable())
     {
-        regs->set_ip((void*)((POINTER_SIZE_INT)regs->get_ip() - 1));
-        bool handled = jvmti_jit_breakpoint_handler(regs);
-        if (handled)
-            return;
+        if (hythread_is_suspend_enabled())
+            hythread_suspend_disable();
+        signal_throw_exception(regs, exn_class);
+    } else {
+        exn_raise_by_class(exn_class);
     }
 
-    general_crash_handler(signum, regs);
-}
+    if (new_ip && regs->get_ip() == new_ip)
+        regs->set_ip(saved_ip);
 
-/**
- * Print out the call stack of the aborted thread.
- * @note call stacks may be used for debugging
- */
-static void abort_handler(int signum, Registers* regs, void* UNREF fault_addr)
-{
-    general_crash_handler(signum, regs);
+    return TRUE;
 }
 
-static void process_crash(Registers* regs)
+Boolean null_reference_handler(port_sigtype UNREF signum, Registers* regs, void* fault_addr)
 {
-    // print stack trace
-    sd_print_stack(regs);
-}
+    TRACE2("signals", "NPE detected at " << regs->get_ip());
 
-struct sig_name_t
-{
-    int    num;
-    char*  name;
-};
-
-static sig_name_t sig_names[] =
-{
-    {SIGTRAP, "SIGTRAP"},
-    {SIGSEGV, "SIGSEGV"},
-    {SIGFPE,  "SIGFPE" },
-    {SIGABRT, "SIGABRT"},
-    {SIGINT,  "SIGINT" },
-    {SIGQUIT, "SIGQUIT"}
-};
+    vm_thread_t vmthread = get_thread_ptr();
+    Global_Env* env = VM_Global_State::loader_env;
+    void* saved_ip = regs->get_ip();
+    void* new_ip = NULL;
 
-static const char* get_sig_name(int signum)
-{
-    for (int i = 0; i < sizeof(sig_names)/sizeof(sig_names[0]); i++)
+    if (is_in_ti_handler(vmthread, saved_ip))
     {
-        if (signum == sig_names[i].num)
-            return sig_names[i].name;
+        new_ip = vm_get_ip_from_regs(vmthread);
+        regs->set_ip(new_ip);
     }
 
-    return "unregistered";
-}
-
-static void general_crash_handler(int signum, Registers* regs)
-{
-    // setup default handler
-    signal(signum, SIG_DFL);
-    // Print message
-    fprintf(stderr, "Signal %d is reported: %s\n", signum, get_sig_name(signum));
-
-    if (!is_gdb_crash_handler_enabled() ||
-        !gdb_crash_handler(regs))
+    if (check_stack_overflow(regs, fault_addr))
     {
-        NativeCodePtr callback = (NativeCodePtr)process_crash;
-        port_set_longjump_regs(callback, regs, 1, regs);
-    }
-}
+        Boolean result = stack_overflow_handler(signum, regs, fault_addr);
 
-static void general_signal_handler(int signum, siginfo_t* info, void* context)
-{
-    bool replaced = false;
-    ucontext_t* uc = (ucontext_t *)context;
-    void* fault_addr = info->si_addr;
-    VM_thread* vm_thread = p_TLS_vmthread;
-    bool violation =
-        (signum == SIGSEGV) && vm_thread && vm_thread->jvmti_thread.violation_flag;
-
-    Registers regs;
-    port_thread_context_to_regs(&regs, uc);
-    void* saved_ip = regs.get_ip();
-    void* new_ip = saved_ip;
-    bool in_java = false;
+        if (new_ip && regs->get_ip() == new_ip)
+            regs->set_ip(saved_ip);
 
-    if (vm_thread)
-    {
-        // 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
-        POINTER_SIZE_INT break_buf =
-            (POINTER_SIZE_INT)vm_thread->jvmti_thread.jvmti_jit_breakpoints_handling_buffer;
-        if ((POINTER_SIZE_INT)saved_ip >= break_buf &&
-            (POINTER_SIZE_INT)saved_ip < break_buf + TM_JVMTI_MAX_BUFFER_SIZE)
-        {
-            // Breakpoints should not occur in breakpoint buffer
-            assert(signum != SIGTRAP);
-
-            replaced = true;
-            new_ip = vm_get_ip_from_regs(vm_thread);
-            regs.set_ip(new_ip);
-            port_thread_regs_to_context(uc, &regs);
-        }
-
-        in_java = (vm_identify_eip(regs.get_ip()) == VM_TYPE_JAVA);
+        return result;
     }
 
+    if (!vmthread || env == NULL ||
+        !is_in_java(regs) || interpreter_enabled())
+        return FALSE; // Crash
+
     // Pass exception to NCAI exception handler
     bool is_handled = 0;
-    bool is_internal = (signum == SIGTRAP) || violation;
-    ncai_process_signal_event((NativeCodePtr)regs.get_ip(),
-                                (jint)signum, is_internal, &is_handled);
+    ncai_process_signal_event((NativeCodePtr)regs->get_ip(),
+                                (jint)signum, false, &is_handled);
     if (is_handled)
-        return;
-
-    // delegate evident cases to crash handler
-    if ((!vm_thread ||
-        (!in_java && signum != SIGSEGV)) &&
-        signum != SIGTRAP && signum != SIGINT && signum != SIGQUIT)
     {
-        regs.set_ip(saved_ip);
-        general_crash_handler(signum, &regs);
-        port_thread_regs_to_context(uc, &regs);
-        return;
+        if (new_ip)
+            regs->set_ip(saved_ip);
+        return TRUE;
     }
 
-    switch (signum)
-    {
-    case SIGTRAP:
-        jvmti_jit_breakpoint_handler(signum, &regs, fault_addr);
-        break;
-    case SIGSEGV:
-        null_java_reference_handler(signum, &regs, fault_addr);
-        break;
-    case SIGFPE:
-        null_java_divide_by_zero_handler(signum, &regs, fault_addr);
-        break;
-    case SIGABRT:
-        abort_handler(signum, &regs, fault_addr);
-        break;
-    case SIGINT:
-        vm_interrupt_handler(signum);
-        break;
-    case SIGQUIT:
-        vm_dump_handler(signum);
-        break;
-    default:
-        // Unknown signal
-        assert(0);
-        break;
-    }
-
-    // If IP was not changed in specific handler to start another handler,
-    // we should restore original IP, if it's nesessary
-    if (replaced && regs.get_ip() == new_ip)
-        regs.set_ip((void*)saved_ip);
+    signal_throw_java_exception(regs, env->java_lang_NullPointerException_Class);
 
-    // Update OS context
-    port_thread_regs_to_context(uc, &regs);
-}
+    if (new_ip && regs->get_ip() == new_ip)
+        regs->set_ip(saved_ip);
 
-void initialize_signals()
-{
-    struct sigaction sa;
-
-    sigemptyset(&sa.sa_mask);
-    sa.sa_flags = SA_SIGINFO;
-    sa.sa_sigaction = &general_signal_handler;
-    sigaction(SIGTRAP, &sa, NULL);
-
-    sigemptyset(&sa.sa_mask);
-    sa.sa_flags = SA_SIGINFO | SA_ONSTACK;;
-    sa.sa_sigaction = &general_signal_handler;
-    sigaction(SIGSEGV, &sa, NULL);
-
-    sigemptyset(&sa.sa_mask);
-    sa.sa_flags = SA_SIGINFO;
-    sa.sa_sigaction = &general_signal_handler;
-    sigaction(SIGFPE, &sa, NULL);
-
-    sigemptyset(&sa.sa_mask);
-    sa.sa_flags = SA_SIGINFO;
-    sa.sa_sigaction = &general_signal_handler;
-    sigaction(SIGINT, &sa, NULL);
-
-    sigemptyset(&sa.sa_mask);
-    sa.sa_flags = SA_SIGINFO;
-    sa.sa_sigaction = &general_signal_handler;
-    sigaction(SIGQUIT, &sa, NULL);
-
-    /* install abort_handler to print out call stack on assertion failures */
-    sigemptyset(&sa.sa_mask);
-    sa.sa_flags = SA_SIGINFO;
-    sa.sa_sigaction = &general_signal_handler;
-    sigaction( SIGABRT, &sa, NULL);
-    /* abort_handler installed */
-
-    // Prepare gdb crash handler
-    init_gdb_crash_handler();
-
-    // Prepare general crash handler
-    sd_init_crash_handler();
-
-} //initialize_signals
-
-void shutdown_signals() {
-    //FIXME: should be defined in future
-} //shutdown_signals
+    return TRUE;
+}

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/include/platform_lowlevel.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/include/platform_lowlevel.h?rev=638327&r1=638326&r2=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/include/platform_lowlevel.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/include/platform_lowlevel.h Tue Mar 18 04:31:02 2008
@@ -25,13 +25,6 @@
 #include <limits.h>
 //#include <ctype.h>
 
-inline void disable_assert_dialogs() {
-    /* NOP on Linux */
-}
-
-inline void debug_break() {
-    abort();
-}
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -46,8 +39,6 @@
 
 #define dllexport
 #define __declspec(junk)
-
-#define _MAX_PATH PATH_MAX
 
 
 #ifdef __cplusplus

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/include/signals_common.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/include/signals_common.h?rev=638327&r1=638326&r2=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/include/signals_common.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/include/signals_common.h Tue Mar 18 04:31:02 2008
@@ -18,9 +18,6 @@
 #ifndef _SIGNALS_COMMON_H_
 #define _SIGNALS_COMMON_H_
 
-#include <sys/ucontext.h>
-#include "vm_core_types.h"
-
 
 #ifdef _IPF_
 #error IPF architecture is not adopted for unified signal handling

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ipf.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ipf.cpp?rev=638327&r1=638326&r2=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ipf.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ipf.cpp Tue Mar 18 04:31:02 2008
@@ -14,145 +14,26 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-/** 
- * @author Intel, Evgueni Brevnov
- * @version $Revision: 1.1.2.2.4.4 $
- */  
-
-// We use signal handlers to detect null pointer and divide by zero
-// exceptions.
-// There must be an easier way of locating the context in the signal
-// handler than what we do here.
-
-#define LOG_DOMAIN "port.old"
-#include "cxxlog.h"
 
 #include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <stdio.h>
-#include <iostream.h>
-#include <fstream.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-
 #include <sys/ucontext.h>
-#include <sys/wait.h>
-
 #undef __USE_XOPEN
 #include <signal.h>
 
 #include <pthread.h>
-#include <sys/time.h>
+#if defined(FREEBSD)
+#include <pthread_np.h>
+#endif
 
+#define LOG_DOMAIN "signals"
+#include "cxxlog.h"
+#include "open/platform_types.h"
 #include "Class.h"
+#include "interpreter.h"
 #include "environment.h"
- 
-#include "open/gc.h"
-
-#include "init.h" 
 #include "exceptions.h"
 #include "exceptions_jit.h"
-#include "vm_threads.h"
-#include "open/vm_util.h"
-#include "compile.h"
-#include "vm_stats.h"
-#include "sync_bits.h"
-
-#include "object_generic.h"
-#include "thread_manager.h"
-
-#include "exception_filter.h"
-#include "interpreter.h"
-#include "crash_handler.h"
-#include "stack_dump.h"
-#include "jvmti_break_intf.h"
-
-
-#include <semaphore.h>
-
-void asm_exception_catch_callback() {
-    // FIXME: not implemented
-    fprintf(stderr, "FIXME: asm_jvmti_exception_catch_callback: not implemented\n");
-    assert(0);
-    abort();
-}
-
-void asm_jvmti_exception_catch_callback() {
-    // FIXME: not implemented
-    fprintf(stderr, "FIXME: asm_jvmti_exception_catch_callback: not implemented\n");
-    assert(0);
-    abort();
-}
-
-static bool java_throw_from_sigcontext(ucontext_t *uc, Class* exc_clss)
-{
-    // FIXME: not implemented
-    fprintf(stderr, "FIXME: java_throw_from_sigcontext: not implemented\n");
-    assert(0);
-    abort();
-    return false;
-}
-
-void abort_handler (int signum, siginfo_t* info, void* context) {
-    fprintf(stderr, "SIGABRT in VM code.\n");
-    Registers regs;
-    ucontext_t *uc = (ucontext_t *)context;
-    port_thread_context_to_regs(&regs, uc);
-    
-    // setup default handler
-    signal(signum, SIG_DFL);
-
-    if (!is_gdb_crash_handler_enabled() ||
-        !gdb_crash_handler(&regs))
-    {
-        // print stack trace
-        sd_print_stack(&regs);
-    }
-}
-
-
-static void throw_from_sigcontext(ucontext_t *uc, Class* exc_clss) {
-    // FIXME: not implemented
-    fprintf(stderr, "FIXME: throw_from_sigcontext: not implemented\n");
-    assert(0);
-    abort();
-}
-
-void null_java_divide_by_zero_handler(int signum, siginfo_t* UNREF info, void* context)
-{
-    ucontext_t *uc = (ucontext_t *)context;
-    Global_Env *env = VM_Global_State::loader_env;
-
-    /* Will not compile on IPF:
-     * TRACE2("signals", "ArithmeticException detected at " <<
-        (void *)uc->uc_mcontext.gregs[REG_EIP]);
-     */
-
-    if (!interpreter_enabled()) {
-        if (java_throw_from_sigcontext(
-                    uc, env->java_lang_ArithmeticException_Class)) {
-            return;
-        }
-    }
-
-    fprintf(stderr, "SIGFPE in VM code.\n");
-    Registers regs;
-    port_thread_context_to_regs(&regs, uc);
-
-    // setup default handler
-    signal(signum, SIG_DFL);
-
-    if (!is_gdb_crash_handler_enabled() ||
-        !gdb_crash_handler(&regs))
-    {
-        // print stack trace
-        sd_print_stack(&regs);
-    }
-}
+#include "signals.h"
 
 
 /*
@@ -186,12 +67,12 @@
 }
 #endif
 
-inline size_t find_guard_stack_size() {
+static inline size_t find_guard_stack_size() {
     return 64*1024;
     
 }
 
-inline size_t find_guard_page_size() {
+static inline size_t find_guard_page_size() {
     int err;
     size_t guard_size;
     pthread_attr_t pthread_attr;
@@ -205,19 +86,19 @@
 static size_t common_guard_stack_size;
 static size_t common_guard_page_size;
 
-inline void* get_stack_addr() {
+static inline void* get_stack_addr() {
     return jthread_self_vm_thread_unsafe()->stack_addr;
 }
 
-inline size_t get_stack_size() {
+static inline size_t get_stack_size() {
     return jthread_self_vm_thread_unsafe()->stack_size;
 }
 
-inline size_t get_guard_stack_size() {
+static inline size_t get_guard_stack_size() {
     return common_guard_stack_size;
 }
 
-inline size_t get_guard_page_size() {
+static inline size_t get_guard_page_size() {
     return common_guard_page_size;
 }
 
@@ -297,11 +178,6 @@
     }
 }
 
-size_t get_default_stack_size() {
-    size_t default_stack_size = get_stack_size();
-    return default_stack_size;
-}
-
 bool check_available_stack_size(size_t required_size) {
     size_t available_stack_size = get_available_stack_size();
 
@@ -329,12 +205,6 @@
     return get_restore_stack_size() < available_stack_size;
 }
 
-void remove_guard_stack() {
-    vm_thread_t vm_thread = jthread_self_vm_thread_unsafe();
-    assert(vm_thread);
-    remove_guard_stack(vm_thread);
-}
-
 void remove_guard_stack(vm_thread_t vm_thread) {
     int err;
     char* stack_addr = (char*) get_stack_addr();
@@ -356,7 +226,7 @@
 
 }
 
-bool check_stack_overflow(siginfo_t *info, ucontext_t *uc) {
+static bool check_stack_overflow(Registers* regs, void* fault_addr) {
     char* stack_addr = (char*) get_stack_addr();
     size_t stack_size = get_stack_size();
     size_t guard_stack_size = get_guard_stack_size();
@@ -365,264 +235,113 @@
     char* guard_page_begin = stack_addr - stack_size + guard_page_size + guard_stack_size;
     char* guard_page_end = guard_page_begin + guard_page_size;
 
-    char* fault_addr = (char*)(info->si_addr);
-    //char* esp_value = (char*)(uc->uc_mcontext.gregs[REG_ESP]);
-
     return((guard_page_begin <= fault_addr) && (fault_addr < guard_page_end));
 }
 
-/*
- * We find the true signal stack frame set-up by kernel,which is located
- * by locate_sigcontext() below; then change its content according to 
- * exception handling semantics, so that when the signal handler is 
- * returned, application can continue its execution in Java exception handler.
- */
 
-void stack_overflow_handler(int signum, siginfo_t* UNREF info, void* context)
+Boolean stack_overflow_handler(port_sigtype UNREF signum, Registers* regs, void* fault_addr)
 {
-    ucontext_t *uc = (ucontext_t *)context;
-    Global_Env *env = VM_Global_State::loader_env;
+    TRACE2("signals", ("SOE detected at ip=%p, sp=%p",
+                            regs->get_ip(), regs->get_sp()));
 
-    if (java_throw_from_sigcontext(
-                uc, env->java_lang_StackOverflowError_Class)) {
-        return;
-    } else {
-        if (is_unwindable()) {
-            if (hythread_is_suspend_enabled()) {
-                tmn_suspend_disable();
-            }
-            throw_from_sigcontext(
-                uc, env->java_lang_StackOverflowError_Class);
-        } else {
-            vm_thread_t vm_thread = p_TLS_vmthread;
-            remove_guard_stack(vm_thread);
-            exn_raise_by_name("java/lang/StackOverflowError");
-            vm_thread->restore_guard_page = true;
-        }
-    }
-}
+    assert(0); // Not implemented
+    abort();
 
-void null_java_reference_handler(int signum, siginfo_t* UNREF info, void* context)
-{ 
-    ucontext_t *uc = (ucontext_t *)context;
-    Global_Env *env = VM_Global_State::loader_env;
-    Registers regs;
-    port_thread_context_to_regs(&regs, uc);
+    vm_thread_t vmthread = get_thread_ptr();
+    Global_Env* env = VM_Global_State::loader_env;
+    void* saved_ip = regs->get_ip();
+    void* new_ip = NULL;
 
-    if (!p_TLS_vmthread)
+    if (is_in_ti_handler(vmthread, saved_ip))
     {
-        if (!is_gdb_crash_handler_enabled() ||
-            !gdb_crash_handler(&regs))
-        {
-            // print stack trace
-            sd_print_stack(&regs);
-        }
+        new_ip = vm_get_ip_from_regs(vmthread);
+        regs->set_ip(new_ip);
     }
 
-    /* Will not compile on IPF:
-     TRACE2("signals", "NPE or SOE detected at " <<
-        (void *)uc->uc_mcontext.gregs[REG_EIP]); */
-
-    if (check_stack_overflow(info, uc)) {
-        stack_overflow_handler(signum, info, context);
-        return;
-    }
-     
-    if (!interpreter_enabled()) {
-        if (java_throw_from_sigcontext(
-                    uc, env->java_lang_NullPointerException_Class)) {
-            return;
-        }
-    }
-    fprintf(stderr, "SIGSEGV in VM code.\n");
+    if (!vmthread || env == NULL)
+        return FALSE; // Crash
 
-    // setup default handler
-    signal(signum, SIG_DFL);
-
-    if (!is_gdb_crash_handler_enabled() ||
-        !gdb_crash_handler(&regs))
+    // Pass exception to NCAI exception handler
+    bool is_handled = 0;
+    ncai_process_signal_event((NativeCodePtr)regs->get_ip(),
+                                (jint)signum, false, &is_handled);
+    if (is_handled)
     {
-        // print stack trace
-        sd_print_stack(&regs);
+        if (new_ip)
+            regs->set_ip(saved_ip);
+        return TRUE;
     }
-}
-
-void initialize_signals() {
-    struct sigaction sa;
-    
-    sigemptyset(&sa.sa_mask);
-    sa.sa_flags = SA_SIGINFO | SA_ONSTACK;;
-    sa.sa_sigaction = &null_java_reference_handler;
-    sigaction(SIGSEGV, &sa, NULL);
-
-    sigemptyset(&sa.sa_mask);
-    sa.sa_flags = SA_SIGINFO;
-    sa.sa_sigaction = &null_java_divide_by_zero_handler;
-    sigaction(SIGFPE, &sa, NULL);
-
-    signal(SIGINT, (void (*)(int)) vm_interrupt_handler);
-    signal(SIGQUIT, (void (*)(int)) vm_dump_handler);
-
-    /* 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;
-    sigaction( SIGABRT, &sa, NULL);
-    /* abort_handler installed */
-
-    // Prepare gdb crash handler
-    init_gdb_crash_handler();
-
-    // Prepare general crash handler
-    sd_init_crash_handler();
-
-} //initialize_signals
-
-void shutdown_signals() {
-    //FIXME: should be defined in future
-} //shutdown_signals
-
-#if 0
 
-static sigset_t signal_set;
+    Class* exn_class = env->java_lang_StackOverflowError_Class;
 
-extern "C" void get_rnat_and_bspstore(uint64* res);
-extern "C" void do_flushrs();
-
-// Variables used to locate the context from the signal handler
-static int sc_nest = -1;
-static bool use_ucontext = false;
-static uint32 exam_point;
-
-bool SuspendThread(unsigned xx){ return 0; }
-bool ResumeThread(unsigned xx){ return 1; }
+    if (is_in_java(regs))
+    {
+        signal_throw_java_exception(regs, exn_class);
+    }
+    else if (is_unwindable())
+    {
+        if (hythread_is_suspend_enabled())
+            hythread_suspend_disable();
+        signal_throw_exception(regs, exn_class);
+    } else {
+        remove_guard_stack(vmthread);
+        vmthread->restore_guard_page = true;
+        exn_raise_by_class(exn_class);
+    }
 
-static bool linux_throw_from_sigcontext(ucontext_t *uc, Class* exc_clss)
-{
-    // FIXME: not implemented
-    assert(0);
-    abort();
-    return false;
-}
+    if (new_ip && regs->get_ip() == new_ip)
+        regs->set_ip(saved_ip);
 
-static void throw_from_sigcontext(ucontext_t *uc, Class* exc_clss) {
-    // FIXME: not implemented
-    assert(0);
-    abort();
-    return false;
+    return TRUE;
 }
 
-
-/*
- * We find the true signal stack frame set-up by kernel,which is located
- * by locate_sigcontext() below; then change its content according to 
- * exception handling semantics, so that when the signal handler is 
- * returned, application can continue its execution in Java exception handler.
- */
-
-void null_java_reference_handler(int signum)
+Boolean null_reference_handler(port_sigtype UNREF signum, Registers* regs, void* fault_addr)
 {
-    uint32* top_ebp = NULL;
-//TODO: ADD correct stack handling here!!
-    Global_Env *env = VM_Global_State::loader_env;
-    linux_throw_from_sigcontext(top_ebp, env->java_lang_NullPointerException_Class);
-}
+    TRACE2("signals", "NPE detected at " << regs->get_ip());
 
+    assert(0); // Not implemented
+    abort();
 
-void null_java_divide_by_zero_handler(int signum)
-{
-    uint32* top_ebp = NULL;
-//TODO: ADD correct stack handling here!!
-    Global_Env *env = VM_Global_State::loader_env;
-    linux_throw_from_sigcontext(top_ebp, env->java_lang_ArithmeticException_Class);
-}
+    vm_thread_t vmthread = get_thread_ptr();
+    Global_Env* env = VM_Global_State::loader_env;
+    void* saved_ip = regs->get_ip();
+    void* new_ip = NULL;
 
-/*
-See function initialize_signals() below first please.
+    if (is_in_ti_handler(vmthread, saved_ip))
+    {
+        new_ip = vm_get_ip_from_regs(vmthread);
+        regs->set_ip(new_ip);
+    }
 
-Two kinds of signal contexts (and stack frames) are tried in
-locate_sigcontext(), one is sigcontext, which is the way of
-Linux kernel implements( see Linux kernel source
-arch/i386/kernel/signal.c for detail); the other is ucontext,
-used in some other other platforms.
-
-The sigcontext locating in Linux is not so simple as expected,
-because it involves not only the kernel, but also glibc/linuxthreads,
-which VM is linked against. In glibc/linuxthreads, user-provided
-signal handler is wrapped by linuxthreads signal handler, i.e.
-the signal handler really registered in system is not the one
-provided by user. So when Linux kernel finishes setting up signal
-stack frame and returns to user mode for singal handler execution,
-locate_sigcontext() is not the one being invoked immediately. It's 
-called by linuxthreads function. That means the user stack viewed by
-locate_sigcontext() is NOT NECESSARILY the signal frame set-up by
-kernel, we need find the true one according to glibc/linuxthreads
-specific signal implementation in different versions.
-
-Because locate_sigcontext() uses IA32 physical register epb for
-call stack frame, compilation option `-fomit-frame-pointer' MUST
-not be used when gcc compiles it; and as gcc info, `-O2' will do
-`-fomit-frame-pointer' by default, although we haven't seen that
-in our experiments.
-*/
+    if (check_stack_overflow(regs, fault_addr))
+    {
+        Boolean result = stack_overflow_handler(signum, regs, fault_addr);
 
-volatile void locate_sigcontext(int signum)
-{
-    sigcontext *sc, *found_sc;
-    uint32 *ebp = NULL;
-    int i;
-
-//TODO: ADD correct stack handling here!!
-
-#define SC_SEARCH_WIDTH 3
-    for (i = 0; i < SC_SEARCH_WIDTH; i++) {
-        sc = (sigcontext *)(ebp + 3 );
-        if (sc->sc_ip == ((uint32)exam_point)) {    // found
-            sc_nest = i;
-            use_ucontext = false;
-            found_sc = sc;
-        // we will try to find the real sigcontext setup by Linux kernel,
-        // because if we want to change the execution path after the signal
-        // handling, we must modify the sigcontext used by kernel. 
-        // LinuxThreads in glibc 2.1.2 setups a sigcontext for our singal
-        // handler, but we should not modify it, because kernel doesn't use 
-        // it when resumes the application. Then we must find the sigcontext
-        // setup by kernel, and modify it in singal handler. 
-        // but, with glibc 2.2.3, it's useless to modify only the sigcontext
-        // setup by Linux kernel, because LinuxThreads does a interesting 
-        // copy after our signal handler returns, which destroys the 
-        // modification we have just done in the handler. So with glibc 2.2.3,
-        // what we need do is simply to modify the sigcontext setup by 
-        // LinuxThreads, which will be copied to overwrite the one setup by 
-        // kernel. Really complicated..., not really. We use a simple trick
-        // to overcome the changes in glibc from version to version, that is,
-        // we modify both sigcontexts setup by kernel and LinuxThreads. Then
-        // it will always work. 
-
-        } else {                    // not found
-            struct ucontext *uc;
-            uc = (struct ucontext *)((uint64)ebp[4]);
-            if ((ebp < (uint32 *)uc) && ((uint32 *)uc < ebp + 0x100)) {
-                sc = (sigcontext *)&uc->uc_mcontext;
-                if (sc->sc_ip == ((uint32)exam_point)) {    // found
-                    sc_nest = i;
-                    use_ucontext = true;
-                    found_sc = sc;
-                    break; 
-                }
-            }
-        }
+        if (new_ip && regs->get_ip() == new_ip)
+            regs->set_ip(saved_ip);
 
-        ebp = (uint32 *)((uint64)ebp[0]);
+        return result;
     }
 
-    if (sc_nest < 0) {
-        printf("cannot locate sigcontext.\n");
-        printf("Please add or remove any irrelevant statement(e.g. add a null printf) in VM source code, then rebuild it. If problem remains, please submit a bug report. Thank you very much\n");
-        exit(1);
+    if (!vmthread || env == NULL ||
+        !is_in_java(regs) || interpreter_enabled())
+        return FALSE; // Crash
+
+    // Pass exception to NCAI exception handler
+    bool is_handled = 0;
+    ncai_process_signal_event((NativeCodePtr)regs->get_ip(),
+                                (jint)signum, false, &is_handled);
+    if (is_handled)
+    {
+        if (new_ip)
+            regs->set_ip(saved_ip);
+        return TRUE;
     }
-}
 
+    signal_throw_java_exception(regs, env->java_lang_NullPointerException_Class);
 
+    if (new_ip && regs->get_ip() == new_ip)
+        regs->set_ip(saved_ip);
 
-#endif
+    return TRUE;
+}

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/natives_support.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/natives_support.cpp?rev=638327&r1=638326&r2=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/natives_support.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/natives_support.cpp Tue Mar 18 04:31:02 2008
@@ -39,8 +39,6 @@
 #include "jni_types.h"
 #include "jni_utils.h"
 
-#include "stack_dump.h" // To update modules list on library load (in debug)
-
 #define LOG_DOMAIN "natives"
 #include "cxxlog.h"
 
@@ -298,8 +296,6 @@
 
     returnCode = pinfo->handle;
 
-    sd_update_modules(); // Updates modules list for crash handling (in debug)
-
 NATIVES_LOAD_LIBRARY_EXIT :
 
 #ifdef PLATFORM_NT
@@ -747,7 +743,7 @@
     if (!filepointer)
         return NULL;
 
-    if (strlen(filepointer) > _MAX_PATH)
+    if (strlen(filepointer) > PORT_PATH_MAX)
         return NULL;
 
     strcpy(buf, filepointer);
@@ -762,7 +758,7 @@
 // Method is stupid and slow but it works for full and partial names
 bool natives_is_library_loaded_slow(const char* libname)
 {
-    char src_buf[_MAX_PATH + 1], cmp_buf[_MAX_PATH + 1];
+    char src_buf[PORT_PATH_MAX + 1], cmp_buf[PORT_PATH_MAX + 1];
 
     if (short_name(libname, src_buf) == NULL)
         return false; // Error case

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/signals.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/signals.cpp?rev=638327&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/signals.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/signals.cpp Tue Mar 18 04:31:02 2008
@@ -0,0 +1,125 @@
+/*
+ *  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.
+ */
+
+#define LOG_DOMAIN "signals"
+#include "cxxlog.h"
+
+#include "open/platform_types.h"
+#include "port_crash_handler.h"
+#include "init.h"
+#include "vm_threads.h"
+#include "environment.h"
+#include "signals.h"
+
+
+Boolean abort_handler(port_sigtype UNREF signum, Registers* UNREF regs, void* fault_addr)
+{
+    TRACE2("signals", "Abort detected at " << regs->get_ip());
+    // Crash always
+    return FALSE;
+}
+
+Boolean ctrl_backslash_handler(port_sigtype UNREF signum, Registers* UNREF regs, void* UNREF fault_addr)
+{
+    TRACE2("signals", "Ctrl+\\ pressed");
+    vm_dump_handler();
+    return TRUE;
+}
+
+Boolean ctrl_break_handler(port_sigtype UNREF signum, Registers* UNREF regs, void* UNREF fault_addr)
+{
+    TRACE2("signals", "Ctrl+Break pressed");
+    vm_dump_handler();
+    return TRUE;
+}
+
+Boolean ctrl_c_handler(port_sigtype UNREF signum, Registers* UNREF regs, void* UNREF fault_addr)
+{
+    TRACE2("signals", "Ctrl+C pressed");
+    vm_interrupt_handler();
+    // Continue execution - the process will be terminated from
+    // the separate thread started in vm_interrupt_handler()
+    return TRUE;
+}
+
+Boolean native_breakpoint_handler(port_sigtype UNREF signum, Registers* regs, void* fault_addr)
+{
+    TRACE2("signals", "Native breakpoint detected at " << regs->get_ip());
+#ifdef _IPF_
+    assert(0); // Not implemented
+    abort();
+#endif
+
+    if (VM_Global_State::loader_env == NULL || interpreter_enabled())
+        return FALSE; // Crash
+
+    vm_thread_t vmthread = get_thread_ptr();
+
+    if (is_in_ti_handler(vmthread, regs->get_ip()))
+        // Breakpoints should not occur in breakpoint buffer
+        return FALSE; // Crash
+
+    // Pass exception to NCAI exception handler
+    bool is_handled = 0;
+    ncai_process_signal_event((NativeCodePtr)regs->get_ip(),
+                                (jint)signum, true, &is_handled);
+    if (is_handled)
+        return TRUE;
+
+    return (Boolean)jvmti_jit_breakpoint_handler(regs);
+}
+
+Boolean arithmetic_handler(port_sigtype UNREF signum, Registers* regs, void* fault_addr)
+{
+    TRACE2("signals", "ArithmeticException detected at " << regs->get_ip());
+#ifdef _IPF_
+    assert(0); // Not implemented
+    abort();
+#endif
+
+    vm_thread_t vmthread = get_thread_ptr();
+    void* saved_ip = regs->get_ip();
+    void* new_ip = NULL;
+
+    if (is_in_ti_handler(vmthread, saved_ip))
+    {
+        new_ip = vm_get_ip_from_regs(vmthread);
+        regs->set_ip(new_ip);
+    }
+
+    // Pass exception to NCAI exception handler
+    bool is_handled = 0;
+    ncai_process_signal_event((NativeCodePtr)regs->get_ip(),
+                                (jint)signum, false, &is_handled);
+    if (is_handled)
+    {
+        if (new_ip)
+            regs->set_ip(saved_ip);
+        return TRUE;
+    }
+
+    if (!vmthread || VM_Global_State::loader_env == NULL ||
+        !is_in_java(regs) || interpreter_enabled())
+        return FALSE; // Crash
+
+    signal_throw_java_exception(regs, VM_Global_State::loader_env->java_lang_ArithmeticException_Class);
+
+    if (new_ip && regs->get_ip() == new_ip)
+        regs->set_ip(saved_ip);
+
+    return TRUE;
+}