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 [2/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...

Copied: harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/linux/stack_dump_os.cpp (from r637971, harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/stack_dump_platf.cpp)
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/linux/stack_dump_os.cpp?p2=harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/linux/stack_dump_os.cpp&p1=harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/stack_dump_platf.cpp&r1=637971&r2=638327&rev=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/stack_dump_platf.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/linux/stack_dump_os.cpp Tue Mar 18 04:31:02 2008
@@ -16,57 +16,24 @@
  */
 
 #include <sys/types.h>
-#include <sys/wait.h>
 #include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/wait.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "open/hythread_ext.h"
-#include "native_stack.h"
-#include "port_filepath.h"
 #include "port_dso.h"
-#include "port_thread.h"
+#include "port_malloc.h"
 #include "stack_dump.h"
 
 
-static hymutex_t g_lock;
-static const char* g_curdir = NULL;
-static const char* g_cmdline = NULL;
-
-
-bool sd_initialize(hymutex_t** p_lock)
-{
-    static int initialized = 0;
-
-    if (!initialized)
-    {
-        IDATA err = hymutex_create(&g_lock, APR_THREAD_MUTEX_NESTED);
-
-        if (err != APR_SUCCESS)
-            return false;
-
-        initialized = true;
-    }
-
-    if (p_lock)
-        *p_lock = &g_lock;
-
-    return true;
-}
-
-
-static bool sd_is_predefined_name(const char* name)
-{
-    if (*name != '[')
-        return false;
+static char* g_curdir = NULL;
+static char* g_cmdline = NULL;
 
-    return true;
-//    return (!strcmp(name, "[heap]") ||
-//            !strcmp(name, "[stack]") ||
-//            !strcmp(name, "[vdso]"));
-}
 
 static inline native_segment_t* sd_find_segment(native_module_t* module, void* ip)
 {
@@ -81,48 +48,10 @@
     return NULL;
 }
 
-void sd_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 = sd_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 (sd_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 = sd_get_module_type(short_name);
-
-    fprintf(stderr, "%s\n(%s)\n", module->filename, module_type);
-}
-
-
-void sd_get_c_method_info(MethodInfo* info, native_module_t* module, void* ip)
+void sd_get_c_method_info(CFunInfo* info, native_module_t* module, void* ip)
 {
-    *info->method_name = 0;
-    *info->file_name = 0;
+    *info->name = 0;
+    *info->filename = 0;
     info->line = -1;
 
     if (!module || !module->filename)
@@ -154,7 +83,7 @@
     else
     {
         close(po[1]);
-        char buf[sizeof(info->method_name) + sizeof(info->file_name)];
+        char buf[sizeof(info->name) + sizeof(info->filename)];
         int status;
         wait(&status);
         int count = read(po[0], buf, sizeof(buf) - 1);
@@ -177,7 +106,7 @@
             if (buf[i] == '\n')
             { // Function name is limited by '\n'
                 buf[i] = '\0';
-                strncpy(info->method_name, buf, sizeof(info->method_name));
+                strncpy(info->name, buf, sizeof(info->name));
                 break;
             }
         }
@@ -193,7 +122,7 @@
             return;
 
         buf[i] = '\0';
-        strncpy(info->file_name, fn, sizeof(info->file_name));
+        strncpy(info->filename, fn, sizeof(info->filename));
 
         info->line = atoi(buf + i + 1); // Line number
 
@@ -202,11 +131,6 @@
     }
 }
 
-int sd_get_cur_tid()
-{
-    return gettid();
-}
-
 void sd_init_crash_handler()
 {
     // Get current directory
@@ -251,15 +175,24 @@
     }
 }
 
-void sd_print_cwdcmdenv()
+void sd_cleanup_crash_handler()
 {
-    fprintf(stderr, "\nWorking directory:\n%s\n", g_curdir ? g_curdir : "'null'");
+    STD_FREE(g_curdir);
+    STD_FREE(g_cmdline);
+}
 
+void sd_print_cmdline_cwd()
+{
     fprintf(stderr, "\nCommand line:\n");
     for (const char* ptr = g_cmdline; *ptr; ptr += strlen(ptr) + 1)
         fprintf(stderr, "%s ", ptr);
     fprintf(stderr, "\n");
 
+    fprintf(stderr, "\nWorking directory:\n%s\n", g_curdir ? g_curdir : "'null'");
+}
+
+void sd_print_environment()
+{
     fprintf(stderr, "\nEnvironment variables:\n");
     for (char** env = environ; *env; ++env)
         fprintf(stderr, "%s\n", *env);

Added: harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/native_unwind.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/native_unwind.cpp?rev=638327&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/native_unwind.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/native_unwind.cpp Tue Mar 18 04:31:02 2008
@@ -0,0 +1,98 @@
+/*
+ *  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.
+ */
+/**
+ * @author Ilya Berezhniuk
+ * @version $Revision: 1.1.2.1 $
+ */
+
+#include <string.h>
+#include "port_modules.h"
+#include "native_unwind.h"
+
+
+//////////////////////////////////////////////////////////////////////////////
+/// Helper functions
+
+bool native_is_in_stack(UnwindContext* context, void* sp)
+{
+    return (sp >= context->stack.base &&
+            sp < (char*)context->stack.base + context->stack.size);
+}
+
+/// Helper functions
+//////////////////////////////////////////////////////////////////////////////
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+
+bool port_init_unwind_context(UnwindContext* 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 port_clean_unwind_context(UnwindContext* context)
+{
+    if (!context)
+        return;
+
+    if (context->modules && context->clean_modules)
+    {
+        port_clear_modules(&context->modules);
+    }
+
+    context->modules = NULL;
+}
+
+bool port_unwind_frame(UnwindContext* context, Registers* regs)
+{
+//    if (native_is_frame_exists(context, regs))
+//    { // Stack frame (x86)
+//        return native_unwind_stack_frame(context, regs);
+//    }
+//    else
+    { // Stack frame does not exist, try using heuristics
+        return native_unwind_special(context, regs);
+    }
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/native_unwind.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/port_crash_handler.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/port_crash_handler.cpp?rev=638327&r1=638326&r2=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/port_crash_handler.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/port_crash_handler.cpp Tue Mar 18 04:31:02 2008
@@ -16,15 +16,22 @@
  */
 
 #include <assert.h>
+#include <stdlib.h>
+#include "port_malloc.h"
+#include "port_mutex.h"
+#include "stack_dump.h"
+#include "signals_internal.h"
 #include "port_crash_handler.h"
 
-static port_signal_handler signal_callbacks[PORT_SIGNAL_MAX] =
+static port_signal_handler signal_callbacks[] =
 {
     NULL, // PORT_SIGNAL_GPF
     NULL, // PORT_SIGNAL_STACK_OVERFLOW
     NULL, // PORT_SIGNAL_ABORT
-    NULL, // PORT_SIGNAL_TRAP
-    NULL, // PORT_SIGNAL_PRIV_INSTR
+    NULL, // PORT_SIGNAL_QUIT
+    NULL, // PORT_SIGNAL_CTRL_BREAK
+    NULL, // PORT_SIGNAL_CTRL_C
+    NULL, // PORT_SIGNAL_BREAKPOINT
     NULL  // PORT_SIGNAL_ARITHMETIC
 };
 
@@ -36,32 +43,70 @@
 
 static crash_additional_actions *crash_actions = NULL;
 
-static unisigned crash_output_flags;
+static unsigned crash_output_flags;
 
-Boolean port_init_crash_handler(port_signal_handler_registration *registrations,
-    unsigned count)
+static osmutex_t g_mutex;
+
+static port_unwind_compiled_frame g_unwind_callback = NULL;
+
+
+Boolean port_init_crash_handler(
+    port_signal_handler_registration *registrations,
+    unsigned count,
+    port_unwind_compiled_frame unwind_callback)
 {
-    if (initialize_signals() == FALSE)
+    if (initialize_signals() != 0)
         return FALSE;
 
-    for (int iii = 0; iii < count; iii++)
+	if (init_private_tls_data() != 0)
+	    return FALSE;
+
+    port_mutex_create(&g_mutex, APR_THREAD_MUTEX_NESTED);
+
+    sd_init_crash_handler();
+
+    for (unsigned iii = 0; iii < count; iii++)
     {
-        assert(registrations[iii]->signum >= PORT_SIGNAL_MIN);
-        assert(registrations[iii]->signum <= PORT_SIGNAL_MAX);
-        signal_callbacks[registrations[iii]->signum] = registrations[iii]->callback;
+        assert(registrations[iii].signum >= PORT_SIGNAL_MIN);
+        assert(registrations[iii].signum <= PORT_SIGNAL_MAX);
+        signal_callbacks[registrations[iii].signum] = registrations[iii].callback;
     }
 
+    g_unwind_callback = unwind_callback;
+
     return TRUE;
 }
 
-void port_crash_handler_set_flags(port_crash_handler_flags flags)
+unsigned port_crash_handler_get_capabilities()
+{
+    // Return the features we currently support
+    return (port_crash_handler_flags)
+           (PORT_CRASH_CALL_DEBUGGER |
+            PORT_CRASH_DUMP_TO_STDERR |
+            PORT_CRASH_STACK_DUMP |
+            PORT_CRASH_DUMP_ALL_THREADS |
+            PORT_CRASH_PRINT_COMMAND_LINE |
+            PORT_CRASH_PRINT_ENVIRONMENT |
+            PORT_CRASH_PRINT_MODULES |
+            PORT_CRASH_PRINT_REGISTERS |
+            PORT_CRASH_DUMP_PROCESS_CORE);
+
+}
+
+void port_crash_handler_set_flags(unsigned flags)
 {
     crash_output_flags = flags;
 }
 
+unsigned port_crash_handler_get_flags()
+{
+    return crash_output_flags;
+}
+
 Boolean port_crash_handler_add_action(port_crash_handler_action action)
 {
-    crash_additional_actions *a = STD_MALLOC(sizeof(crash_additional_actions));
+    crash_additional_actions *a =
+        (crash_additional_actions*)STD_MALLOC(sizeof(crash_additional_actions));
     if (NULL == a)
         return FALSE;
 
@@ -73,9 +118,12 @@
 
 Boolean port_shutdown_crash_handler()
 {
-    if (shutdown_signals() == FALSE)
+    if (shutdown_signals() != 0)
         return FALSE;
 
+	if (free_private_tls_data() != 0)
+	    return FALSE;
+
     for (crash_additional_actions *a = crash_actions; NULL != a;)
     {
         crash_additional_actions *next = a->next;
@@ -83,5 +131,48 @@
         a = next;
     }
 
+    sd_cleanup_crash_handler();
+
+    port_mutex_destroy(&g_mutex);
+
     return TRUE;
+}
+
+/* Returns 0  when execution should be continued with (updated) Registers
+   Returns 1  when crash occured and process should invoke a debugger
+   Returns -1 when crash occured and process should be terminated */
+int port_process_signal(port_sigtype signum, Registers *regs, void* fault_addr, Boolean iscrash)
+{
+    if (!iscrash)
+    {
+        assert(signum >= PORT_SIGNAL_MIN);
+        assert(signum <= PORT_SIGNAL_MAX);
+
+        if (signal_callbacks[signum] != NULL)
+        {
+            Boolean cres = signal_callbacks[signum](signum, regs, fault_addr);
+
+            if (cres) // signal was processed
+                return 0;
+        }
+    }
+
+    // CRASH
+    port_mutex_lock(&g_mutex);
+
+    sd_print_crash_info(signum, regs, g_unwind_callback);
+
+    for (crash_additional_actions* action = crash_actions;
+         action; action = action->next)
+    {
+        action->action(signum, regs, fault_addr);
+    }
+
+    if ((crash_output_flags & PORT_CRASH_CALL_DEBUGGER) != 0)
+    {
+        port_mutex_unlock(&g_mutex);
+        return 1;
+    }
+
+    return -1;
 }

Copied: harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/stack_dump.cpp (from r637971, harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp)
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/stack_dump.cpp?p2=harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/stack_dump.cpp&p1=harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp&r1=637971&r2=638327&rev=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/stack_dump.cpp Tue Mar 18 04:31:02 2008
@@ -14,28 +14,23 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-/** 
- * @author Vladimir Nenashev
- * @version $Revision$
- */  
 
 #include <ctype.h>
-#include "vm_threads.h"
+#include <assert.h>
+#include <string.h>
+// offsetof macro
+#if defined(WIN32)
+#include <stddef.h>
+#else
+#include <objalloc.h>
+#endif
+
 #include "port_malloc.h"
-#include "port_dso.h"
-#include "jit_intf_cpp.h"
-#include "Class.h"
-#include "class_member.h"
-#include "exceptions.h"
-#include "stack_trace.h"
-#include "interpreter_exports.h"
-#include "cci.h"
-#include "m2n.h"
-#include "native_stack.h"
-#include "native_modules.h"
-#include "natives_support.h"
-#include "exception_filter.h"
+#include "port_unwind.h"
+#include "port_modules.h"
 
+#include "port_crash_handler.h"
+#include "port_frame_info.h"
 #include "stack_dump.h"
 
 
@@ -52,461 +47,222 @@
     assert(res && g_modules && count);
 }
 
-#ifdef SD_UPDATE_MODULES
-// Is called to update modules info
-void sd_update_modules()
-{
-    hymutex_t* sd_lock;
-    bool res = sd_initialize(&sd_lock);
-
-    if (!res)
-        return;
-
-    hymutex_lock(sd_lock);
 
-    if (g_modules)
-        port_clear_modules(&g_modules);
+// "%s::%s (%s): %s:%d" - class::name (signature): file:line
+static const char* vm_fmt_tbl[] = {
+// method_class_name is present
+    "%s::%s (%s): %s:%d\n",
+    "%s::%s (%s)\n", // No sourcefile
+    "%s::%s: %s:%d\n", // No signature
+    "%s::%s\n", // No signature no sourcefile
+// method_class_name is absent
+    "%s (%s): %s:%d\n",
+    "%s (%s)\n", // No sourcefile
+    "%s: %s:%d\n", // No signature
+    "%s\n", // No signature no sourcefile
+};
 
-    int count;
-    res = port_get_all_modules(&g_modules, &count);
-    assert(res && g_modules && count);
-
-    hymutex_unlock(sd_lock);
-}
-#endif // SD_UPDATE_MODULES
-
-
-static char* sd_construct_java_method_name(Method* m, char* buf)
+static void sd_print_vm_line(FILE* file, int count, port_stack_frame_info* fi)
 {
-    if (!m || !buf)
-    {
-        *buf = 0;
-        return NULL;
-    }
-
-    char* ptr = buf;
+    if (!fi->method_name)
+        return;
 
-    const char* err_str = "<--Truncated: too long name";
-    size_t err_len = strlen(err_str);
+    if (count >= 0)
+        fprintf(file, "%3d: ", count);
+    else
+        fprintf(file, "     "); // additional VM info - indent
 
-    size_t remain = SD_MNAME_LENGTH - 1;
-    const char* cname = m->get_class()->get_name()->bytes;
-    size_t clen = m->get_class()->get_name()->len;
-    const char* mname = m->get_name()->bytes;
-    size_t mlen = m->get_name()->len;
-    const char* descr = m->get_descriptor()->bytes;
-    size_t dlen = m->get_descriptor()->len;
+    const void* args[5] = {fi->method_class_name, fi->method_name,
+                     fi->method_signature, fi->source_file_name,
+                     (const void*)(size_t)fi->source_line_number};
+    const void** pargs = args;
+    int fmt_num = 0;
 
-    if (clen + 1 > remain)
+    if (!fi->method_class_name)
     {
-        size_t len = remain - err_len;
-        memcpy(ptr, cname, len);
-        strcpy(ptr + len, err_str);
-        return buf;
+        fmt_num += 4;
+        pargs++;
     }
-
-    memcpy(ptr, cname, clen);
-    ptr += clen;
-    *ptr++ = '.';
-    remain -= clen + 1;
-
-    if (mlen > remain)
+    if (!fi->method_signature)
     {
-        if (remain > err_len)
-            memcpy(ptr, mname, remain - err_len);
-
-        strcpy(ptr + remain - err_len, err_str);
-        return buf;
+        fmt_num += 2;
+        args[2] = args[3];
+        args[3] = args[4];
     }
+    if (!fi->source_file_name)
+        fmt_num += 1;
 
-    memcpy(ptr, mname, mlen);
-    ptr += mlen;
-    remain -= mlen;
-
-    if (dlen > remain)
-    {
-        if (remain > err_len)
-            memcpy(ptr, descr, remain - err_len);
-
-        strcpy(ptr + remain - err_len, err_str);
-        return buf;
-    }
-
-    strcpy(ptr, descr);
-    return buf;
+    fprintf(file, vm_fmt_tbl[fmt_num],
+                  pargs[0], pargs[1], pargs[2], pargs[3], pargs[4]);
 }
 
-static void sd_get_java_method_info(MethodInfo* info, Method* m, void* ip,
-                                    bool is_ip_past, int inl_depth)
-{
-    *info->method_name = 0;
-    *info->file_name = 0;
-    info->line = -1;
 
-    if (!m || !method_get_class(m))
-        return;
-
-    if (!sd_construct_java_method_name(m, info->method_name))
+static void sd_print_c_line(FILE* file, int count, CFunInfo* cfi)
+{
+    if (!cfi->name)
         return;
 
-    const char* fname = NULL;
-    get_file_and_line(m, ip, is_ip_past, inl_depth, &fname, &info->line);
-
-    if (fname)
-    {
-        if (strlen(fname) >= sizeof(info->file_name))
-        {
-            memcpy(info->file_name, fname, sizeof(info->file_name));
-            info->file_name[sizeof(info->file_name) - 1] = 0;
-        }
-        else
-            strcpy(info->file_name, fname);
-    }
+    fprintf(file, "%3d: %s (%s:%d)\n",
+        count, cfi->name,
+        cfi->filename ? cfi->filename : "??",
+        cfi->line);
 }
 
-static void sd_print_line(int count, MethodInfo* m) {
 
-    fprintf(stderr, "%3d: %s (%s:%d)\n",
-        count,
-        *m->method_name ? m->method_name : "??",
-        *m->file_name ? m->file_name : "??",
-        m->line);
+static void sd_print_modules()
+{
+    sd_fill_modules(); // Fill modules table if needed
+    fprintf(stderr, "\nLoaded modules:\n\n");
+    port_dump_modules(g_modules, stderr);
 }
 
 
-static void sd_print_stack_jit(VM_thread* thread,
-                        native_frame_t* frames, jint num_frames)
+static void sd_print_stack(Registers* regs, port_unwind_compiled_frame unwind)
 {
-    jint frame_num = 0;
-    jint count = 0;
-    StackIterator* si = NULL;
-
-    if (thread)
-        si = si_create_from_native(thread);
-
-    while ((si && !si_is_past_end(si)) || frame_num < num_frames)
+    if (!regs)
     {
-        MethodInfo m;
-        void* cur_ip = frames[frame_num].ip;
-
-        if (frame_num < num_frames && frames[frame_num].java_depth < 0)
-        {
-            if (native_is_ip_stub(cur_ip)) // Generated stub
-            {
-                char buf[81];
-                char* stub_name =
-                    native_get_stub_name(cur_ip, buf, sizeof(buf));
-
-                fprintf(stderr, "%3d: 0x%"W_PI_FMT": stub '%s'\n",
-                    count++, (POINTER_SIZE_INT)cur_ip,
-                    stub_name ? stub_name : "??");
-                ++frame_num;
-                continue;
-            }
-
-            // pure native frame
-            native_module_t* module = port_find_module(g_modules, cur_ip);
-            sd_get_c_method_info(&m, module, cur_ip);
-            sd_print_line(count++, &m);
-            ++frame_num;
-            continue;
-        }
+        fprintf(stderr, "No stack trace due to registers info absence\n");
+        return;
+    }
 
-        // Java/JNI frame, look into stack iterator
+    fprintf(stderr, "\nStack trace:\n");
 
-        // If iterator is exhausted
-        if (si_is_past_end(si) ||
-            (si_is_native(si) && !m2n_get_previous_frame(si_get_m2n(si))))
-            break;
+    Registers locregs = *regs;
+    UnwindContext uwcontext;
+    bool hasnative = false;
 
-        if (si_is_native(si) && frame_num < num_frames)
-        {
-            // Print information from native stack trace for JNI frames
-            native_module_t* module = port_find_module(g_modules, cur_ip);
-            sd_get_c_method_info(&m, module, cur_ip);
-            sd_print_line(count, &m);
-        }
-        else if (si_is_native(si) && frame_num >= num_frames)
-        {
-            // Print information about JNI frames from iterator
-            // when native stack trace is not available
-            Method* method = m2n_get_method(si_get_m2n(si));
-            void* ip = m2n_get_ip(si_get_m2n(si));
-            sd_get_java_method_info(&m, method, ip, false, -1);
-            sd_print_line(count, &m);
-        }
-        else // !si_is_native(si)
-        {
-            // Print information about Java method from iterator
-            CodeChunkInfo* cci = si_get_code_chunk_info(si);
-            Method* method = cci->get_method();
-            void* ip = (void*)si_get_ip(si);
-
-            uint32 inlined_depth = si_get_inline_depth(si);
-            uint32 offset = (uint32)((POINTER_SIZE_INT)ip -
-                (POINTER_SIZE_INT)cci->get_code_block_addr());
-            bool is_ip_past = (frame_num != 0);
-
-            if (inlined_depth)
-            {
-                for (uint32 i = inlined_depth; i > 0; i--)
-                {
-                    Method* inl_method = cci->get_jit()->get_inlined_method(
-                                            cci->get_inline_info(), offset, i);
-
-                    sd_get_java_method_info(&m, inl_method, ip, is_ip_past, i);
-                    sd_print_line(count++, &m);
-
-                    if (frame_num < num_frames)
-                        ++frame_num; // Go to the next native frame
-                }
-            }
+    if (port_init_unwind_context(&uwcontext, g_modules, &locregs))
+        hasnative = true;
 
-            sd_get_java_method_info(&m, method, ip, is_ip_past, -1);
-            sd_print_line(count, &m);
-        }
+    port_stack_frame_info uwinfo;
 
-        ++count;
-        si_goto_previous(si);
+    int framenum = 0;
+    int uwresult = -1;
 
-        if (frame_num < num_frames)
-            ++frame_num; // Go to the next native frame
+    // Prepare VM-specific struct for stack iteration
+    if (unwind)
+    {
+        memset(&uwinfo, 0, sizeof(port_stack_frame_info));
+        uwresult = unwind(&locregs, &uwinfo);
     }
 
-    if (si)
-        si_free(si);
-}
-
-static void sd_print_stack_interpreter(VM_thread* thread,
-    native_frame_t* frames, jint num_frames)
-{
-    FrameHandle* frame = interpreter.interpreter_get_last_frame(thread);
-    jint frame_num = 0;
-    jint count = 0;
-
-    while (frame || frame_num < num_frames)
+    if (uwresult > 0)
     {
-        MethodInfo m;
+        uwinfo.iteration_state = STD_ALLOCA(uwresult);
+        memset(uwinfo.iteration_state, 0, uwresult);
+        uwresult = unwind(&locregs, &uwinfo);
+        assert(uwresult <= 0);
+    }
 
-        if (frame_num < num_frames && frames[frame_num].java_depth < 0)
-        { // pure native frame
-            native_module_t* module = port_find_module(g_modules, frames[frame_num].ip);
-            sd_get_c_method_info(&m, module, frames[frame_num].ip);
-            sd_print_line(count++, &m);
-            ++frame_num;
+    while (true)
+    {
+        // Unwinding with VM callback
+        if (unwind && uwresult == 0)
+        {
+            sd_print_vm_line(stderr, framenum++, &uwinfo);
+            // Cleanup frame info except 'iteration_state'
+            memset(&uwinfo, 0, offsetof(port_stack_frame_info, iteration_state));
+            // Try unwinding by the callback for next iteration
+            uwresult = unwind(&locregs, &uwinfo);
             continue;
         }
 
-        // Java/JNI frame, look into stack iterator
-
-        Method* method = (Method*)interpreter.interpreter_get_frame_method(frame);
-        uint8* bc_ptr = interpreter.interpreter_get_frame_bytecode_ptr(frame);
-
-        // Print information from native stack trace
-        // when method is not available or is native
-        if (frame_num < num_frames &&
-            (!method || method_is_native(method)))
-        {
-            native_module_t* module = port_find_module(g_modules, frames[frame_num].ip);
-            sd_get_c_method_info(&m, module, frames[frame_num].ip);
-            sd_print_line(count, &m);
+        // Print native frame info
+        CFunInfo cfi = {0};
+        native_module_t* module = port_find_module(g_modules, locregs.get_ip());
+        sd_get_c_method_info(&cfi, module, locregs.get_ip());
+        sd_print_c_line(stderr, framenum++, &cfi);
+
+        if (unwind && uwresult < 0 && uwinfo.method_name)
+        { // VM has not unwound but has provided additional frame info
+            sd_print_vm_line(stderr, -1, &uwinfo); // Print as additional info
         }
 
-        // Print information about method from iterator
-        // when is Java method or when native stack trace is not available
-        if (method &&
-            (!method_is_native(method) || frame_num >= num_frames))
-        {
-            sd_get_java_method_info(&m, method, (void*)bc_ptr, false, -1);
-            sd_print_line(count, &m);
-        }
-
-        ++count;
-        frame = interpreter.interpreter_get_prev_frame(frame);
-
-        if (frame_num < num_frames)
-            ++frame_num; // Go to the next native frame
-    }
-}
-
-const char* sd_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 (!hasnative) // Native unwinding is not initialized
+            break;
 
-    if (!memcmp(short_name, PORT_DSO_PREFIX, strlen(PORT_DSO_PREFIX)))
-        nameptr += strlen(PORT_DSO_PREFIX);
+        // Try native unwinding
+        bool nativeres = port_unwind_frame(&uwcontext, &locregs);
 
-    char* vm_modules[] = {"java", "em", "encoder", "gc_gen", "gc_gen_uncomp", "gc_cc",
-        "harmonyvm", "hythr", "interpreter", "jitrino", "vmi"};
+        if (!nativeres)
+            break; // Neither VM calback nor native unwinding can unwind the frame
 
-    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";
+        // Cleanup frame info except 'iteration_state'
+        memset(&uwinfo, 0, offsetof(port_stack_frame_info, iteration_state));
+        // Try unwinding by the callback for next iteration
+        uwresult = unwind(&locregs, &uwinfo);
     }
 
-    if (natives_is_library_loaded_slow(short_name))
-        return "JNI native library";
+    if (hasnative)
+        port_clean_unwind_context(&uwcontext);
 
-    return "Unknown/system native module";
+    fprintf(stderr, "<end of stack trace>\n");
+    fflush(stderr);
 }
 
 
-static void sd_print_module_info(Registers* regs)
+struct sig_name_t
 {
-#ifdef SD_UPDATE_MODULES
-    sd_fill_modules(); // Fill modules table if needed
-#endif
+    int    num;
+    char*  name;
+};
 
-    native_module_t* module = port_find_module(g_modules, (void*)regs->get_ip());
-    sd_parse_module_info(module, (void*)regs->get_ip());
-}
-
-static void sd_print_modules()
+static sig_name_t sig_names[] =
 {
-    fprintf(stderr, "\nLoaded modules:\n\n");
-    port_dump_modules(g_modules, stderr);
-}
-
+    {PORT_SIGNAL_GPF,            "GENERAL_PROTECTION_FAULT"},
+    {PORT_SIGNAL_STACK_OVERFLOW, "STACK_OVERFLOW"},
+    {PORT_SIGNAL_ABORT,          "ABORT" },
+    {PORT_SIGNAL_QUIT,           "QUIT"},
+    {PORT_SIGNAL_CTRL_C,         "CTRL_C" },
+    {PORT_SIGNAL_CTRL_BREAK,     "CTRL_BREAK" },
+    {PORT_SIGNAL_BREAKPOINT,     "BREAKPOINT"},
+    {PORT_SIGNAL_ARITHMETIC,     "ARITHMETIC_EXCEPTION" },
+    {PORT_SIGNAL_UNKNOWN,        "UNKNOWN"}
+};
 
-static void sd_print_threads_info(VM_thread* cur_thread)
+static const char* get_sig_name(int signum)
 {
-    if (!cur_thread)
-        fprintf(stderr, "\nCurrent thread is not attached to VM, ID: %d\n", sd_get_cur_tid());
-
-    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++)
+    for (int i = 0; i < sizeof(sig_names)/sizeof(sig_names[0]); 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);
-        }
+        if (signum == sig_names[i].num)
+            return sig_names[i].name;
     }
 
-    hythread_iterator_release(&it);
+    return "unknown signal";
 }
 
-
-void sd_print_stack(Registers* regs)
+static void print_name_and_context(int signum, Registers* regs)
 {
-    hymutex_t* sd_lock;
-    int disable_count;
-    bool unwindable;
-
-    VM_thread* thread = get_thread_ptr(); // Can be NULL for pure native thread
-
-    // Enable suspend to allow working with threads
-    if (thread)
-        disable_count = hythread_reset_suspend_disable();
+    // Print signal name
+    fprintf(stderr, "\nSignal reported: %s\n", get_sig_name(signum));
 
-    // Acquire global lock to print threads list and stop other crashed threads
-    hythread_global_lock();
-
-    if (!sd_initialize(&sd_lock))
-        return;
+    // Print register state
+    if (regs)
+        print_reg_state(regs);
+    else
+        fprintf(stderr, "\nRegisters info is absent\n");
+}
 
-    hymutex_lock(sd_lock);
-    if (thread)
-        unwindable = set_unwindable(false); // To call Java code
 
-    // Print register info
-    print_reg_state(regs);
+void sd_print_crash_info(int signum, Registers* regs, port_unwind_compiled_frame unwind)
+{
+    // Print signal name and register info
+    if (port_crash_handler_get_flags() & PORT_CRASH_PRINT_REGISTERS)
+        print_name_and_context(signum, regs);
 
-    // Print crashed modile info
-    sd_print_module_info(regs);
+    // Print command line and working directory
+    if (port_crash_handler_get_flags() & PORT_CRASH_PRINT_COMMAND_LINE)
+        sd_print_cmdline_cwd();
 
     // Print program environment info
-    sd_print_cwdcmdenv();
+    if (port_crash_handler_get_flags() & PORT_CRASH_PRINT_ENVIRONMENT)
+        sd_print_environment();
 
     // Print the whole list of modules
-    sd_print_modules();
-
-    native_frame_t* frames = NULL;
-
-    // Print threads info
-    sd_print_threads_info(thread);
-
-    // We are trying to get native stack trace using walk_native_stack_registers
-    // function and get corresponding Java methods for stack trace from
-    // JIT/interpreter stack iterator.
-    // When native stack trace is not complete (for example, when
-    // walk_native_stack_registers cannot unwind frames in release build),
-    // we will use JIT/interpreter stack iterator to complete stack trace.
-
-    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)
-            walk_native_stack_registers(&context, regs, thread, num_frames, frames);
-        else
-            num_frames = 0; // Consider native stack trace empty
-
-        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);
-
-        fprintf(stderr, "<end of stack trace>\n");
-        fflush(stderr);
-    }
-
-    if (thread)
-        set_unwindable(unwindable);
-
-    // Do not unlock to prevent other threads from printing crash stack
-    //hymutex_unlock(sd_lock);
+    if (port_crash_handler_get_flags() & PORT_CRASH_PRINT_MODULES)
+        sd_print_modules();
 
-    hythread_global_unlock();
-    if (thread)
-        hythread_set_suspend_disable(disable_count);
+    // Print stack of crashed module
+    if (port_crash_handler_get_flags() & PORT_CRASH_STACK_DUMP)
+        sd_print_stack(regs, unwind);
 }

Copied: harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/win/native_unwind_os.cpp (from r637971, harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_stack_os.cpp)
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/win/native_unwind_os.cpp?p2=harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/win/native_unwind_os.cpp&p1=harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_stack_os.cpp&r1=637971&r2=638327&rev=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_stack_os.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/win/native_unwind_os.cpp Tue Mar 18 04:31:02 2008
@@ -16,11 +16,12 @@
  */
 
 
-#include "native_modules.h"
-#include "native_stack.h"
+#include "open/hythread_ext.h" // for correct Windows.h inclusion
+#include "port_modules.h"
+#include "native_unwind.h"
 
 
-bool native_is_in_code(WalkContext* context, void* ip)
+bool native_is_in_code(UnwindContext* context, void* ip)
 {
     if (!ip)
         return false;
@@ -37,7 +38,7 @@
                     PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) != 0);
 }
 
-bool native_get_stack_range(WalkContext* context, Registers* regs, native_segment_t* seg)
+bool native_get_stack_range(UnwindContext* context, Registers* regs, native_segment_t* seg)
 {
     MEMORY_BASIC_INFORMATION mem_info;
 

Copied: harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/win/stack_dump_os.cpp (from r637971, harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/stack_dump_platf.cpp)
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/win/stack_dump_os.cpp?p2=harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/win/stack_dump_os.cpp&p1=harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/stack_dump_platf.cpp&r1=637971&r2=638327&rev=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/stack_dump_platf.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/crash_handler/win/stack_dump_os.cpp Tue Mar 18 04:31:02 2008
@@ -15,10 +15,10 @@
  *  limitations under the License.
  */
 
-#include "open/hythread_ext.h"
-#include "native_stack.h"
+#include <string.h>
+#include "open/hythread_ext.h" // for correct Windows.h inclusion
+#include "port_malloc.h"
 #include "stack_dump.h"
-#include "port_filepath.h"
 
 #ifndef NO_DBGHELP
 #include <dbghelp.h>
@@ -26,10 +26,9 @@
 #endif
 
 
-static hymutex_t g_lock;
-static const char* g_curdir = NULL;
-static const char* g_cmdline = NULL;
-static const char* g_environ = NULL;
+static char* g_curdir = NULL;
+static char* g_cmdline = NULL;
+static char* g_environ = NULL;
 
 #ifndef NO_DBGHELP
 typedef BOOL (WINAPI *SymFromAddr_type)
@@ -49,111 +48,80 @@
     OUT PDWORD                pdwDisplacement,
     OUT PIMAGEHLP_LINE        Line    );
 
+typedef BOOL (WINAPI *MiniDumpWriteDump_type)
+   (HANDLE          hProcess,
+    DWORD           ProcessId,
+    HANDLE          hFile,
+    MINIDUMP_TYPE   DumpType,
+    PMINIDUMP_EXCEPTION_INFORMATION   ExceptionParam,
+    PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
+    PMINIDUMP_CALLBACK_INFORMATION    CallbackParam);
+
 static SymFromAddr_type g_SymFromAddr = NULL;
 static SymGetLineFromAddr64_type g_SymGetLineFromAddr64 = NULL;
 static SymGetLineFromAddr_type g_SymGetLineFromAddr = NULL;
 #endif // #ifndef NO_DBGHELP
 
 
-bool sd_initialize(hymutex_t** p_lock)
-{
-    static int initialized = 0;
-
-    if (!initialized)
-    {
-        IDATA err = hymutex_create(&g_lock, APR_THREAD_MUTEX_NESTED);
-
-        if (err != APR_SUCCESS)
-            return false;
 
+void create_minidump(LPEXCEPTION_POINTERS exp)
+{
 #ifndef NO_DBGHELP
-// Preventive initialization does not work
-//        if (!SymInitialize(GetCurrentProcess(), NULL, TRUE))
-//            return false;
+    MINIDUMP_EXCEPTION_INFORMATION mei = {GetCurrentThreadId(), exp, TRUE};
+    MiniDumpWriteDump_type mdwd = NULL;
 
-        HMODULE hdbghelp = ::LoadLibrary("dbghelp");
+    HMODULE hdbghelp = ::LoadLibrary("dbghelp");
 
-        if (hdbghelp)
-        {
-            SymSetOptions(SYMOPT_LOAD_LINES);
-            g_SymFromAddr = (SymFromAddr_type)::GetProcAddress(hdbghelp, "SymFromAddr");
-            g_SymGetLineFromAddr64 = (SymGetLineFromAddr64_type)::GetProcAddress(hdbghelp, "SymGetLineFromAddr64");
-            g_SymGetLineFromAddr = (SymGetLineFromAddr_type)::GetProcAddress(hdbghelp, "SymGetLineFromAddr");
-        }
-#endif // #ifndef NO_DBGHELP
+    if (hdbghelp)
+        mdwd = (MiniDumpWriteDump_type)::GetProcAddress(hdbghelp, "MiniDumpWriteDump");
 
-        initialized = true;
+    if (!mdwd)
+    {
+        fprintf(stderr, "\nFailed to open DbgHelp library\n");
+        fflush(stderr);
+        return;
     }
 
-    if (p_lock)
-        *p_lock = &g_lock;
-
-    return true;
-}
-
-
-static const char* sd_get_region_access_info(MEMORY_BASIC_INFORMATION* pinfo)
-{
-    if ((pinfo->State & MEM_COMMIT) == 0)
-        return "not committed";
-
-    if ((pinfo->Protect & PAGE_GUARD) != 0)
-        return "guard page occured";
+    char filename[24];
+    sprintf(filename, "minidump_%d.dmp", GetCurrentProcessId());
 
-    if ((pinfo->Protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ |
-                          PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY |
-                          PAGE_READWRITE | PAGE_READONLY)) != 0)
-        return "";
+    HANDLE file = CreateFile(filename, GENERIC_WRITE, 0, 0,
+                                CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
 
-    if ((pinfo->Protect & (PAGE_READWRITE | PAGE_READONLY)) != 0)
-        return "without execution rights";
-
-    return "without read rights";;
-}
-
-void sd_parse_module_info(native_module_t* module, void* ip)
-{
-    fprintf(stderr, "\nCrashed module:\n");
-
-    if (module)
+    if (file == INVALID_HANDLE_VALUE)
     {
-        native_segment_t* segment = module->segments;
+        fprintf(stderr, "\nFailed to create minidump file: %s\n", filename);
+        fflush(stderr);
+        return;
+    }
 
-        assert(module->filename);
+    SymInitialize(GetCurrentProcess(), NULL, TRUE);
 
-        if (!module->filename)
-        { // We should not reach this code
-            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;
-        }
+    BOOL res = mdwd(GetCurrentProcess(), GetCurrentProcessId(),
+                                file, MiniDumpNormal, &mei, 0, 0);
 
-        // Common shared module
-        const char* short_name = port_filepath_basename(module->filename);
-        const char* module_type = sd_get_module_type(short_name);
-        fprintf(stderr, "%s\n(%s)\n", module->filename, module_type);
-        return;
+    if (!res)
+    {
+        fprintf(stderr, "\nFailed to create minidump\n");
+        fflush(stderr);
+    }
+    else
+    {
+        char dir[_MAX_PATH];
+        GetCurrentDirectory(_MAX_PATH, dir);
+        fprintf(stderr, "\nMinidump is generated:\n%s\\%s\n", dir, filename);
+        fflush(stderr);
     }
 
-    // module == NULL
-    size_t start_addr, end_addr, region_size;
-    MEMORY_BASIC_INFORMATION mem_info;
-
-    VirtualQuery(ip, &mem_info, sizeof(mem_info));
-    start_addr = (size_t)mem_info.BaseAddress;
-    region_size = (size_t)mem_info.RegionSize;
-    end_addr = start_addr + region_size;
-
-    fprintf(stderr, "Memory region 0x%"W_PI_FMT":0x%"W_PI_FMT" %s\n",
-                start_addr, end_addr, sd_get_region_access_info(&mem_info));
+    CloseHandle(file);
+#endif // #ifndef NO_DBGHELP
 }
 
 
-void sd_get_c_method_info(MethodInfo* info, native_module_t* UNREF module, void* ip)
+void sd_get_c_method_info(CFunInfo* info, native_module_t* module, void* ip)
 {
-    *info->method_name = 0;
-    *info->file_name = 0;
+    *info->name = 0;
+    *info->filename = 0;
     info->line = -1;
 
 #ifndef NO_DBGHELP
@@ -170,7 +138,7 @@
     if (g_SymFromAddr &&
         g_SymFromAddr(GetCurrentProcess(), (DWORD64)(POINTER_SIZE_INT)ip, &funcDispl, pSymb))
     {
-        strcpy(info->method_name, pSymb->Name);
+        strcpy(info->name, pSymb->Name);
     }
 
     if (g_SymGetLineFromAddr64)
@@ -184,7 +152,7 @@
                                    &offset, &lineinfo))
         {
             info->line = lineinfo.LineNumber;
-            strncpy(info->file_name, lineinfo.FileName, sizeof(info->file_name));
+            strncpy(info->filename, lineinfo.FileName, sizeof(info->filename));
             return;
         }
     }
@@ -200,20 +168,31 @@
                                  &offset, &lineinfo))
         {
             info->line = lineinfo.LineNumber;
-            strncpy(info->file_name, lineinfo.FileName, sizeof(info->file_name));
+            strncpy(info->filename, lineinfo.FileName, sizeof(info->filename));
         }
     }
 
 #endif // #ifndef NO_DBGHELP
 }
 
-int sd_get_cur_tid()
-{
-    return GetCurrentThreadId();
-}
-
 void sd_init_crash_handler()
 {
+#ifndef NO_DBGHELP
+// Preventive initialization does not work
+//        if (!SymInitialize(GetCurrentProcess(), NULL, TRUE))
+//            return false;
+
+        HMODULE hdbghelp = ::LoadLibrary("dbghelp");
+
+        if (hdbghelp)
+        {
+            SymSetOptions(SYMOPT_LOAD_LINES);
+            g_SymFromAddr = (SymFromAddr_type)::GetProcAddress(hdbghelp, "SymFromAddr");
+            g_SymGetLineFromAddr64 = (SymGetLineFromAddr64_type)::GetProcAddress(hdbghelp, "SymGetLineFromAddr64");
+            g_SymGetLineFromAddr = (SymGetLineFromAddr_type)::GetProcAddress(hdbghelp, "SymGetLineFromAddr");
+        }
+#endif // #ifndef NO_DBGHELP
+
     // Get current directory
     DWORD required = GetCurrentDirectory(0, NULL);
     char* ptr = (char*)STD_MALLOC(required);
@@ -256,11 +235,21 @@
     FreeEnvironmentStrings((char*)env_block);
 }
 
-void sd_print_cwdcmdenv()
+void sd_cleanup_crash_handler()
+{
+    STD_FREE(g_curdir);
+    STD_FREE(g_cmdline);
+    STD_FREE(g_environ);
+}
+
+void sd_print_cmdline_cwd()
 {
-    fprintf(stderr, "\nWorking directory:\n%s\n", g_curdir ? g_curdir : "'null'");
     fprintf(stderr, "\nCommand line:\n%s\n", g_cmdline);
+    fprintf(stderr, "\nWorking directory:\n%s\n", g_curdir ? g_curdir : "'null'");
+}
 
+void sd_print_environment()
+{
     fprintf(stderr, "\nEnvironment variables:\n");
 
     const char* penv = (char*)g_environ;

Copied: harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/linux/memaccess.cpp (from r637971, harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_memory_linux.cpp)
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/linux/memaccess.cpp?p2=harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/linux/memaccess.cpp&p1=harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_memory_linux.cpp&r1=637971&r2=638327&rev=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_memory_linux.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/linux/memaccess.cpp Tue Mar 18 04:31:02 2008
@@ -1,3 +1,19 @@
+/*
+ *  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.
+ */
 /**
  * @author Ilya Berezhniuk
  * @version $Revision$
@@ -5,283 +21,98 @@
 #include <sys/mman.h>
 #include <limits.h>
 
+#include "port_general.h"
 #include "port_vmem.h"
-#ifdef _IA32_
-#include "encoder.h"
-#include "jit_intf_cpp.h"
-#endif // #ifdef _IA32_
-#include "nogc.h"
-#include "dump.h"
-#include "ncai_direct.h"
-#include "ncai_internal.h"
+#include "port_barriers.h"
 
+#include "signals_internal.h"
+#include "port_memaccess.h"
 
-typedef void* (__cdecl *get_return_address_stub_type)();
 
+extern "C" void port_memcpy_asm(void* dst, const void* src, size_t size,
+                                void** prestart_addr, void* memcpyaddr);
 
-#ifdef _IA32_
 
-static get_return_address_stub_type gen_get_return_address_stub()
+static int memcpy_internal(void* dst, const void* src, size_t size, int from)
 {
-    static get_return_address_stub_type addr = NULL;
-
-    if (addr)
-        return addr;
-
-    const int stub_size = 0x04;
-    char *stub = (char *)malloc_fixed_code_for_jit(stub_size, DEFAULT_CODE_ALIGNMENT, CODE_BLOCK_HEAT_COLD, CAA_Allocate);
-#ifdef _DEBUG
-    memset(stub, 0xcc /*int 3*/, stub_size);
-#endif
-    char *ss = stub;
-
-    M_Base_Opnd m1(esp_reg, 0);
-    ss = mov(ss,  eax_opnd,  m1);
-    ss = ret(ss);
-
-    addr = (get_return_address_stub_type)stub;
-    assert(ss - stub <= stub_size);
-
-    /*
-       The following code will be generated:
+    port_tls_data tlsdata;
 
-        mov         eax,dword ptr [esp]
-        ret
-    */
-
-    DUMP_STUB(stub, "get_return_address", ss - stub);
-
-    return addr;
-}
-#endif // #ifdef _IA32_
-
-
-ncaiError ncai_read_memory_internal(void* addr, size_t size, void* buf, bool UNUSED calc_pass = false)
-{
-#ifndef _IA32_
-    // SIGSEGV processing is not implemented for EM64T/IPF
-    memcpy(buf, addr, size);
-    return NCAI_ERROR_NONE;
-#else // #ifndef _IA32_
-
-static void* read_memory_1st_label = NULL;
-static void* read_memory_2nd_label = NULL;
-
-    char dummy_str[3];
-
-    if (calc_pass)
+    if (!get_private_tls_data())
     {
-        addr = dummy_str;
-        buf = dummy_str;
-        *dummy_str = 'a'; // To avoid warnings
-        size = 1;
+        if (set_private_tls_data(&tlsdata) != 0)
+            return -1;
     }
 
-    jvmti_thread_t jvmti_thread = &p_TLS_vmthread->jvmti_thread;
+    tlsdata.violation_flag = 1;
 
-    unsigned char* src_ptr = (unsigned char*)addr;
-    unsigned char* dest_ptr = (unsigned char*)buf;
+    void* memcpyaddr = (void*)&memcpy;
+    port_memcpy_asm(dst, src, size, &tlsdata.restart_address, memcpyaddr);
 
-    jvmti_thread->violation_flag = 1;
-    jvmti_thread->violation_restart_address = read_memory_1st_label;
-
-    size_t i;
-    for (i = 0; i < size; i++)
+    if (tlsdata.violation_flag == 1)
     {
-        *dest_ptr = *src_ptr;
-
-        void* label = (gen_get_return_address_stub())();
-        read_memory_1st_label = label;
-
-        if (jvmti_thread->violation_flag == 0)
-            break;
-
-        ++src_ptr;
-        ++dest_ptr;
+        pthread_setspecific(port_tls_key, NULL);
+        return 0;
     }
 
-    if (jvmti_thread->violation_flag == 0 || calc_pass)
-    {
-        if (!calc_pass)
-        {
-            size_t* page_sizes = port_vmem_page_sizes();
-            size_t page_size = page_sizes[0];
-
-            POINTER_SIZE_INT start =
-                ((POINTER_SIZE_INT)addr + i) & ~(page_size - 1);
-            POINTER_SIZE_INT pastend =
-                ((POINTER_SIZE_INT)addr + size + page_size - 1) & ~(page_size - 1);
-
-            int result = mprotect((void*)start, pastend - start,
-                                    PROT_READ | PROT_WRITE | PROT_EXEC);
-
-            if (result == EAGAIN)
-            {
-                timespec delay = {0, 10};
-                nanosleep(&delay, NULL);
-                result = mprotect((void*)start, pastend - start,
-                                    PROT_READ | PROT_WRITE | PROT_EXEC);
-            }
-
-            if (result != 0)
-                return NCAI_ERROR_ACCESS_DENIED;
-        }
-
-        if (calc_pass)
-            ++size;
-
-        jvmti_thread->violation_flag = 1;
-        jvmti_thread->violation_restart_address = read_memory_2nd_label;
-
-        for (; i < size; i++)
-        {
-            *dest_ptr++ = *src_ptr++;
-
-            void* label = (gen_get_return_address_stub())();
-            read_memory_2nd_label = label;
-
-            if (jvmti_thread->violation_flag == 0)
-                return NCAI_ERROR_ACCESS_DENIED;
-        }
-    }
-
-    jvmti_thread->violation_flag = 0;
-    return NCAI_ERROR_NONE;
-#endif // #ifndef _IA32_
-}
-
-
-ncaiError ncai_read_memory(void* addr, size_t size, void* buf)
-{
-    if (!buf || !addr)
-        return NCAI_ERROR_NULL_POINTER;
-
-    if (size == 0)
-        return NCAI_ERROR_ILLEGAL_ARGUMENT;
-
-    if (p_TLS_vmthread == NULL)
-        return NCAI_ERROR_INTERNAL;
-
-    if (ncai_read_memory_internal(NULL, 0, NULL, true) != NCAI_ERROR_NONE)
-        return NCAI_ERROR_INTERNAL;
-
-    return ncai_read_memory_internal(addr, size, buf, false);
-}
-
+    // Try changing memory access
+    size_t* page_sizes = port_vmem_page_sizes();
+    size_t page_size = page_sizes[0];
 
-static ncaiError ncai_write_memory_internal(void* addr, size_t size, void* buf, bool UNUSED calc_pass = false)
-{
-#ifndef _IA32_
-    // SIGSEGV processing is not implemented for EM64T/IPF
-    memcpy(addr, buf, size);
-    return NCAI_ERROR_NONE;
-#else // #ifndef _IA32_
+    const void* addr = from ? src : dst;
 
-static void* write_memory_1st_label = NULL;
-static void* write_memory_2nd_label = NULL;
+    POINTER_SIZE_INT start =
+        (POINTER_SIZE_INT)addr & ~(page_size - 1);
+    POINTER_SIZE_INT pastend =
+        ((POINTER_SIZE_INT)addr + size + page_size - 1) & ~(page_size - 1);
 
-    char dummy_str[3];
+    int result = mprotect((void*)start, pastend - start,
+                            PROT_READ | PROT_WRITE | PROT_EXEC);
 
-    if (calc_pass)
+    if (result == EAGAIN)
     {
-        addr = dummy_str;
-        buf = dummy_str;
-        *dummy_str = 'a'; // To avoid warnings
-        size = 1;
+        timespec delay = {0, 10};
+        nanosleep(&delay, NULL);
+        result = mprotect((void*)start, pastend - start,
+                            PROT_READ | PROT_WRITE | PROT_EXEC);
     }
 
-    jvmti_thread_t jvmti_thread = &p_TLS_vmthread->jvmti_thread;
+    if (result != 0)
+        return -1;
 
-    unsigned char* src_ptr = (unsigned char*)buf;
-    unsigned char* dest_ptr = (unsigned char*)addr;
+    tlsdata.violation_flag = 1;
 
-    jvmti_thread->violation_flag = 1;
-    jvmti_thread->violation_restart_address = write_memory_1st_label;
+    port_memcpy_asm(dst, src, size, &tlsdata.restart_address, memcpyaddr);
 
-    size_t i;
-    for (i = 0; i < size; i++)
-    {
-        *dest_ptr = *src_ptr;
-
-        void* label = (gen_get_return_address_stub())();
-        write_memory_1st_label = label;
+    pthread_setspecific(port_tls_key, NULL);
+    return (tlsdata.violation_flag == 1) ? 0 : -1;
+}
 
-        if (jvmti_thread->violation_flag == 0)
-            break;
 
-        ++src_ptr;
-        ++dest_ptr;
-    }
+int port_read_memory(void* addr, size_t size, void* buf)
+{
+    if (!buf || !addr)
+        return -1;
 
-    if (jvmti_thread->violation_flag == 0 || calc_pass)
-    {
-        if (!calc_pass)
-        {
-            size_t* page_sizes = port_vmem_page_sizes();
-            size_t page_size = page_sizes[0];
-
-            POINTER_SIZE_INT start =
-                ((POINTER_SIZE_INT)addr + i) & ~(page_size - 1);
-            POINTER_SIZE_INT pastend =
-                ((POINTER_SIZE_INT)addr + size + page_size - 1) & ~(page_size - 1);
-
-            int result = mprotect((void*)start, pastend - start,
-                                    PROT_READ | PROT_WRITE | PROT_EXEC);
-
-            if (result == EAGAIN)
-            {
-                timespec delay = {0, 10};
-                nanosleep(&delay, NULL);
-                result = mprotect((void*)start, pastend - start,
-                                    PROT_READ | PROT_WRITE | PROT_EXEC);
-            }
-
-            if (result != 0)
-                return NCAI_ERROR_ACCESS_DENIED;
-        }
-
-        if (calc_pass)
-            ++size;
-
-        jvmti_thread->violation_flag = 1;
-        jvmti_thread->violation_restart_address = write_memory_2nd_label;
-
-        for (; i < size; i++)
-        {
-            *dest_ptr++ = *src_ptr++;
-
-            void* label = (gen_get_return_address_stub())();
-            write_memory_2nd_label = label;
-
-            if (jvmti_thread->violation_flag == 0)
-                return NCAI_ERROR_ACCESS_DENIED;
-        }
-    }
+    if (size == 0)
+        return 0;
 
-#ifdef _IPF_
-    asm volatile ("mf" ::: "memory");
-#else
-    __asm__("mfence");
-#endif
-
-    jvmti_thread->violation_flag = 0;
-    return NCAI_ERROR_NONE;
-#endif // #ifndef _IA32_
+    return memcpy_internal(buf, addr, size, 1);
 }
 
-ncaiError ncai_write_memory(void* addr, size_t size, void* buf)
+int port_write_memory(void* addr, size_t size, void* buf)
 {
     if (!buf || !addr)
-        return NCAI_ERROR_NULL_POINTER;
+        return -1;
 
     if (size == 0)
-        return NCAI_ERROR_ILLEGAL_ARGUMENT;
+        return 0;
 
-    if (p_TLS_vmthread == NULL)
-        return NCAI_ERROR_INTERNAL;
+    int result = memcpy_internal(addr, buf, size, 0);
 
-    if (ncai_write_memory_internal(NULL, 0, NULL, true) != NCAI_ERROR_NONE)
-        return NCAI_ERROR_INTERNAL;
+    if (result == 0)
+    {
+        port_rw_barrier();
+    }
 
-    return ncai_write_memory_internal(addr, size, buf, false);
+    return result;
 }

Added: harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/linux/memaccess_em64t.s
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/linux/memaccess_em64t.s?rev=638327&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/linux/memaccess_em64t.s (added)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/linux/memaccess_em64t.s Tue Mar 18 04:31:02 2008
@@ -0,0 +1,42 @@
+//
+//  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.
+//
+    .text
+	.align 16
+
+// port_memcpy_asm(void* dst, const void* src, size_t size,
+//                 void** prestart_addr, void* memcpyaddr);
+// 1st arg (RDI) - dest
+// 2nd arg (RSI) - src
+// 3rd arg (RDX) - len
+// 4th arg (RCX) - address of restart_address storage
+// 5th arg (R8)  - address of memcpy - to avoid PIC problems in GNU asm
+
+.globl port_memcpy_asm
+    .type    port_memcpy_asm, @function
+port_memcpy_asm:
+    pushq   %rbx
+    callq   precall
+precall:
+    popq    %rax
+    addq    $(preret - precall), %rax
+    movq    %rax, (%rcx)
+
+    callq   *%r8
+
+preret:
+    popq    %rbx
+    ret

Added: harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/linux/memaccess_ia32.s
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/linux/memaccess_ia32.s?rev=638327&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/linux/memaccess_ia32.s (added)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/linux/memaccess_ia32.s Tue Mar 18 04:31:02 2008
@@ -0,0 +1,49 @@
+//
+//  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.
+//
+    .text
+    .align 4
+
+// port_memcpy_asm(void* dst, const void* src, size_t size,
+//                 void** prestart_addr, void* memcpyaddr);
+// 1st arg (EBP +  8) - dest
+// 2nd arg (EBP + 12) - src
+// 3rd arg (EBP + 16) - len
+// 4th arg (EBP + 20) - address of restart_address storage
+// 5th arg (EBP + 24) - address of memcpy - not used on x86
+
+.globl port_memcpy_asm
+    .type    port_memcpy_asm, @function
+port_memcpy_asm:
+    pushl    %ebp
+    movl     %esp, %ebp
+    subl     $20, %esp
+
+    movl    20(%ebp), %eax
+    movl    $preret, (%eax)
+
+    movl    8(%ebp), %eax
+    movl    %eax, (%esp)
+    movl    12(%ebp), %eax
+    movl    %eax, 4(%esp)
+    movl    16(%ebp), %eax
+    movl    %eax, 8(%esp)
+    call    memcpy
+
+preret:
+    addl    $20, %esp
+    popl    %ebp
+    ret

Added: harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/linux/memaccess_ipf.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/linux/memaccess_ipf.cpp?rev=638327&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/linux/memaccess_ipf.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/linux/memaccess_ipf.cpp Tue Mar 18 04:31:02 2008
@@ -0,0 +1,51 @@
+/*
+ *  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.
+ */
+/**
+ * @author Ilya Berezhniuk
+ * @version $Revision$
+ */
+
+#include <string.h>
+#include "port_memaccess.h"
+
+
+int port_read_memory(void* addr, size_t size, void* buf)
+{
+    if (!buf || !addr)
+        return -1;
+
+    if (size == 0)
+        return 0;
+
+    memcpy(buf, addr, size);
+
+    return 0;
+}
+
+int port_write_memory(void* addr, size_t size, void* buf)
+{
+    if (!buf || !addr)
+        return -1;
+
+    if (size == 0)
+        return 0;
+
+    memcpy(addr, buf, size);
+    asm volatile ("mf" ::: "memory");
+
+    return 0;
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/linux/memaccess_ipf.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/win/memaccess.cpp (from r637971, harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_memory_win.cpp)
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/win/memaccess.cpp?p2=harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/win/memaccess.cpp&p1=harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_memory_win.cpp&r1=637971&r2=638327&rev=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_memory_win.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/memaccess/win/memaccess.cpp Tue Mar 18 04:31:02 2008
@@ -1,49 +1,65 @@
+/*
+ *  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.
+ */
 /**
  * @author Ilya Berezhniuk
  * @version $Revision$
  */
-#include "ncai_direct.h"
-#include "ncai_internal.h"
+
+#include "open/platform_types.h"
+#include <windows.h>
+#include "port_memaccess.h"
 
 
-ncaiError ncai_read_memory(void* addr, size_t size, void* buf)
+int port_read_memory(void* addr, size_t size, void* buf)
 {
     if (!buf || !addr)
-        return NCAI_ERROR_NULL_POINTER;
+        return -1;
 
     if (size == 0)
-        return NCAI_ERROR_ILLEGAL_ARGUMENT;
+        return 0;
 
     SIZE_T bytes_read;
 
     BOOL result = ReadProcessMemory(GetCurrentProcess(),
                                     addr, buf, size, &bytes_read);
-    assert(bytes_read == size);
 
-    if (!result)
-        return NCAI_ERROR_ACCESS_DENIED;
+    if (!result || bytes_read != size)
+        return -1;
 
-    return NCAI_ERROR_NONE;
+    return 0;
 }
 
-ncaiError ncai_write_memory(void* addr, size_t size, void* buf)
+int port_write_memory(void* addr, size_t size, void* buf)
 {
     if (!buf || !addr)
-        return NCAI_ERROR_NULL_POINTER;
+        return -1;
 
     if (size == 0)
-        return NCAI_ERROR_ILLEGAL_ARGUMENT;
+        return 0;
 
     SIZE_T bytes_written;
 
     BOOL result = WriteProcessMemory(GetCurrentProcess(),
                                     addr, buf, size, &bytes_written);
-    assert(bytes_written == size);
 
-    if (!result)
-        return NCAI_ERROR_ACCESS_DENIED;
+    if (!result || bytes_written != size)
+        return -1;
 
     FlushInstructionCache(GetCurrentProcess(), addr, size);
 
-    return NCAI_ERROR_NONE;
+    return 0;
 }

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/modules/linux/native_modules_os.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/modules/linux/native_modules_os.c?rev=638327&r1=638326&r2=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/modules/linux/native_modules_os.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/modules/linux/native_modules_os.c Tue Mar 18 04:31:02 2008
@@ -26,7 +26,7 @@
 #include <unistd.h>
 #include "open/types.h"
 #include "port_malloc.h"
-#include "native_modules.h"
+#include "port_modules.h"
 
 
 typedef struct _raw_module raw_module;

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/modules/native_modules.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/modules/native_modules.c?rev=638327&r1=638326&r2=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/modules/native_modules.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/modules/native_modules.c Tue Mar 18 04:31:02 2008
@@ -18,7 +18,7 @@
 #include <stdio.h>
 #include "open/types.h"
 #include "port_malloc.h"
-#include "native_modules.h"
+#include "port_modules.h"
 
 
 native_module_t* port_find_module(native_module_t* modules, void* code_ptr)

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/modules/win/native_modules_os.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/modules/win/native_modules_os.c?rev=638327&r1=638326&r2=638327&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/modules/win/native_modules_os.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/modules/win/native_modules_os.c Tue Mar 18 04:31:02 2008
@@ -20,11 +20,12 @@
  */
 
 #include "port_malloc.h"
-#include "native_modules.h"
+#include "port_modules.h"
 
 #include <memory.h>
 #include <Windows.h>
 #include <Tlhelp32.h>
+
 
 static native_module_t* fill_module(MODULEENTRY32 src);
 

Added: harmony/enhanced/drlvm/trunk/vm/port/src/signals/include/signals_internal.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/signals/include/signals_internal.h?rev=638327&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/signals/include/signals_internal.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/signals/include/signals_internal.h Tue Mar 18 04:31:02 2008
@@ -0,0 +1,118 @@
+/*
+ *  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.
+ */
+
+#ifndef _SIGNALS_INTERNAL_H_
+#define _SIGNALS_INTERNAL_H_
+
+#include "port_general.h"
+#include "port_thread.h"
+#include "open/platform_types.h"
+#include "open/hythread_ext.h" /* For windows.h */
+
+
+/* Thread-specific structure */
+typedef struct
+{
+    /* Previous crash handling stage to restart crash processing */
+    int     crash_stage;
+
+#ifndef WIN32 /* UNIX */
+    /* Flag and restart address for memory access violation detection */
+    int     violation_flag;
+    void*   restart_address;
+#endif /* UNIX */
+
+#ifdef WIN32
+    Boolean assert_dialog;
+#endif
+
+    /* Flag to produce minidump/core on the second exception catch */
+    Boolean   produce_core;
+
+} port_tls_data;
+
+
+#ifdef WIN32
+typedef DWORD port_tls_key_t;
+#else
+typedef pthread_key_t port_tls_key_t;
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern port_tls_key_t port_tls_key;
+
+int init_private_tls_data();
+int free_private_tls_data();
+
+PORT_INLINE port_tls_data* get_private_tls_data()
+{
+#ifdef WIN32
+        return (port_tls_data*)TlsGetValue(port_tls_key);
+#else
+        return (port_tls_data*)pthread_getspecific(port_tls_key);
+#endif
+}
+
+PORT_INLINE int set_private_tls_data(port_tls_data* data)
+{
+#ifdef WIN32
+        return TlsSetValue(port_tls_key, data) ? 0 : -1;
+#else
+        return pthread_setspecific(port_tls_key, data);
+#endif
+}
+
+
+#define INSTRUMENTATION_BYTE_HLT 0xf4 // HLT instruction
+#define INSTRUMENTATION_BYTE_CLI 0xfa // CLI instruction
+#define INSTRUMENTATION_BYTE_INT3 0xcc // INT 3 instruction
+
+#ifdef WINNT
+#define INSTRUMENTATION_BYTE INSTRUMENTATION_BYTE_CLI
+#else
+#define INSTRUMENTATION_BYTE INSTRUMENTATION_BYTE_INT3
+#endif
+
+
+#ifdef WIN32
+
+/**
+ * Assembler wrapper for clearing CLD flag - bug in VEHs
+ * appeared in debug prolog.
+ */
+LONG NTAPI vectored_exception_handler(LPEXCEPTION_POINTERS nt_exception);
+
+/* Internal exception handler */
+LONG NTAPI vectored_exception_handler_internal(LPEXCEPTION_POINTERS nt_exception);
+
+#else /* UNIX */
+
+//
+
+#endif /* WIN32 */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SIGNALS_INTERNAL_H_ */

Propchange: harmony/enhanced/drlvm/trunk/vm/port/src/signals/include/signals_internal.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/vm/port/src/signals/linux/signals_common.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/signals/linux/signals_common.cpp?rev=638327&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/signals/linux/signals_common.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/signals/linux/signals_common.cpp Tue Mar 18 04:31:02 2008
@@ -0,0 +1,179 @@
+/*
+ *  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 <unistd.h>
+#undef __USE_XOPEN
+#include <signal.h>
+
+#include "open/platform_types.h"
+#include "port_crash_handler.h"
+#include "stack_dump.h"
+#include "../linux/include/gdb_crash_handler.h"
+#include "signals_internal.h"
+
+
+port_tls_key_t port_tls_key;
+
+int init_private_tls_data()
+{
+    return (pthread_key_create(&port_tls_key, NULL) == 0) ? 0 : -1;
+}
+
+int free_private_tls_data()
+{
+    return (pthread_key_delete(port_tls_key) == 0) ? 0 : -1;
+}
+
+
+static void c_handler(Registers* pregs, size_t signum, void* fault_addr)
+{ // this exception handler is executed *after* VEH handler returned
+    int result;
+    Registers regs = *pregs;
+
+    // Check if SIGSEGV is produced by port_read/write_memory
+    port_tls_data* tlsdata = get_private_tls_data();
+    if (tlsdata && tlsdata->violation_flag)
+    {
+        tlsdata->violation_flag = 0;
+        pregs->set_ip(tlsdata->restart_address);
+        return;
+    }
+
+    switch ((int)signum)
+    {
+    case SIGSEGV:
+        result = port_process_signal(PORT_SIGNAL_GPF, pregs, fault_addr, FALSE);
+        break;
+    case SIGFPE:
+        result = port_process_signal(PORT_SIGNAL_ARITHMETIC, pregs, fault_addr, FALSE);
+        break;
+    case SIGTRAP:
+        // Correct return address
+        pregs->set_ip((void*)((POINTER_SIZE_INT)pregs->get_ip() - 1));
+        result = port_process_signal(PORT_SIGNAL_BREAKPOINT, pregs, fault_addr, FALSE);
+        break;
+    case SIGINT:
+        result = port_process_signal(PORT_SIGNAL_CTRL_C, pregs, fault_addr, FALSE);
+        break;
+    case SIGQUIT:
+        result = port_process_signal(PORT_SIGNAL_QUIT, pregs, fault_addr, FALSE);
+        break;
+    default:
+        result = port_process_signal(PORT_SIGNAL_UNKNOWN, pregs, fault_addr, TRUE);
+    }
+
+    if (result == 0)
+        return;
+
+    // We've got a crash
+    if (result > 0)
+    { // result > 0 - invoke debugger
+        bool result = gdb_crash_handler(&regs);
+        // Continue with exiting process if not sucessful...
+    }
+
+    // result < 0 - exit process
+    if ((port_crash_handler_get_flags() & PORT_CRASH_DUMP_PROCESS_CORE) != 0)
+    { // Return to the same place to produce the same crash and generate core
+        signal(signum, SIG_DFL); // setup default handler
+        return;
+    }
+    // No core needed - simply terminate
+    _exit(-1);
+}
+
+static void general_signal_handler(int signum, siginfo_t* info, void* context)
+{
+    Registers regs;
+    // Convert OS context to Registers
+    port_thread_context_to_regs(&regs, (ucontext_t*)context);
+    // Prepare registers for transfering control out of signal handler
+    void* callback = (void*)&c_handler;
+    port_set_longjump_regs(callback, &regs, 3,
+                            &regs, (void*)(size_t)signum, info->si_addr);
+    // Convert prepared Registers back to OS context
+    port_thread_regs_to_context((ucontext_t*)context, &regs);
+    // Return from signal handler to go to C handler
+}
+
+
+struct sig_reg
+{
+    int signal;
+    int flags;
+    bool set_up;
+};
+
+static sig_reg signals_used[] =
+{
+    { SIGTRAP, SA_SIGINFO, false },
+    { SIGSEGV, SA_SIGINFO | SA_ONSTACK, false },
+    { SIGFPE,  SA_SIGINFO, false },
+    { SIGINT,  SA_SIGINFO, false },
+    { SIGQUIT, SA_SIGINFO, false },
+    { SIGABRT, SA_SIGINFO, false }
+};
+
+static struct sigaction old_actions[sizeof(signals_used)/sizeof(signals_used[0])];
+
+
+static void restore_signals()
+{
+    for (size_t i = 0; i < sizeof(signals_used)/sizeof(signals_used[0]); i++)
+    {
+        if (!signals_used[i].set_up)
+            continue;
+
+        signals_used[i].set_up = false;
+        sigaction(signals_used[i].signal, &old_actions[i], NULL);
+    }
+}
+
+int initialize_signals()
+{
+    struct sigaction sa;
+
+    for (size_t i = 0; i < sizeof(signals_used)/sizeof(signals_used[0]); i++)
+    {
+        sigemptyset(&sa.sa_mask);
+        sa.sa_flags = signals_used[i].flags;
+        sa.sa_sigaction = &general_signal_handler;
+
+        if (0 != sigaction(signals_used[i].signal, &sa, &old_actions[i]))
+        {
+            restore_signals();
+            return -1;
+        }
+    }
+
+    // Prepare gdb crash handler
+    if (!init_gdb_crash_handler())
+    {
+        restore_signals();
+        return -1;
+    }
+
+    return 0;
+
+} //initialize_signals
+
+int shutdown_signals()
+{
+    cleanup_gdb_crash_handler();
+    restore_signals();
+    return 0;
+} //shutdown_signals

Propchange: harmony/enhanced/drlvm/trunk/vm/port/src/signals/linux/signals_common.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/vm/port/src/signals/linux/signals_ipf.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/signals/linux/signals_ipf.cpp?rev=638327&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/signals/linux/signals_ipf.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/signals/linux/signals_ipf.cpp Tue Mar 18 04:31:02 2008
@@ -0,0 +1,283 @@
+/*
+ *  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 <unistd.h>
+#undef __USE_XOPEN
+#include <signal.h>
+
+#include "open/platform_types.h"
+#include "port_crash_handler.h"
+#include "stack_dump.h"
+#include "../linux/include/gdb_crash_handler.h"
+#include "signals_internal.h"
+
+
+port_tls_key_t port_tls_key;
+
+int init_private_tls_data()
+{
+    return (pthread_key_create(&port_tls_key, NULL) == 0) ? 0 : -1;
+}
+
+int free_private_tls_data()
+{
+    return (pthread_key_delete(port_tls_key) == 0) ? 0 : -1;
+}
+
+
+/* Out-of-signal-handler signal processing is not implemented for IPF
+
+static void c_handler(Registers* pregs, size_t signum, void* fault_addr)
+{ // this exception handler is executed *after* VEH handler returned
+}
+*/
+
+static void general_signal_handler(int signum, siginfo_t* info, void* context)
+{
+    Registers regs;
+/* Not implemented
+    // Check if SIGSEGV is produced by port_read/write_memory
+    port_tls_data* tlsdata = get_private_tls_data();
+    if (tlsdata && tlsdata->violation_flag)
+    {
+        tlsdata->violation_flag = 0;
+        pregs->set_ip(tlsdata->restart_address);
+        return;
+    }
+*/
+    // Convert OS context to Registers
+    port_thread_context_to_regs(&regs, (ucontext_t*)context);
+
+    void* fault_addr = info->si_addr;
+    int result;
+
+    switch ((int)signum)
+    {
+    case SIGSEGV:
+        result = port_process_signal(PORT_SIGNAL_GPF, &regs, fault_addr, FALSE);
+        break;
+    case SIGFPE:
+        result = port_process_signal(PORT_SIGNAL_ARITHMETIC, &regs, fault_addr, FALSE);
+        break;
+    case SIGTRAP:
+        // Correct return address - FIXME ??? probably not needed on IPF
+        regs.set_ip((void*)((POINTER_SIZE_INT)regs.get_ip() - 1));
+        result = port_process_signal(PORT_SIGNAL_BREAKPOINT, &regs, fault_addr, FALSE);
+        break;
+    case SIGINT:
+        result = port_process_signal(PORT_SIGNAL_CTRL_C, &regs, fault_addr, FALSE);
+        break;
+    case SIGQUIT:
+        result = port_process_signal(PORT_SIGNAL_QUIT, &regs, fault_addr, FALSE);
+        break;
+    default:
+        result = port_process_signal(PORT_SIGNAL_UNKNOWN, &regs, fault_addr, TRUE);
+    }
+
+    if (result == 0)
+        return;
+
+    // We've got a crash
+    if (result > 0)
+    { // result > 0 - invoke debugger
+        bool result = gdb_crash_handler(&regs);
+        // Continue with exiting process if not sucessful...
+    }
+
+    // Convert Registers back to OS context
+    port_thread_regs_to_context((ucontext_t*)context, &regs);
+
+    // result < 0 - exit process
+    if ((port_crash_handler_get_flags() & PORT_CRASH_DUMP_PROCESS_CORE) != 0)
+    { // Return to the same place to produce the same crash and generate core
+        signal(signum, SIG_DFL); // setup default handler
+        return;
+    }
+    // No core needed - simply terminate
+    _exit(-1);
+}
+
+
+struct sig_reg
+{
+    int signal;
+    int flags;
+    bool set_up;
+};
+
+static sig_reg signals_used[] =
+{
+    { SIGTRAP, SA_SIGINFO, false },
+    { SIGSEGV, SA_SIGINFO | SA_ONSTACK, false },
+    { SIGFPE,  SA_SIGINFO, false },
+    { SIGINT,  SA_SIGINFO, false },
+    { SIGQUIT, SA_SIGINFO, false },
+    { SIGABRT, SA_SIGINFO, false }
+};
+
+static struct sigaction old_actions[sizeof(signals_used)/sizeof(signals_used[0])];
+
+
+static void restore_signals()
+{
+    for (size_t i = 0; i < sizeof(signals_used)/sizeof(signals_used[0]); i++)
+    {
+        if (!signals_used[i].set_up)
+            continue;
+
+        signals_used[i].set_up = false;
+        sigaction(signals_used[i].signal, &old_actions[i], NULL);
+    }
+}
+
+int initialize_signals()
+{
+    struct sigaction sa;
+
+    for (size_t i = 0; i < sizeof(signals_used)/sizeof(signals_used[0]); i++)
+    {
+        sigemptyset(&sa.sa_mask);
+        sa.sa_flags = signals_used[i].flags;
+        sa.sa_sigaction = &general_signal_handler;
+
+        if (0 != sigaction(signals_used[i].signal, &sa, &old_actions[i]))
+        {
+            restore_signals();
+            return -1;
+        }
+    }
+
+    // Prepare gdb crash handler
+    if (!init_gdb_crash_handler())
+    {
+        restore_signals();
+        return -1;
+    }
+
+    return 0;
+
+} //initialize_signals
+
+int shutdown_signals() {
+    cleanup_gdb_crash_handler();
+    restore_signals();
+    return 0;
+} //shutdown_signals
+
+#if 0
+
+// Variables used to locate the context from the signal handler
+static int sc_nest = -1;
+static bool use_ucontext = false;
+static uint32 exam_point;
+
+/*
+ * 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.
+ */
+
+/*
+See function initialize_signals() below first please.
+
+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.
+*/
+
+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;
+                }
+            }
+        }
+
+        ebp = (uint32 *)((uint64)ebp[0]);
+    }
+
+    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);
+    }
+}
+
+
+
+#endif

Propchange: harmony/enhanced/drlvm/trunk/vm/port/src/signals/linux/signals_ipf.cpp
------------------------------------------------------------------------------
    svn:eol-style = native