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, ®s, "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(®s);
+ sd_print_stack(®s);
}
}
@@ -178,7 +178,7 @@
!gdb_crash_handler())
{
// print stack trace
- st_print_stack(®s);
+ sd_print_stack(®s);
}
}
@@ -462,7 +462,7 @@
!gdb_crash_handler())
{
// print stack trace
- st_print_stack(®s);
+ sd_print_stack(®s);
}
}
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, ®s);
- st_print_stack(®s);
+ sd_print_stack(®s);
}
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