diff --git a/vm/vmcore/src/jni/jni.cpp b/vm/vmcore/src/jni/jni.cpp index ce99890..3b1b77f 100644 --- a/vm/vmcore/src/jni/jni.cpp +++ b/vm/vmcore/src/jni/jni.cpp @@ -1463,6 +1463,7 @@ VMEXPORT jint JNICALL DestroyJavaVM(Java // Destroy VM environment. delete java_vm->vm_env; + java_vm->vm_env = NULL; // Destroy VM pool. apr_pool_destroy(java_vm->pool); diff --git a/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp b/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp index 131830a..8c4b2b0 100644 --- a/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp +++ b/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp @@ -52,16 +52,38 @@ static void print_callstack(LPEXCEPTION_ static LONG process_crash(LPEXCEPTION_POINTERS nt_exception, const char* msg = NULL) { +static __declspec(thread) POINTER_SIZE_INT saved_eip = 0; + Registers regs; nt_to_vm_context(nt_exception->ContextRecord, ®s); // Check crash location to prevent infinite recursion - if (regs.get_ip() == p_TLS_vmthread->regs.get_ip()) + if (regs.get_ip() == (void*)saved_eip) return EXCEPTION_CONTINUE_SEARCH; // Store registers to compare IP in future - p_TLS_vmthread->regs = regs; + saved_eip = (POINTER_SIZE_INT)regs.get_ip(); + + switch (nt_exception->ExceptionRecord->ExceptionCode) + { + case EXCEPTION_DATATYPE_MISALIGNMENT: + case EXCEPTION_ILLEGAL_INSTRUCTION: + case EXCEPTION_ACCESS_VIOLATION: + case EXCEPTION_PRIV_INSTRUCTION: + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + case EXCEPTION_FLT_OVERFLOW: + case EXCEPTION_FLT_UNDERFLOW: + case EXCEPTION_INT_DIVIDE_BY_ZERO: + case EXCEPTION_INT_OVERFLOW: + break; - if (get_boolean_property("vm.assert_dialog", TRUE, VM_PROPERTIES)) + case EXCEPTION_STACK_OVERFLOW: + default: + return EXCEPTION_CONTINUE_SEARCH; + } + + // We can't obtain a value of property if loader_env is NULL + if (VM_Global_State::loader_env == NULL || + get_boolean_property("vm.assert_dialog", TRUE, VM_PROPERTIES)) return EXCEPTION_CONTINUE_SEARCH; print_state(nt_exception, msg); @@ -204,28 +226,32 @@ LONG NTAPI vectored_exception_handler_in PCONTEXT context = nt_exception->ContextRecord; Registers regs; bool flag_replaced = false; + VM_thread* vmthread = p_TLS_vmthread; // Convert NT context to Registers nt_to_vm_context(context, ®s); POINTER_SIZE_INT saved_eip = (POINTER_SIZE_INT)regs.get_ip(); - assert(p_TLS_vmthread); - // If exception is occured in processor instruction previously - // instrumented by breakpoint, the actual exception address will reside - // in jvmti_jit_breakpoints_handling_buffer - // We should replace exception address with saved address of instruction - POINTER_SIZE_INT break_buf = - (POINTER_SIZE_INT)p_TLS_vmthread->jvmti_jit_breakpoints_handling_buffer; - if (saved_eip >= break_buf && - saved_eip < break_buf + 50) + bool in_java = false; + + if (vmthread) { - flag_replaced = true; - regs.set_ip(p_TLS_vmthread->jvmti_saved_exception_registers.get_ip()); - vm_to_nt_context(®s, context); - } + // If exception is occured in processor instruction previously + // instrumented by breakpoint, the actual exception address will reside + // in jvmti_jit_breakpoints_handling_buffer + // We should replace exception address with saved address of instruction + POINTER_SIZE_INT break_buf = + (POINTER_SIZE_INT)vmthread->jvmti_jit_breakpoints_handling_buffer; + if (saved_eip >= break_buf && + saved_eip < break_buf + 50) + { + flag_replaced = true; + regs.set_ip(vmthread->jvmti_saved_exception_registers.get_ip()); + vm_to_nt_context(®s, context); + } - TRACE2("signals", ("VEH received an exception: code = %x, ip = %p, sp = %p", - nt_exception->ExceptionRecord->ExceptionCode, regs.get_ip(), regs_get_sp(®s))); + in_java = (vm_identify_eip(regs.get_ip()) == VM_TYPE_JAVA); + } // the possible reasons for hardware exception are // - segfault or division by zero in java code @@ -240,10 +266,11 @@ LONG NTAPI vectored_exception_handler_in // - other (internal VM error or debugger breakpoint) // => delegate to default handler - bool in_java = (vm_identify_eip(regs.get_ip()) == VM_TYPE_JAVA); - - // delegate "other" cases to default handler - if (!in_java && code != STATUS_STACK_OVERFLOW) + // delegate "other" cases to crash handler + // Crash handler shouls be invoked when VM_thread is not attached to VM + // or exception has occured in native code and it's not STACK_OVERFLOW + if (!vmthread || + (!in_java && code != STATUS_STACK_OVERFLOW)) { LONG result = process_crash(nt_exception); regs.set_ip((void*)saved_eip); @@ -251,6 +278,9 @@ LONG NTAPI vectored_exception_handler_in return result; } + TRACE2("signals", ("VEH received an exception: code = %x, ip = %p, sp = %p", + nt_exception->ExceptionRecord->ExceptionCode, regs.get_ip(), regs_get_sp(®s))); + // if HWE occured in java code, suspension should also have been disabled assert(!in_java || !hythread_is_suspend_enabled()); @@ -267,7 +297,7 @@ LONG NTAPI vectored_exception_handler_in ("StackOverflowError detected at ip = %p, esp = %p", regs.get_ip(), regs_get_sp(®s))); - p_TLS_vmthread->restore_guard_page = true; + vmthread->restore_guard_page = true; exn_class = env->java_lang_StackOverflowError_Class; if (in_java) { // stack overflow occured in java code: @@ -339,7 +369,7 @@ LONG NTAPI vectored_exception_handler_in // save register context of hardware exception site // into thread-local registers snapshot - p_TLS_vmthread->regs = regs; + vmthread->regs = regs; // __cdecl <=> push parameters in the reversed order // push in_java argument onto stack