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/01/14 19:17:07 UTC

svn commit: r611872 - in /harmony/enhanced/drlvm/trunk: build/make/components/vm/ vm/include/open/ vm/port/include/ vm/port/src/file_io/ vm/vmcore/include/ vm/vmcore/src/ncai/ vm/vmcore/src/stack/ vm/vmcore/src/util/ vm/vmcore/src/util/linux/ vm/vmcore...

Author: gshimansky
Date: Mon Jan 14 10:16:47 2008
New Revision: 611872

URL: http://svn.apache.org/viewvc?rev=611872&view=rev
Log:
Applied patch from HARMONY-5379
[drlvm][signals] Several crash handler improvements


Added:
    harmony/enhanced/drlvm/trunk/vm/port/src/file_io/filepath_generic.c   (with props)
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/stack_dump_platf.cpp   (with props)
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/stack_dump_platf.cpp   (with props)
Modified:
    harmony/enhanced/drlvm/trunk/build/make/components/vm/port.xml
    harmony/enhanced/drlvm/trunk/vm/include/open/types.h
    harmony/enhanced/drlvm/trunk/vm/port/include/port_dso.h
    harmony/enhanced/drlvm/trunk/vm/port/include/port_filepath.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_modules.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/stack_dump.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_modules.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_handler.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/ia32_em64t/signals_common.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/include/platform_lowlevel.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/include/signals_common.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_modules.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/os_wrapper.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_em64t.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ipf.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_modules_common.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/natives_support.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_modules.cpp

Modified: harmony/enhanced/drlvm/trunk/build/make/components/vm/port.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/build/make/components/vm/port.xml?rev=611872&r1=611871&r2=611872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/build/make/components/vm/port.xml (original)
+++ harmony/enhanced/drlvm/trunk/build/make/components/vm/port.xml Mon Jan 14 10:16:47 2008
@@ -63,6 +63,7 @@
                 <include name="misc/win/*.c" if="is.windows"/>
                 <include name="vmem/win/*.c" if="is.windows"/>
                 <include name="thread/win/*.c" if="is.windows"/>
+                <include name="file_io/*.c"/>
             </fileset>
         </compiler>
 

Modified: harmony/enhanced/drlvm/trunk/vm/include/open/types.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/open/types.h?rev=611872&r1=611871&r2=611872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/open/types.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/open/types.h Mon Jan 14 10:16:47 2008
@@ -132,7 +132,7 @@
 /**
  * The integer datatypes on the platform that can hold a pointer.
  */
- #ifdef POINTER64
+#ifdef POINTER64
 #define POINTER_SIZE_INT uint64
 #define POINTER_SIZE_SINT int64
 #ifdef PLATFORM_NT
@@ -140,10 +140,12 @@
 #else 
 #define PI_FMT "ll"
 #endif
+#define W_PI_FMT "016"PI_FMT
 #else
 #define POINTER_SIZE_INT uint32
 #define POINTER_SIZE_SINT int32
 #define PI_FMT ""
+#define W_PI_FMT "08"PI_FMT
 #endif // POINTER64
 
 /**

Modified: harmony/enhanced/drlvm/trunk/vm/port/include/port_dso.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/include/port_dso.h?rev=611872&r1=611871&r2=611872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/include/port_dso.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/include/port_dso.h Mon Jan 14 10:16:47 2008
@@ -51,10 +51,14 @@
 #endif
 
 #ifdef PLATFORM_POSIX
-#   define PORT_DSO_NAME(name) "lib" name ".so"
+#   define PORT_DSO_PREFIX "lib"
+#   define PORT_DSO_EXT ".so"
 #elif PLATFORM_NT
-#   define PORT_DSO_NAME(name) name ".dll"
+#   define PORT_DSO_PREFIX ""
+#   define PORT_DSO_EXT ".dll"
 #endif
+
+#define PORT_DSO_NAME(name) PORT_DSO_PREFIX name PORT_DSO_EXT
 
 /**
  * @defgroup dso_modes Shared library binding modes

Modified: harmony/enhanced/drlvm/trunk/vm/port/include/port_filepath.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/include/port_filepath.h?rev=611872&r1=611871&r2=611872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/include/port_filepath.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/include/port_filepath.h Mon Jan 14 10:16:47 2008
@@ -94,6 +94,15 @@
 APR_DECLARE(char*) port_filepath_canonical(const char* original,
                                       apr_pool_t* pool);
 
+/**
+* Finds short file name in the specified filepath.
+* Returns the pointer to short file name in the source string.
+* If source filepath contains no path separators, returns filepath pointer itself.
+* @param root  - the beginning of the file path
+* @return The pointer to short file name.
+*/
+APR_DECLARE(const char*) port_filepath_basename(const char* filepath);
+
 /** @} */
 
 

Added: harmony/enhanced/drlvm/trunk/vm/port/src/file_io/filepath_generic.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/file_io/filepath_generic.c?rev=611872&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/file_io/filepath_generic.c (added)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/file_io/filepath_generic.c Mon Jan 14 10:16:47 2008
@@ -0,0 +1,34 @@
+/*
+ *  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 <string.h>
+#include "port_filepath.h"
+
+APR_DECLARE(const char*) port_filepath_basename(const char* filepath)
+{
+    char* separator;
+
+    if (!filepath || !*filepath)
+        return filepath;
+
+    separator = strrchr(filepath, PORT_FILE_SEPARATOR);
+
+    if (!separator && (PORT_FILE_SEPARATOR != '/'))
+        separator = strrchr(filepath, '/');
+
+    return separator ? (separator + 1) : filepath;
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/port/src/file_io/filepath_generic.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_modules.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_modules.h?rev=611872&r1=611871&r2=611872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_modules.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_modules.h Mon Jan 14 10:16:47 2008
@@ -55,25 +55,6 @@
 void clear_native_modules(native_module_t**);
 native_module_t* find_native_module(native_module_t* modules, void* code_ptr);
 
-#ifdef PLATFORM_POSIX
-typedef struct _raw_module raw_module;
-
-// Structure to accumulate several segments for the same module
-struct _raw_module
-{
-    void*               start;
-    void*               end;
-    bool                acc_r;
-    bool                acc_x;
-    char*               name;
-    raw_module*         next;
-};
-
-void native_clear_raw_list(raw_module*);
-raw_module* native_add_raw_segment(raw_module*, void*, void*, char, char);
-native_module_t* native_fill_module(raw_module*, size_t);
-#endif // PLATFORM_POSIX
-
 
 #ifdef __cplusplus
 }

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/stack_dump.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/stack_dump.h?rev=611872&r1=611871&r2=611872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/stack_dump.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/stack_dump.h Mon Jan 14 10:16:47 2008
@@ -23,12 +23,62 @@
 #ifndef __STACK_DUMP_H_
 #define __STACK_DUMP_H_
 
+#include "open/hythread_ext.h"
 #include "vm_core_types.h"
 #include "jni.h"
+#include "native_modules.h"
+
+
+#ifdef _DEBUG
+#define SD_UPDATE_MODULES
+#endif
+
+#ifdef SD_UPDATE_MODULES
+#define sd_update_modules() sd_update_modules()
+#else
+#define sd_update_modules()
+#endif
+
+#ifdef PLATFORM_POSIX
+#include <strings.h>
+#define strcmp_case strcasecmp
+#else // Win
+#include <string.h>
+#define strcmp_case _stricmp
+#endif
+
+#include "platform_lowlevel.h"
+
+#define SD_MNAME_LENGTH 2048
+
+// Symbolic method info: method name, source file name and a line number of an instruction within the method
+struct MethodInfo {
+    char method_name[SD_MNAME_LENGTH];
+    char file_name[_MAX_PATH];
+    int line;
+};
+
+
 
 /**
  * Prints a stack trace using given register context for current thread
  */
-void st_print_stack(Registers* regs);
+void sd_print_stack(Registers* regs);
+
+/**
+ * Updates modules list for crash reporting
+ */
+#ifdef SD_UPDATE_MODULES
+void sd_update_modules();
+#endif
+
+// platform-dependent functions
+bool sd_initialize(hymutex_t** p_lock);
+void sd_parse_module_info(native_module_t* module, void* ip);
+void sd_get_c_method_info(MethodInfo* info, native_module_t* module, void* ip);
+int sd_get_cur_tid();
+
+// general functions to call from platform-dependent code
+const char* sd_get_module_type(const char* short_name);
 
 #endif //!__STACK_DUMP_H_

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=611872&r1=611871&r2=611872&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 Mon Jan 14 10:16:47 2008
@@ -29,6 +29,14 @@
 static void ncai_dealloc_module(ncaiModule module);
 
 
+#ifdef PLATFORM_POSIX
+#include <strings.h>
+#define strcmp_case strcasecmp
+#else // Win
+#define strcmp_case _stricmp
+#endif
+
+
 ncaiError JNICALL
 ncaiGetAllLoadedModules (ncaiEnv *env,
         jint *count_ptr,
@@ -156,11 +164,11 @@
 static void ncai_identify_module_is_VM(ncaiModule module)
 {
     char* vm_modules[] = {"java", "vmcore", "harmonyvm", "em", "interpreter",
-        "gc", "gc_cc", "VMI", "vmi", "encoder", "jitrino", "hythr"};
+        "gc_gen", "gc_gen_uncomp", "gc_cc", "vmi", "encoder", "jitrino", "hythr"};
 
     for (size_t i = 0; i < sizeof(vm_modules)/sizeof(vm_modules[0]); i++)
     {
-        if(strcmp(module->info->name, vm_modules[i]) == 0)
+        if(strcmp_case(module->info->name, vm_modules[i]) == 0)
         {
             module->info->kind = NCAI_MODULE_VM_INTERNAL;
             return;
@@ -368,6 +376,9 @@
 
     for (native_module_t* cur = modules; cur; cur = cur->next)
     {
+        if (!cur->filename)
+            continue;
+
         ncaiError error = ncai_add_module(list, cur);
 
         if (error != NCAI_ERROR_NONE)

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp?rev=611872&r1=611871&r2=611872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp Mon Jan 14 10:16:47 2008
@@ -19,10 +19,10 @@
  * @version $Revision$
  */  
 
-#include "stack_dump.h"
-#include "native_stack.h"
+#include <ctype.h>
 #include "vm_threads.h"
 #include "port_malloc.h"
+#include "port_dso.h"
 #include "jit_intf_cpp.h"
 #include "Class.h"
 #include "class_member.h"
@@ -30,221 +30,142 @@
 #include "interpreter_exports.h"
 #include "cci.h"
 #include "m2n.h"
-#include <ctype.h>
-
-#ifdef PLATFORM_NT
-
-#ifndef NO_DBGHELP
-#include <dbghelp.h>
-#pragma comment(linker, "/defaultlib:dbghelp.lib")
-#endif
+#include "native_stack.h"
+#include "native_modules.h"
+#include "natives_support.h"
 
-#else
-#include <unistd.h>
-#endif
+#include "stack_dump.h"
 
-#ifdef POINTER64
-#define W_PI_FMT "016"PI_FMT
-#else
-#define W_PI_FMT "08"PI_FMT
-#endif
 
+static native_module_t* g_modules = NULL;
 
-// Symbolic method info: method name, source file name and a line number of an instruction within the method
-struct MethodInfo {
-    char* method_name;
-    char* file_name;
-    int line;
-};
-
-#ifdef PLATFORM_POSIX
-
-/**
- * Find a module which a given IP address belongs to.
- * Returns module file name and offset of an IP address from beginnig of the segment (used in addr2line tool)
- */
-static char* get_module(native_module_t* info, jint num_modules, void* ip, POINTER_SIZE_INT* offset) {
-
-    for (int i = 0; i < num_modules; i++, info = info->next) {
-        for (int j = 0; j < info->seg_count; j++) {
-            if (info->segments[j].type != SEGMENT_TYPE_DATA) {
-                if ( (POINTER_SIZE_INT) info->segments[j].base <= (POINTER_SIZE_INT) ip &&
-                    (POINTER_SIZE_INT) ip < (POINTER_SIZE_INT) info->segments[j].base + info->segments[j].size) {
-
-                    *offset = (strstr(info->filename, ".so") == NULL) ? // Executable
-                                (POINTER_SIZE_INT)ip :
-                                (POINTER_SIZE_INT)ip - (POINTER_SIZE_INT)info->segments[j].base;
+// Is called to fill modules list (should be called under lock)
+static void sd_fill_modules()
+{
+    if (g_modules)
+        clear_native_modules(&g_modules);
 
-                    return info->filename;
-                }
-            }
-        }
-    }
-    return NULL;
+    int count;
+    bool res = get_all_native_modules(&g_modules, &count);
+    assert(res && g_modules && count);
 }
-#endif
 
-static void st_get_c_method_info(MethodInfo* info, void* ip) {
-    info->method_name = NULL;
-    info->file_name = NULL;
-    info->line = -1;
-#ifdef PLATFORM_NT
-#ifndef NO_DBGHELP
-    if (!SymInitialize(GetCurrentProcess(), NULL, true)) {
-        return;
-    }
-    BYTE smBuf[sizeof(SYMBOL_INFO) + 2048];
-    PSYMBOL_INFO pSymb = (PSYMBOL_INFO)smBuf;
-    pSymb->SizeOfStruct = sizeof(smBuf);
-    pSymb->MaxNameLen = 2048;
-    DWORD64 funcDispl;
-    if(SymFromAddr(GetCurrentProcess(), (DWORD64)ip, &funcDispl, pSymb)) {
-        info->method_name = (char*) STD_MALLOC(strlen(pSymb->Name) + 1);
-        strcpy(info->method_name, pSymb->Name);        
-    }
-    DWORD lineOffset;
-    IMAGEHLP_LINE lineInfo;
-    if (SymGetLineFromAddr(GetCurrentProcess(), (DWORD)ip, &lineOffset, &lineInfo)) {
-        info->line = lineInfo.LineNumber;
-        info->file_name = (char*) STD_MALLOC(strlen(lineInfo.FileName) + 1);
-        strcpy(info->file_name, lineInfo.FileName);
+#ifdef SD_UPDATE_MODULES
+// Is called to update modules info
+void sd_update_modules()
+{
+    hymutex_t* sd_lock;
+    bool res = sd_initialize(&sd_lock);
 
-    }
-#else
-    return;
-#endif
-#else // PLATFORM_NT
-    jint num_modules;
-    native_module_t* modules;
-    if (!get_all_native_modules(&modules, &num_modules)) {
-        fprintf(stderr, "Warning: Cannot get modules info, no symbolic information will be provided\n");
+    if (!res)
         return;
-    }
-    
-    POINTER_SIZE_INT offset;
-    char* module = get_module(modules, num_modules, ip, &offset);
-    if (module) {
-        int po[2];
-        pipe(po);
-
-        char ip_str[20];
-        sprintf(ip_str, "0x%"PI_FMT"x\n", offset);
-
-        if (!fork()) {
-            close(po[0]);
-            dup2(po[1], 1);
-            execlp("addr2line", "addr2line", "-f", "-e", module, "-C", ip_str, NULL);
-            fprintf(stderr, "Warning: Cannot run addr2line. No symbolic information will be available\n");
-            printf("??\n??:0\n"); // Emulate addr2line output
-            exit(-1);
-        } else {
-            close(po[1]);
-            char buf[256];
-            int status;
-            wait(&status);
-            int count = read(po[0], buf, 255);
-            close(po[0]);
-            if (count >= 0) {
-                while (isspace(buf[count-1])) {
-                    count--;
-                }
-                buf[count] = '\0';
-                int i = 0;
-                for (; i < count; i++) {
-                    if (buf[i] == '\n') { // Function name is limited by '\n'
-                        buf[i] = '\0';
-                        info->method_name = (char*) STD_MALLOC(strlen(buf) + 1);
-                        strcpy(info->method_name, buf);
-                        break;
-                    }
-                }
-                char* fn = buf + i + 1;
-                for (; i < count && buf[i] != ':'; i++) // File name and line number are separated by ':'
-                    ;
-                buf[i] = '\0';
-                info->file_name = (char*) STD_MALLOC(strlen(fn) + 1);
-                strcpy(info->file_name, fn);
-                char* line = buf + i + 1;
-                info->line = atoi(line);
-                if (info->line == 0) {
-                    info->line = -1;
-                }
-            } else {
-                fprintf(stderr, "read() failed during execution of addr2line\n");
-            }
-        }
-    }
-#endif
+
+    hymutex_lock(sd_lock);
+    sd_fill_modules();
+    hymutex_unlock(sd_lock);
 }
+#endif // SD_UPDATE_MODULES
+
 
-static char* construct_java_method_name(Method* m)
+static char* sd_construct_java_method_name(Method* m, char* buf)
 {
-    if (!m)
+    if (!m || !buf)
+    {
+        *buf = 0;
         return NULL;
+    }
 
-    const char* mname = m->get_name()->bytes;
-    size_t mlen = m->get_name()->len;
+    char* ptr = buf;
+
+    const char* err_str = "<--Truncated: too long name";
+    size_t err_len = strlen(err_str);
+
+    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;
-    
-    char* method_name = (char*)STD_MALLOC(mlen + clen + dlen + 2);
-    if (!method_name)
-        return NULL;
 
-    char* ptr = method_name;
+    if (clen + 1 > remain)
+    {
+        size_t len = remain - err_len;
+        memcpy(ptr, cname, len);
+        strcpy(ptr + len, err_str);
+        return buf;
+    }
+
     memcpy(ptr, cname, clen);
     ptr += clen;
     *ptr++ = '.';
+    remain -= clen + 1;
+
+    if (mlen > remain)
+    {
+        if (remain > err_len)
+            memcpy(ptr, mname, remain - err_len);
+
+        strcpy(ptr + remain - err_len, err_str);
+        return buf;
+    }
+
     memcpy(ptr, mname, mlen);
     ptr += mlen;
-    memcpy(ptr, descr, dlen);
-    ptr[dlen] = '\0';
+    remain -= mlen;
+
+    if (dlen > remain)
+    {
+        if (remain > err_len)
+            memcpy(ptr, descr, remain - err_len);
 
-    return method_name;
+        strcpy(ptr + remain - err_len, err_str);
+        return buf;
+    }
+
+    strcpy(ptr, descr);
+    return buf;
 }
 
-static void st_get_java_method_info(MethodInfo* info, Method* m, void* ip,
+static void sd_get_java_method_info(MethodInfo* info, Method* m, void* ip,
                                     bool is_ip_past, int inl_depth)
 {
-    info->method_name = NULL;
-    info->file_name = NULL;
+    *info->method_name = 0;
+    *info->file_name = 0;
     info->line = -1;
 
     if (!m || !method_get_class(m))
         return;
 
-    info->method_name = construct_java_method_name(m);
+    if (!sd_construct_java_method_name(m, info->method_name))
+        return;
+
     const char* fname = NULL;
     get_file_and_line(m, ip, is_ip_past, inl_depth, &fname, &info->line);
 
     if (fname)
     {
-        size_t fsize = strlen(fname) + 1;
-        info->file_name = (char*)STD_MALLOC(fsize);
-        if (info->file_name)
-            memcpy(info->file_name, fname, fsize);
+        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);
     }
 }
 
-static void st_print_line(int count, MethodInfo* m) {
+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->method_name ? m->method_name : "??",
+        *m->file_name ? m->file_name : "??",
         m->line);
-
-    if (m->method_name)
-        STD_FREE(m->method_name);
-
-    if (m->file_name)
-        STD_FREE(m->file_name);
 }
 
 
-void st_print_stack_jit(VM_thread* thread,
+static void sd_print_stack_jit(VM_thread* thread,
                         native_frame_t* frames, jint num_frames)
 {
     jint frame_num = 0;
@@ -256,7 +177,7 @@
 
     while ((si && !si_is_past_end(si)) || frame_num < num_frames)
     {
-        MethodInfo m = {NULL, NULL, 0};
+        MethodInfo m;
 
         if (frame_num < num_frames && frames[frame_num].java_depth < 0)
         {
@@ -269,8 +190,9 @@
             }
 
             // pure native frame
-            st_get_c_method_info(&m, frames[frame_num].ip);
-            st_print_line(count++, &m);
+            native_module_t* module = find_native_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;
             continue;
         }
@@ -285,8 +207,9 @@
         if (si_is_native(si) && frame_num < num_frames)
         {
             // Print information from native stack trace for JNI frames
-            st_get_c_method_info(&m, frames[frame_num].ip);
-            st_print_line(count, &m);
+            native_module_t* module = find_native_module(g_modules, frames[frame_num].ip);
+            sd_get_c_method_info(&m, module, frames[frame_num].ip);
+            sd_print_line(count, &m);
         }
         else if (si_is_native(si) && frame_num >= num_frames)
         {
@@ -294,8 +217,8 @@
             // 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));
-            st_get_java_method_info(&m, method, ip, false, -1);
-            st_print_line(count, &m);
+            sd_get_java_method_info(&m, method, ip, false, -1);
+            sd_print_line(count, &m);
         }
         else // !si_is_native(si)
         {
@@ -309,22 +232,23 @@
                 (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--)
+            if (inlined_depth)
             {
-                Method* inl_method = cci->get_jit()->get_inlined_method(
+                for (uint32 i = inlined_depth; i > 0; i--)
+                {
+                    Method* inl_method = cci->get_jit()->get_inlined_method(
                                             cci->get_inline_info(), offset, i);
 
-                st_get_java_method_info(&m, inl_method, ip, is_ip_past, i);
-                st_print_line(count++, &m);
+                    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 (frame_num < num_frames)
+                        ++frame_num; // Go to the next native frame
+                }
             }
 
-            st_get_java_method_info(&m, method, ip, is_ip_past, -1);
-            st_print_line(count, &m);
+            sd_get_java_method_info(&m, method, ip, is_ip_past, -1);
+            sd_print_line(count, &m);
         }
 
         ++count;
@@ -338,7 +262,7 @@
         si_free(si);
 }
 
-void st_print_stack_interpreter(VM_thread* thread,
+static void sd_print_stack_interpreter(VM_thread* thread,
     native_frame_t* frames, jint num_frames)
 {
     FrameHandle* frame = interpreter.interpreter_get_last_frame(thread);
@@ -347,12 +271,13 @@
 
     while (frame || frame_num < num_frames)
     {
-        MethodInfo m = {NULL, NULL, 0};
+        MethodInfo m;
 
         if (frame_num < num_frames && frames[frame_num].java_depth < 0)
         { // pure native frame
-            st_get_c_method_info(&m, frames[frame_num].ip);
-            st_print_line(count++, &m);
+            native_module_t* module = find_native_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;
             continue;
         }
@@ -367,8 +292,9 @@
         if (frame_num < num_frames &&
             (!method || method_is_native(method)))
         {
-            st_get_c_method_info(&m, frames[frame_num].ip);
-            st_print_line(count, &m);
+            native_module_t* module = find_native_module(g_modules, frames[frame_num].ip);
+            sd_get_c_method_info(&m, module, frames[frame_num].ip);
+            sd_print_line(count, &m);
         }
 
         // Print information about method from iterator
@@ -376,8 +302,8 @@
         if (method &&
             (!method_is_native(method) || frame_num >= num_frames))
         {
-            st_get_java_method_info(&m, method, (void*)bc_ptr, false, -1);
-            st_print_line(count, &m);
+            sd_get_java_method_info(&m, method, (void*)bc_ptr, false, -1);
+            sd_print_line(count, &m);
         }
 
         ++count;
@@ -388,8 +314,124 @@
     }
 }
 
-void st_print_stack(Registers* regs)
+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 (!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 sd_print_modules_info(Registers* regs)
 {
+#ifndef SD_UPDATE_MODULES
+    sd_fill_modules(); // Fill modules table if needed
+#endif
+
+    native_module_t* module = find_native_module(g_modules, (void*)regs->get_ip());
+    sd_parse_module_info(module, (void*)regs->get_ip());
+
+    fprintf(stderr, "\nLoaded modules:\n\n");
+    dump_native_modules(g_modules, stderr);
+}
+
+
+static void sd_print_threads_info(VM_thread* cur_thread)
+{
+    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++)
+    {
+        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;
+        jstring name;
+        char* java_name = NULL;
+
+        if (java_thread)
+        {
+            jclass cl = GetObjectClass(jni_env, java_thread);
+            jmethodID id = jni_env->GetMethodID(cl, "getName","()Ljava/lang/String;");
+            name = jni_env->CallObjectMethod(java_thread, id);
+            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 ? java_name : "");
+
+        if (java_thread)
+            jni_env->ReleaseStringUTFChars(name, java_name);
+
+    }
+
+    hythread_iterator_release(&it);
+}
+
+
+void sd_print_stack(Registers* regs)
+{
+    hymutex_t* sd_lock;
+
+    // Enable suspend to allow working with threads
+    int disable_count = hythread_reset_suspend_disable();
+    // Acquire global lock to print threads list and stop other crashed threads
+    hythread_global_lock();
+
+    if (!sd_initialize(&sd_lock))
+        return;
+
+    hymutex_lock(sd_lock);
+
+    VM_thread* thread = get_thread_ptr(); // Can be NULL for pure native thread
+    native_frame_t* frames = NULL;
+
+    // Print crashed modile info and whole list of modules
+    sd_print_modules_info(regs);
+
+    // 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.
@@ -397,9 +439,6 @@
     // walk_native_stack_registers cannot unwind frames in release build),
     // we will use JIT/interpreter stack iterator to complete stack trace.
 
-    VM_thread* thread = get_thread_ptr(); // Can be NULL for pure native thread
-    native_frame_t* frames = NULL;
-
     jint num_frames =
         walk_native_stack_registers(regs, thread, -1, NULL);
 
@@ -411,13 +450,19 @@
     else
         num_frames = 0; // Consider native stack trace empty
 
-   fprintf(stderr, "Stack trace:\n");
+    fprintf(stderr, "\nStack trace:\n");
 
     if(interpreter_enabled() && thread)
-        st_print_stack_interpreter(thread, frames, num_frames);
+        sd_print_stack_interpreter(thread, frames, num_frames);
     else // It should be used also for threads without VM_thread structure
-        st_print_stack_jit(thread, frames, num_frames);
+        sd_print_stack_jit(thread, frames, num_frames);
+
+    fprintf(stderr, "<end of stack trace>\n");
+    fflush(stderr);
+
+    // Do not unlock to prevent other threads from printing crash stack
+    //hymutex_unlock(sd_lock);
 
-  fprintf(stderr, "<end of stack trace>\n");
-  fflush(stderr);
+    hythread_global_unlock();
+    hythread_set_suspend_disable(disable_count);
 }

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_handler.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_handler.cpp?rev=611872&r1=611871&r2=611872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_handler.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_handler.cpp Mon Jan 14 10:16:47 2008
@@ -20,16 +20,12 @@
  */
 
 #include <sys/types.h>
-#if defined(LINUX)
-#include <linux/unistd.h>
-#include <errno.h>
-#else
 #include <unistd.h>
-#endif
 #include <stdio.h>
 #include <semaphore.h>
 
 #include "environment.h"
+#include "platform_lowlevel.h"
 
 #include "crash_handler.h"
 #if defined(FREEBSD)
@@ -60,18 +56,6 @@
     return get_boolean_property("vm.crash_handler", FALSE, VM_PROPERTIES);
 }
 
-#if defined(LINUX)
-#ifdef _syscall0
-_syscall0(pid_t, gettid)
-pid_t gettid(void);
-#else
-static pid_t gettid(void)
-{
-    return (pid_t)syscall(__NR_gettid);
-}
-#endif
-#endif
-
 bool gdb_crash_handler()
 {
     if (!g_prepared ||
@@ -80,13 +64,7 @@
 
     static const int tid_len = 10;
     char tid[tid_len];
-    snprintf(tid, tid_len, "%d",
-#if defined(LINUX)
-        gettid()
-#else
-        getpid()
-#endif
-	);
+    snprintf(tid, tid_len, "%d", gettid());
 
     if (fork() == 0)
     {

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=611872&r1=611871&r2=611872&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 Mon Jan 14 10:16:47 2008
@@ -492,6 +492,14 @@
     general_crash_handler(signum, &regs, "SIGABRT");
 }
 
+static void process_crash(Registers* regs)
+{
+    // Print register info
+    print_state(regs);
+    // print stack trace
+    sd_print_stack(regs);
+}
+
 static void general_crash_handler(int signum, Registers* regs, const char* message)
 {
     // setup default handler
@@ -502,8 +510,7 @@
     if (!is_gdb_crash_handler_enabled() ||
         !gdb_crash_handler())
     {
-        // print stack trace
-        st_print_stack(regs);
+        process_crash(regs);
     }
 }
 

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=611872&r1=611871&r2=611872&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 Mon Jan 14 10:16:47 2008
@@ -49,6 +49,26 @@
 
 #define _MAX_PATH PATH_MAX
 
+
+#if defined(LINUX)
+
+#include <sys/types.h>
+#include <linux/unistd.h>
+#include <errno.h>
+
+#ifdef _syscall0
+pid_t gettid(void);
+#else // _syscall0
+#include <sys/syscall.h>
+#include <unistd.h>
+#define gettid() ((pid_t)syscall(__NR_gettid))
+#endif
+
+#else // !LINUX
+#define gettid() getpid()
+#endif
+
+
 #ifdef __cplusplus
 }
 #endif

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=611872&r1=611871&r2=611872&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 Mon Jan 14 10:16:47 2008
@@ -101,5 +101,6 @@
 void ucontext_to_regs(Registers* regs, ucontext_t *uc);
 void regs_to_ucontext(ucontext_t *uc, Registers* regs);
 
+void print_state(Registers* regs);
 
 #endif // _SIGNALS_COMMON_H_

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_modules.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_modules.cpp?rev=611872&r1=611871&r2=611872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_modules.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_modules.cpp Mon Jan 14 10:16:47 2008
@@ -29,23 +29,23 @@
 #include "native_modules.h"
 
 
-void clear_native_modules(native_module_t** list_ptr)
-{
-    native_module_t* cur = *list_ptr;
-
-    while (cur)
-    {
-        native_module_t* next = cur->next;
-
-        if (cur->filename)
-            STD_FREE(cur->filename);
+typedef struct _raw_module raw_module;
 
-        STD_FREE(cur);
-        cur = next;
-    }
+// Structure to accumulate several segments for the same module
+struct _raw_module
+{
+    void*               start;
+    void*               end;
+    bool                acc_r;
+    bool                acc_x;
+    char*               name;
+    raw_module*         next;
+};
+
+void native_clear_raw_list(raw_module*);
+raw_module* native_add_raw_segment(raw_module*, void*, void*, char, char);
+native_module_t* native_fill_module(raw_module*, size_t);
 
-    *list_ptr = NULL;
-}
 
 void native_clear_raw_list(raw_module* list)
 {
@@ -150,10 +150,14 @@
         int res = sscanf(buf, "%" PI_FMT "x-%" PI_FMT "x %c%*c%c%*c %*" PI_FMT "x %*02x:%*02x %*u %s",
             &start, &end, &acc_r, &acc_x, filename);
 
-        if (res < 5)
+        if (res < 4)
             continue;
 
-        if (module.name == NULL || // First module, first record
+        if (res < 5)
+            *filename = 0;
+
+        if (module.name == NULL || // First module, or single memory region
+            !(*filename)        || // Single memory region
             strcmp(module.name, filename) != 0) // Next module
         {
             if (segment_count) // Add previous module
@@ -173,16 +177,21 @@
                 cur_next_ptr = &filled->next;
             }
 
-            module.name = (char*)STD_MALLOC(strlen(filename) + 1);
-            if (module.name == NULL)
+            if (*filename)
             {
-                native_clear_raw_list(&module);
-                clear_native_modules(list_ptr);
-                fclose(file);
-                return false;
-            }
+                module.name = (char*)STD_MALLOC(strlen(filename) + 1);
+                if (module.name == NULL)
+                {
+                    native_clear_raw_list(&module);
+                    clear_native_modules(list_ptr);
+                    fclose(file);
+                    return false;
+                }
 
-            strcpy(module.name, filename);
+                strcpy(module.name, filename);
+            }
+            else
+                module.name = NULL;
 
             // Store new module information
             module.start = (void*)start;

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/os_wrapper.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/os_wrapper.cpp?rev=611872&r1=611871&r2=611872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/os_wrapper.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/os_wrapper.cpp Mon Jan 14 10:16:47 2008
@@ -28,6 +28,7 @@
 #include <errno.h>
 
 #include "port_malloc.h"
+#include "platform_lowlevel.h"
 
 #ifndef __SMP__
 #error
@@ -47,5 +48,11 @@
 #error
 -- must be using an old version of pthreads
 -- which uses SIGUSR1, SIGUSR2 (which conflicts with the java app debugger and vm)
+#endif
+#endif
+
+#ifdef LINUX
+#ifdef _syscall0
+_syscall0(pid_t, gettid)
 #endif
 #endif

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_em64t.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_em64t.cpp?rev=611872&r1=611871&r2=611872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_em64t.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_em64t.cpp Mon Jan 14 10:16:47 2008
@@ -17,6 +17,7 @@
 
 
 #include <sys/ucontext.h>
+#include <stdio.h>
 #include "vm_core_types.h"
 #include "signals_common.h"
 
@@ -89,4 +90,26 @@
         pregs->r9 = param;
         return;
     }
+}
+
+void print_state(Registers* regs)
+{
+    fprintf(stderr, "Registers:\n");
+    fprintf(stderr, "    RAX: 0x%016llx, RBX: 0x%016llx\n",
+        regs->rax, regs->rbx);
+    fprintf(stderr, "    RCX: 0x%016llx, RDX: 0x%016llx\n",
+        regs->rcx, regs->rdx);
+    fprintf(stderr, "    RSI: 0x%016llx, RDI: 0x%016llx\n",
+        regs->rsi, regs->rdi);
+    fprintf(stderr, "    RSP: 0x%016llx, RBP: 0x%016llx\n",
+        regs->rsp, regs->rbp);
+    fprintf(stderr, "    R8 : 0x%016llx, R9 : 0x%016llx\n",
+        regs->r8,  regs->r9);
+    fprintf(stderr, "    R10: 0x%016llx, R11: 0x%016llx\n",
+        regs->r10, regs->r11);
+    fprintf(stderr, "    R12: 0x%016llx, R13: 0x%016llx\n",
+        regs->r12, regs->r13);
+    fprintf(stderr, "    R14: 0x%016llx, R15: 0x%016llx\n",
+        regs->r14, regs->r15);
+    fprintf(stderr, "    RIP: 0x%016llx\n", regs->rip);
 }

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp?rev=611872&r1=611871&r2=611872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp Mon Jan 14 10:16:47 2008
@@ -17,6 +17,7 @@
 
 
 #include <sys/ucontext.h>
+#include <stdio.h>
 #include "vm_core_types.h"
 #include "signals_common.h"
 
@@ -82,3 +83,14 @@
 #else
 #error need to add correct mcontext_t lookup for registers
 #endif
+
+void print_state(Registers* regs)
+{
+    fprintf(stderr, "Registers:\n");
+    fprintf(stderr, "    EAX: 0x%08x, EBX: 0x%08x, ECX: 0x%08x, EDX: 0x%08x\n",
+        regs->eax, regs->ebx, regs->ecx, regs->edx);
+    fprintf(stderr, "    ESI: 0x%08x, EDI: 0x%08x, ESP: 0x%08x, EBP: 0x%08x\n",
+        regs->esi, regs->edi, regs->esp, regs->ebp);
+    fprintf(stderr, "    EIP: 0x%08x\n", regs->eip);
+}
+

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=611872&r1=611871&r2=611872&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 Mon Jan 14 10:16:47 2008
@@ -138,7 +138,7 @@
         !gdb_crash_handler())
     {
         // print stack trace
-        st_print_stack(&regs);
+        sd_print_stack(&regs);
     }
 }
 
@@ -178,7 +178,7 @@
         !gdb_crash_handler())
     {
         // print stack trace
-        st_print_stack(&regs);
+        sd_print_stack(&regs);
     }
 }
 
@@ -462,7 +462,7 @@
         !gdb_crash_handler())
     {
         // print stack trace
-        st_print_stack(&regs);
+        sd_print_stack(&regs);
     }
 }
 

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/stack_dump_platf.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/stack_dump_platf.cpp?rev=611872&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/stack_dump_platf.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/stack_dump_platf.cpp Mon Jan 14 10:16:47 2008
@@ -0,0 +1,204 @@
+/*
+ *  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 <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "open/hythread_ext.h"
+#include "native_stack.h"
+#include "port_filepath.h"
+#include "port_dso.h"
+#include "stack_dump.h"
+
+
+static hymutex_t g_lock;
+
+
+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;
+
+    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)
+{
+    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 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"X\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"X:0x%"W_PI_FMT"X%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"X:0x%"W_PI_FMT"X%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)
+{
+    *info->method_name = 0;
+    *info->file_name = 0;
+    info->line = -1;
+
+    if (!module || !module->filename)
+        return;
+
+    POINTER_SIZE_INT offset = (POINTER_SIZE_INT)ip;
+
+    if (strstr(module->filename, PORT_DSO_EXT) != NULL) // Shared object
+    { // IP for addr2line should be an offset within shared library
+        native_segment_t* seg = sd_find_segment(module, ip);
+        offset -= (POINTER_SIZE_INT)seg->base;
+    }
+
+    int po[2];
+    pipe(po);
+
+    char ip_str[20];
+    sprintf(ip_str, "0x%"PI_FMT"x\n", offset);
+
+    if (!fork())
+    {
+        close(po[0]);
+        dup2(po[1], 1);
+        execlp("addr2line", "addr2line", "-f", "-s", "-e", module->filename, "-C", ip_str, NULL);
+        //fprintf(stderr, "Warning: Cannot run addr2line. No symbolic information will be available\n");
+        printf("??\n??:0\n"); // Emulate addr2line output
+        exit(-1);
+    }
+    else
+    {
+        close(po[1]);
+        char buf[sizeof(info->method_name) + sizeof(info->file_name)];
+        int status;
+        wait(&status);
+        int count = read(po[0], buf, sizeof(buf) - 1);
+        close(po[0]);
+
+        if (count < 0)
+        {
+            fprintf(stderr, "read() failed during addr2line execution\n");
+            return;
+        }
+
+        while (isspace(buf[count-1]))
+            count--;
+
+        buf[count] = '\0';
+        int i = 0;
+
+        for (; i < count; i++)
+        {
+            if (buf[i] == '\n')
+            { // Function name is limited by '\n'
+                buf[i] = '\0';
+                strncpy(info->method_name, buf, sizeof(info->method_name));
+                break;
+            }
+        }
+
+        if (i == count)
+            return;
+
+        char* fn = buf + i + 1;
+
+        for (; i < count && buf[i] != ':'; i++); // File name and line number are separated by ':'
+
+        if (i == count)
+            return;
+
+        buf[i] = '\0';
+        strncpy(info->file_name, fn, sizeof(info->file_name));
+
+        info->line = atoi(buf + i + 1); // Line number
+
+        if (info->line == 0)
+            info->line = -1;
+    }
+}
+
+int sd_get_cur_tid()
+{
+    return gettid();
+}

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

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_modules_common.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_modules_common.cpp?rev=611872&r1=611871&r2=611872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_modules_common.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_modules_common.cpp Mon Jan 14 10:16:47 2008
@@ -15,7 +15,9 @@
  *  limitations under the License.
  */
 
+#include "open/types.h"
 #include "native_modules.h"
+#include "port_malloc.h"
 
 native_module_t* find_native_module(native_module_t* modules, void* code_ptr)
 {
@@ -38,13 +40,35 @@
 {
     for (native_module_t* module = modules; module; module = module->next)
     {
+        if (!module->filename)
+            continue;
+
         fprintf(out, "%s:\n", module->filename);
 
         for (size_t i = 0; i < module->seg_count; i++)
         {
-            char* base = (char*)module->segments[i].base;
+            size_t base = (size_t)module->segments[i].base;
 
-            fprintf(out, "\t%p:%p\n", base, base + module->segments[i].size);
+            fprintf(out, "\t0x%"W_PI_FMT"x:0x%"W_PI_FMT"x\n",
+                    base, base + module->segments[i].size);
         }
     }
+}
+
+void clear_native_modules(native_module_t** list_ptr)
+{
+    native_module_t* cur = *list_ptr;
+
+    while (cur)
+    {
+        native_module_t* next = cur->next;
+
+        if (cur->filename)
+            STD_FREE(cur->filename);
+
+        STD_FREE(cur);
+        cur = next;
+    }
+
+    *list_ptr = NULL;
 }

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=611872&r1=611871&r2=611872&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 Mon Jan 14 10:16:47 2008
@@ -39,6 +39,8 @@
 #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"
 
@@ -296,6 +298,8 @@
 
     returnCode = pinfo->handle;
 
+    sd_update_modules(); // Updates modules list for crash handling (in debug)
+
 NATIVES_LOAD_LIBRARY_EXIT :
 
 #ifdef PLATFORM_NT
@@ -738,25 +742,15 @@
 {
     assert(name != NULL && buf != NULL);
 
-    const char* filepointer = strrchr(name, '/');
+    const char* filepointer = port_filepath_basename(name);
 
     if (!filepointer)
-        filepointer = strrchr(name, '\\');
-
-    if (filepointer)
-    {
-        if (strlen(filepointer + 1) > _MAX_PATH)
-            return NULL;
+        return NULL;
 
-        strcpy(buf, filepointer + 1);
-    }
-    else
-    {
-        if (strlen(name) > _MAX_PATH)
-            return NULL;
+    if (strlen(filepointer) > _MAX_PATH)
+        return NULL;
 
-        strcpy(buf, name);
-    }
+    strcpy(buf, filepointer);
 
 #ifdef PLATFORM_NT
     lowercase_buf(buf);

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp?rev=611872&r1=611871&r2=611872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp Mon Jan 14 10:16:47 2008
@@ -47,7 +47,7 @@
     PCONTEXT context = nt_exception->ContextRecord;
     Registers regs;
     nt_to_vm_context(context, &regs);
-    st_print_stack(&regs);
+    sd_print_stack(&regs);
 }
 
 

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_modules.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_modules.cpp?rev=611872&r1=611871&r2=611872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_modules.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_modules.cpp Mon Jan 14 10:16:47 2008
@@ -73,24 +73,6 @@
     return true;
 }
 
-void clear_native_modules(native_module_t** list_ptr)
-{
-    native_module_t* cur = *list_ptr;
-
-    while (cur)
-    {
-        native_module_t* next = cur->next;
-
-        if (cur->filename)
-            STD_FREE(cur->filename);
-
-        STD_FREE(cur);
-        cur = next;
-    }
-
-    *list_ptr = NULL;
-}
-
 native_module_t* fill_module(MODULEENTRY32 src)
 {
     native_module_t* module =
@@ -111,10 +93,19 @@
     strlwr(module->filename);
 
     module->seg_count = 1;
-    module->segments[0].type = SEGMENT_TYPE_UNKNOWN;
     module->segments[0].base = src.modBaseAddr;
     module->segments[0].size = (size_t)src.modBaseSize;
     module->next = NULL;
+
+    MEMORY_BASIC_INFORMATION mem_info;
+    VirtualQuery(src.modBaseAddr, &mem_info, sizeof(mem_info));
+
+    if ((mem_info.Protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) != 0)
+        module->segments[0].type = SEGMENT_TYPE_CODE;
+    else if ((mem_info.Protect & (PAGE_READWRITE | PAGE_READONLY)) != 0)
+        module->segments[0].type = SEGMENT_TYPE_DATA;
+    else
+        module->segments[0].type = SEGMENT_TYPE_UNKNOWN;
 
     return module;
 }

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/stack_dump_platf.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/stack_dump_platf.cpp?rev=611872&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/stack_dump_platf.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/stack_dump_platf.cpp Mon Jan 14 10:16:47 2008
@@ -0,0 +1,205 @@
+/*
+ *  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 "open/hythread_ext.h"
+#include "native_stack.h"
+#include "stack_dump.h"
+#include "port_filepath.h"
+
+#ifndef NO_DBGHELP
+#include <dbghelp.h>
+#pragma comment(linker, "/defaultlib:dbghelp.lib")
+#endif
+
+
+static hymutex_t g_lock;
+
+#ifndef NO_DBGHELP
+typedef BOOL (WINAPI *SymFromAddr_type)
+   (IN  HANDLE              hProcess,
+    IN  DWORD64             Address,
+    OUT PDWORD64            Displacement,
+    IN OUT PSYMBOL_INFO     Symbol    );
+typedef BOOL (WINAPI *SymGetLineFromAddr64_type)
+   (IN  HANDLE                  hProcess,
+    IN  DWORD64                 qwAddr,
+    OUT PDWORD                  pdwDisplacement,
+    OUT PIMAGEHLP_LINE64        Line64);
+
+typedef BOOL (WINAPI *SymGetLineFromAddr_type)
+   (IN  HANDLE                hProcess,
+    IN  DWORD                 dwAddr,
+    OUT PDWORD                pdwDisplacement,
+    OUT PIMAGEHLP_LINE        Line    );
+
+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;
+
+#ifndef NO_DBGHELP
+// Preventive initialization does not work
+//        if (!SymInitialize(GetCurrentProcess(), NULL, TRUE))
+//            return false;
+
+        HMODULE hdbghelp = ::LoadLibrary("dbghelp");
+
+        if (hdbghelp)
+        {
+            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
+
+        initialized = true;
+    }
+
+    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";
+
+    if ((pinfo->Protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ |
+                          PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY |
+                          PAGE_READWRITE | PAGE_READONLY)) != 0)
+        return "";
+
+    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)
+    {
+        native_segment_t* segment = module->segments;
+
+        assert(module->filename);
+
+        if (!module->filename)
+        { // We should not reach this code
+            fprintf(stderr, "Unknown memory region 0x%"W_PI_FMT"X:0x%"W_PI_FMT"X%s\n",
+                    (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);
+        return;
+    }
+
+    // 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"X:0x%"W_PI_FMT"X %s\n",
+                start_addr, end_addr, sd_get_region_access_info(&mem_info));
+}
+
+
+void sd_get_c_method_info(MethodInfo* info, native_module_t* UNREF module, void* ip)
+{
+    *info->method_name = 0;
+    *info->file_name = 0;
+    info->line = -1;
+
+#ifndef NO_DBGHELP
+
+    if (!SymInitialize(GetCurrentProcess(), NULL, TRUE))
+        return;
+
+    BYTE smBuf[sizeof(SYMBOL_INFO) + SD_MNAME_LENGTH - 1];
+    PSYMBOL_INFO pSymb = (PSYMBOL_INFO)smBuf;
+    pSymb->SizeOfStruct = sizeof(SYMBOL_INFO);
+    pSymb->MaxNameLen = SD_MNAME_LENGTH;
+    DWORD64 funcDispl;
+
+    if (g_SymFromAddr &&
+        g_SymFromAddr(GetCurrentProcess(), (DWORD64)(POINTER_SIZE_INT)ip, &funcDispl, pSymb))
+    {
+        strcpy(info->method_name, pSymb->Name);
+    }
+
+    if (g_SymGetLineFromAddr64)
+    {
+        DWORD offset;
+        IMAGEHLP_LINE64 lineinfo;
+        if (g_SymGetLineFromAddr64(GetCurrentProcess(),
+                                   (DWORD64)(POINTER_SIZE_INT)ip,
+                                   &offset, &lineinfo))
+        {
+            info->line = lineinfo.LineNumber;
+            strncpy(info->file_name, lineinfo.FileName, sizeof(info->file_name));
+            return;
+        }
+    }
+
+    if (g_SymGetLineFromAddr)
+    {
+        DWORD offset;
+        IMAGEHLP_LINE lineinfo;
+        if (g_SymGetLineFromAddr(GetCurrentProcess(),
+                                 (DWORD)(POINTER_SIZE_INT)ip,
+                                 &offset, &lineinfo))
+        {
+            info->line = lineinfo.LineNumber;
+            strncpy(info->file_name, lineinfo.FileName, sizeof(info->file_name));
+        }
+    }
+
+#endif // #ifndef NO_DBGHELP
+}
+
+int sd_get_cur_tid()
+{
+    return GetCurrentThreadId();
+}

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