--- old/src/cpu/aarch64/vm/frame_aarch64.cpp 2017-06-28 09:40:11.879072380 -0400 +++ new/src/cpu/aarch64/vm/frame_aarch64.cpp 2017-06-28 09:40:11.499317185 -0400 @@ -784,6 +784,8 @@ frame::frame(void* sp, void* fp, void* pc) { init((intptr_t*)sp, (intptr_t*)fp, (address)pc); } + +void frame::pd_ps() {} #endif void JavaFrameAnchor::make_walkable(JavaThread* thread) { --- old/src/cpu/arm/vm/frame_arm.cpp 2017-06-28 09:40:21.061406214 -0400 +++ new/src/cpu/arm/vm/frame_arm.cpp 2017-06-28 09:40:20.726881665 -0400 @@ -621,6 +621,8 @@ frame::frame(void* sp, void* fp, void* pc) { init((intptr_t*)sp, (intptr_t*)fp, (address)pc); } + +void frame::pd_ps() {} #endif intptr_t *frame::initial_deoptimization_info() { --- old/src/cpu/ppc/vm/frame_ppc.cpp 2017-06-28 09:40:29.551655468 -0400 +++ new/src/cpu/ppc/vm/frame_ppc.cpp 2017-06-28 09:40:29.218479648 -0400 @@ -244,4 +244,6 @@ frame::frame(void* sp, void* fp, void* pc) : _sp((intptr_t*)sp), _unextended_sp((intptr_t*)sp) { find_codeblob_and_set_pc_and_deopt_state((address)pc); // also sets _fp and adjusts _unextended_sp } + +void frame::pd_ps() {} #endif --- old/src/cpu/s390/vm/frame_s390.cpp 2017-06-28 09:40:38.082131656 -0400 +++ new/src/cpu/s390/vm/frame_s390.cpp 2017-06-28 09:40:37.747680163 -0400 @@ -496,6 +496,8 @@ } } + +void frame::pd_ps() {} #endif // !PRODUCT intptr_t *frame::initial_deoptimization_info() { --- old/src/cpu/sparc/vm/frame_sparc.cpp 2017-06-28 09:40:46.999525624 -0400 +++ new/src/cpu/sparc/vm/frame_sparc.cpp 2017-06-28 09:40:46.664251672 -0400 @@ -785,3 +785,53 @@ // unused... but returns fp() to minimize changes introduced by 7087445 return fp(); } + +#ifndef PRODUCT +extern "C" void findpc(int x); + +void frame::pd_ps() { + intptr_t* curr_sp = sp(); + intptr_t* prev_sp = curr_sp - 1; + intptr_t *pc = NULL; + intptr_t *next_pc = NULL; + int count = 0; + tty->print_cr("register window backtrace from " INTPTR_FORMAT ":", p2i(curr_sp)); + while (curr_sp != NULL && ((intptr_t)curr_sp & 7) == 0 && curr_sp > prev_sp && curr_sp < prev_sp+1000) { + pc = next_pc; + next_pc = (intptr_t*) curr_sp[I7->sp_offset_in_saved_window()]; + tty->print("[%d] curr_sp=" INTPTR_FORMAT " pc=", count, p2i(curr_sp)); + findpc((intptr_t)pc); + if (WizardMode && Verbose) { + // print register window contents also + tty->print_cr(" L0..L7: {" + INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " + INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " ", + curr_sp[0+0], curr_sp[0+1], curr_sp[0+2], curr_sp[0+3], + curr_sp[0+4], curr_sp[0+5], curr_sp[0+6], curr_sp[0+7]); + tty->print_cr(" I0..I7: {" + INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " + INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " ", + curr_sp[8+0], curr_sp[8+1], curr_sp[8+2], curr_sp[8+3], + curr_sp[8+4], curr_sp[8+5], curr_sp[8+6], curr_sp[8+7]); + // (and print stack frame contents too??) + + CodeBlob *b = CodeCache::find_blob((address) pc); + if (b != NULL) { + if (b->is_nmethod()) { + Method* m = ((nmethod*)b)->method(); + int nlocals = m->max_locals(); + int nparams = m->size_of_parameters(); + tty->print_cr("compiled java method (locals = %d, params = %d)", nlocals, nparams); + } + } + } + prev_sp = curr_sp; + curr_sp = (intptr_t *)curr_sp[FP->sp_offset_in_saved_window()]; + curr_sp = (intptr_t *)((intptr_t)curr_sp + STACK_BIAS); + count += 1; + } + if (curr_sp != NULL) + tty->print("[%d] curr_sp=" INTPTR_FORMAT " [bogus sp!]", count, p2i(curr_sp)); +} + +#endif // PRODUCT --- old/src/cpu/x86/vm/frame_x86.cpp 2017-06-28 09:40:55.504922061 -0400 +++ new/src/cpu/x86/vm/frame_x86.cpp 2017-06-28 09:40:55.171392345 -0400 @@ -680,6 +680,9 @@ frame::frame(void* sp, void* fp, void* pc) { init((intptr_t*)sp, (intptr_t*)fp, (address)pc); } + +void frame::pd_ps() {} + #endif void JavaFrameAnchor::make_walkable(JavaThread* thread) { --- old/src/cpu/zero/vm/frame_zero.cpp 2017-06-28 09:41:04.146301865 -0400 +++ new/src/cpu/zero/vm/frame_zero.cpp 2017-06-28 09:41:03.811480071 -0400 @@ -444,4 +444,6 @@ frame::frame(void* sp, void* fp, void* pc) { Unimplemented(); } + +void frame::pd_ps() {} #endif --- old/src/os/aix/vm/os_aix.cpp 2017-06-28 09:41:13.661123720 -0400 +++ new/src/os/aix/vm/os_aix.cpp 2017-06-28 09:41:13.232111269 -0400 @@ -1623,7 +1623,7 @@ // Ctrl-C is pressed during error reporting, likely because the error // handler fails to abort. Let VM die immediately. - if (sig == SIGINT && is_error_reported()) { + if (sig == SIGINT && VMError::is_error_reported()) { os::die(); } --- old/src/os/bsd/vm/os_bsd.cpp 2017-06-28 09:41:22.469751807 -0400 +++ new/src/os/bsd/vm/os_bsd.cpp 2017-06-28 09:41:22.105846981 -0400 @@ -1847,7 +1847,7 @@ // Ctrl-C is pressed during error reporting, likely because the error // handler fails to abort. Let VM die immediately. - if (sig == SIGINT && is_error_reported()) { + if (sig == SIGINT && VMError::is_error_reported()) { os::die(); } --- old/src/os/linux/vm/os_linux.cpp 2017-06-28 09:41:31.051871792 -0400 +++ new/src/os/linux/vm/os_linux.cpp 2017-06-28 09:41:30.707957816 -0400 @@ -2402,7 +2402,7 @@ // Ctrl-C is pressed during error reporting, likely because the error // handler fails to abort. Let VM die immediately. - if (sig == SIGINT && is_error_reported()) { + if (sig == SIGINT && VMError::is_error_reported()) { os::die(); } --- old/src/os/solaris/vm/attachListener_solaris.cpp 2017-06-28 09:41:39.838861018 -0400 +++ new/src/os/solaris/vm/attachListener_solaris.cpp 2017-06-28 09:41:39.452874114 -0400 @@ -27,6 +27,7 @@ #include "runtime/os.inline.hpp" #include "services/attachListener.hpp" #include "services/dtraceAttacher.hpp" +#include "utilities/vmError.hpp" #include #include @@ -309,7 +310,7 @@ // if we are stopped at ShowMessageBoxOnError then maybe we can // load a diagnostic library - if (res == 0 && is_error_reported()) { + if (res == 0 && VMError::is_error_reported()) { if (ShowMessageBoxOnError) { // TBD - support loading of diagnostic library here } --- old/src/os/solaris/vm/os_solaris.cpp 2017-06-28 09:41:48.274494751 -0400 +++ new/src/os/solaris/vm/os_solaris.cpp 2017-06-28 09:41:48.017192814 -0400 @@ -2095,7 +2095,7 @@ static void UserHandler(int sig, void *siginfo, void *context) { // Ctrl-C is pressed during error reporting, likely because the error // handler fails to abort. Let VM die immediately. - if (sig == SIGINT && is_error_reported()) { + if (sig == SIGINT && VMError::is_error_reported()) { os::die(); } --- old/src/os/windows/vm/os_windows.cpp 2017-06-28 09:41:56.718733519 -0400 +++ new/src/os/windows/vm/os_windows.cpp 2017-06-28 09:41:56.374199525 -0400 @@ -1979,7 +1979,7 @@ static BOOL WINAPI consoleHandler(DWORD event) { switch (event) { case CTRL_C_EVENT: - if (is_error_reported()) { + if (VMError::is_error_reported()) { // Ctrl-C is pressed during error reporting, likely because the error // handler fails to abort. Let VM die immediately. os::die(); --- old/src/share/vm/code/codeCache.cpp 2017-06-28 09:42:05.867787908 -0400 +++ new/src/share/vm/code/codeCache.cpp 2017-06-28 09:42:05.528559712 -0400 @@ -50,6 +50,7 @@ #include "runtime/sweeper.hpp" #include "services/memoryService.hpp" #include "trace/tracing.hpp" +#include "utilities/vmError.hpp" #include "utilities/xmlstream.hpp" #ifdef COMPILER1 #include "c1/c1_Compilation.hpp" @@ -593,7 +594,7 @@ CodeBlob* CodeCache::find_blob(void* start) { CodeBlob* result = find_blob_unsafe(start); // We could potentially look up non_entrant methods - guarantee(result == NULL || !result->is_zombie() || result->is_locked_by_vm() || is_error_reported(), "unsafe access to zombie method"); + guarantee(result == NULL || !result->is_zombie() || result->is_locked_by_vm() || VMError::is_error_reported(), "unsafe access to zombie method"); return result; } --- old/src/share/vm/oops/method.cpp 2017-06-28 09:42:14.187188303 -0400 +++ new/src/share/vm/oops/method.cpp 2017-06-28 09:42:13.845090975 -0400 @@ -59,6 +59,7 @@ #include "runtime/sharedRuntime.hpp" #include "runtime/signature.hpp" #include "utilities/quickSort.hpp" +#include "utilities/vmError.hpp" #include "utilities/xmlstream.hpp" // Implementation of Method @@ -242,7 +243,7 @@ #ifdef ASSERT { ResourceMark rm; - assert(is_native() && bcp == code_base() || contains(bcp) || is_error_reported(), + assert(is_native() && bcp == code_base() || contains(bcp) || VMError::is_error_reported(), "bcp doesn't belong to this method: bcp: " INTPTR_FORMAT ", method: %s", p2i(bcp), name_and_sig_as_C_string()); } --- old/src/share/vm/opto/cfgnode.cpp 2017-06-28 09:42:22.348758763 -0400 +++ new/src/share/vm/opto/cfgnode.cpp 2017-06-28 09:42:22.009364579 -0400 @@ -41,6 +41,7 @@ #include "opto/regmask.hpp" #include "opto/runtime.hpp" #include "opto/subnode.hpp" +#include "utilities/vmError.hpp" // Portions of code courtesy of Clifford Click @@ -873,8 +874,8 @@ // Verify a whole nest of phis rooted at this one. void PhiNode::verify_adr_type(bool recursive) const { - if (is_error_reported()) return; // muzzle asserts when debugging an error - if (Node::in_dump()) return; // muzzle asserts when printing + if (VMError::is_error_reported()) return; // muzzle asserts when debugging an error + if (Node::in_dump()) return; // muzzle asserts when printing assert((_type == Type::MEMORY) == (_adr_type != NULL), "adr_type for memory phis only"); --- old/src/share/vm/opto/machnode.cpp 2017-06-28 09:42:30.265848547 -0400 +++ new/src/share/vm/opto/machnode.cpp 2017-06-28 09:42:30.016583486 -0400 @@ -26,6 +26,7 @@ #include "gc/shared/collectedHeap.hpp" #include "opto/machnode.hpp" #include "opto/regalloc.hpp" +#include "utilities/vmError.hpp" //============================================================================= // Return the value requested @@ -587,7 +588,7 @@ if (ctrl == NULL) return NULL; // node is dead const TypePtr* adr_type = ctrl->adr_type(); #ifdef ASSERT - if (!is_error_reported() && !Node::in_dump()) + if (!VMError::is_error_reported() && !Node::in_dump()) assert(adr_type != NULL, "source must have adr_type"); #endif return adr_type; --- old/src/share/vm/opto/memnode.cpp 2017-06-28 09:42:38.430830783 -0400 +++ new/src/share/vm/opto/memnode.cpp 2017-06-28 09:42:38.182084456 -0400 @@ -43,6 +43,7 @@ #include "opto/phaseX.hpp" #include "opto/regmask.hpp" #include "utilities/copy.hpp" +#include "utilities/vmError.hpp" // Portions of code courtesy of Clifford Click @@ -713,7 +714,7 @@ #ifdef PRODUCT cross_check = NULL; #else - if (!VerifyAliases || is_error_reported() || Node::in_dump()) cross_check = NULL; + if (!VerifyAliases || VMError::is_error_reported() || Node::in_dump()) cross_check = NULL; #endif const TypePtr* tp = t->isa_ptr(); if (tp == NULL) { @@ -4385,9 +4386,9 @@ // verify a narrow slice (either incoming or outgoing) static void verify_memory_slice(const MergeMemNode* m, int alias_idx, Node* n) { - if (!VerifyAliases) return; // don't bother to verify unless requested - if (is_error_reported()) return; // muzzle asserts when debugging an error - if (Node::in_dump()) return; // muzzle asserts when printing + if (!VerifyAliases) return; // don't bother to verify unless requested + if (VMError::is_error_reported()) return; // muzzle asserts when debugging an error + if (Node::in_dump()) return; // muzzle asserts when printing assert(alias_idx >= Compile::AliasIdxRaw, "must not disturb base_memory or sentinel"); assert(n != NULL, ""); // Elide intervening MergeMem's @@ -4447,7 +4448,7 @@ } else { // make sure the stored slice is sane #ifdef ASSERT - if (is_error_reported() || Node::in_dump()) { + if (VMError::is_error_reported() || Node::in_dump()) { } else if (might_be_same(n, base_memory())) { // Give it a pass: It is a mostly harmless repetition of the base. // This can arise normally from node subsumption during optimization. --- old/src/share/vm/opto/multnode.cpp 2017-06-28 09:42:46.557502192 -0400 +++ new/src/share/vm/opto/multnode.cpp 2017-06-28 09:42:46.310137817 -0400 @@ -32,6 +32,7 @@ #include "opto/phaseX.hpp" #include "opto/regmask.hpp" #include "opto/type.hpp" +#include "utilities/vmError.hpp" //============================================================================= //------------------------------MultiNode-------------------------------------- @@ -106,7 +107,7 @@ if (ctrl == NULL) return NULL; // node is dead const TypePtr* adr_type = ctrl->adr_type(); #ifdef ASSERT - if (!is_error_reported() && !Node::in_dump()) + if (!VMError::is_error_reported() && !Node::in_dump()) assert(adr_type != NULL, "source must have adr_type"); #endif return adr_type; --- old/src/share/vm/prims/jni.cpp 2017-06-28 09:42:54.586200058 -0400 +++ new/src/share/vm/prims/jni.cpp 2017-06-28 09:42:54.243997214 -0400 @@ -84,6 +84,7 @@ #include "utilities/histogram.hpp" #include "utilities/internalVMTests.hpp" #include "utilities/macros.hpp" +#include "utilities/vmError.hpp" #if INCLUDE_ALL_GCS #include "gc/g1/g1SATBCardTableModRefBS.hpp" #endif // INCLUDE_ALL_GCS @@ -3983,7 +3984,7 @@ // Some platforms (like Win*) need a wrapper around these test // functions in order to properly handle error conditions. - test_error_handler(); + VMError::test_error_handler(); if (ExecuteInternalVMTests) { InternalVMTests::run(); } --- old/src/share/vm/runtime/frame.hpp 2017-06-28 09:43:02.839390024 -0400 +++ new/src/share/vm/runtime/frame.hpp 2017-06-28 09:43:02.500996880 -0400 @@ -418,6 +418,8 @@ int pd_oop_map_offset_adjustment() const; + DEBUG_ONLY(void pd_ps();) // platform dependent frame printing + #include CPU_HEADER(frame) }; --- old/src/share/vm/runtime/globals.hpp 2017-06-28 09:43:11.055881559 -0400 +++ new/src/share/vm/runtime/globals.hpp 2017-06-28 09:43:10.792011859 -0400 @@ -928,11 +928,11 @@ notproduct(uintx, ErrorHandlerTest, 0, \ "If > 0, provokes an error after VM initialization; the value " \ "determines which error to provoke. See test_error_handler() " \ - "in debug.cpp.") \ + "in vmError.cpp.") \ \ notproduct(uintx, TestCrashInErrorHandler, 0, \ "If > 0, provokes an error inside VM error handler (a secondary " \ - "crash). see test_error_handler() in debug.cpp.") \ + "crash). see test_error_handler() in vmError.cpp") \ \ notproduct(bool, TestSafeFetchInErrorHandler, false, \ "If true, tests SafeFetch inside error handler.") \ --- old/src/share/vm/runtime/java.cpp 2017-06-28 09:43:19.263772476 -0400 +++ new/src/share/vm/runtime/java.cpp 2017-06-28 09:43:19.015869358 -0400 @@ -446,7 +446,7 @@ #endif // Hang forever on exit if we're reporting an error. - if (ShowMessageBoxOnError && is_error_reported()) { + if (ShowMessageBoxOnError && VMError::is_error_reported()) { os::infinite_sleep(); } --- old/src/share/vm/runtime/os.hpp 2017-06-28 09:43:27.053439057 -0400 +++ new/src/share/vm/runtime/os.hpp 2017-06-28 09:43:26.806458346 -0400 @@ -38,6 +38,7 @@ #endif class AgentLibrary; +class frame; // os defines the interface to operating system; this includes traditional // OS services (time, I/O) as well as other functionality with system- --- old/src/share/vm/runtime/stubRoutines.cpp 2017-06-28 09:43:34.941200344 -0400 +++ new/src/share/vm/runtime/stubRoutines.cpp 2017-06-28 09:43:34.649312335 -0400 @@ -31,6 +31,7 @@ #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" #include "utilities/copy.hpp" +#include "utilities/vmError.hpp" #ifdef COMPILER2 #include "opto/runtime.hpp" #endif @@ -238,7 +239,7 @@ static void test_safefetch32() { if (CanUseSafeFetch32()) { int dummy = 17; - int* const p_invalid = (int*) get_segfault_address(); + int* const p_invalid = (int*) VMError::get_segfault_address(); int* const p_valid = &dummy; int result_invalid = SafeFetch32(p_invalid, 0xABC); assert(result_invalid == 0xABC, "SafeFetch32 error"); @@ -258,7 +259,7 @@ const intptr_t v2 = 0xDEFDDEFD; #endif intptr_t dummy = v1; - intptr_t* const p_invalid = (intptr_t*) get_segfault_address(); + intptr_t* const p_invalid = (intptr_t*) VMError::get_segfault_address(); intptr_t* const p_valid = &dummy; intptr_t result_invalid = SafeFetchN(p_invalid, v2); assert(result_invalid == v2, "SafeFetchN error"); --- old/src/share/vm/runtime/thread.cpp 2017-06-28 09:43:43.065184840 -0400 +++ new/src/share/vm/runtime/thread.cpp 2017-06-28 09:43:42.811631650 -0400 @@ -101,6 +101,7 @@ #include "utilities/events.hpp" #include "utilities/macros.hpp" #include "utilities/preserveException.hpp" +#include "utilities/vmError.hpp" #if INCLUDE_ALL_GCS #include "gc/cms/concurrentMarkSweepThread.hpp" #include "gc/g1/concurrentMarkThread.inline.hpp" @@ -1288,7 +1289,7 @@ // should be done, and sleep that amount of time. int time_waited = sleep(); - if (is_error_reported()) { + if (VMError::is_error_reported()) { // A fatal error has happened, the error handler(VMError::report_and_die) // should abort JVM after creating an error log file. However in some // rare cases, the error handler itself might deadlock. Here periodically @@ -4148,7 +4149,7 @@ } // Hang forever on exit if we are reporting an error. - if (ShowMessageBoxOnError && is_error_reported()) { + if (ShowMessageBoxOnError && VMError::is_error_reported()) { os::infinite_sleep(); } os::wait_for_keypress_at_exit(); --- old/src/share/vm/runtime/vmThread.cpp 2017-06-28 09:43:50.959853729 -0400 +++ new/src/share/vm/runtime/vmThread.cpp 2017-06-28 09:43:50.713053539 -0400 @@ -40,6 +40,7 @@ #include "trace/tracing.hpp" #include "utilities/dtrace.hpp" #include "utilities/events.hpp" +#include "utilities/vmError.hpp" #include "utilities/xmlstream.hpp" // Dummy VM operation to act as first element in our circular double-linked list @@ -433,7 +434,7 @@ GuaranteedSafepointInterval); // Support for self destruction - if ((SelfDestructTimer != 0) && !is_error_reported() && + if ((SelfDestructTimer != 0) && !VMError::is_error_reported() && (os::elapsedTime() > (double)SelfDestructTimer * 60.0)) { tty->print_cr("VM self-destructed"); exit(-1); --- old/src/share/vm/utilities/debug.cpp 2017-06-28 09:43:59.189122657 -0400 +++ new/src/share/vm/utilities/debug.cpp 2017-06-28 09:43:58.798114457 -0400 @@ -179,7 +179,7 @@ return true; } - if (!is_error_reported() && !SuppressFatalErrorMessage) { + if (!VMError::is_error_reported() && !SuppressFatalErrorMessage) { // print a friendly hint: fdStream out(defaultStream::output_fd()); out.print_raw_cr("# To suppress the following error report, specify this argument"); @@ -341,107 +341,6 @@ } } -static bool error_reported = false; - -// call this when the VM is dying--it might loosen some asserts -void set_error_reported() { - error_reported = true; -} - -bool is_error_reported() { - return error_reported; -} - -#ifndef PRODUCT -#include - -typedef void (*voidfun_t)(); -// Crash with an authentic sigfpe -static void crash_with_sigfpe() { - // generate a native synchronous SIGFPE where possible; - // if that did not cause a signal (e.g. on ppc), just - // raise the signal. - volatile int x = 0; - volatile int y = 1/x; -#ifndef _WIN32 - // OSX implements raise(sig) incorrectly so we need to - // explicitly target the current thread - pthread_kill(pthread_self(), SIGFPE); -#endif -} // end: crash_with_sigfpe - -// crash with sigsegv at non-null address. -static void crash_with_segfault() { - - char* const crash_addr = (char*) get_segfault_address(); - *crash_addr = 'X'; - -} // end: crash_with_segfault - -// returns an address which is guaranteed to generate a SIGSEGV on read, -// for test purposes, which is not NULL and contains bits in every word -void* get_segfault_address() { - return (void*) -#ifdef _LP64 - 0xABC0000000000ABCULL; -#else - 0x00000ABC; -#endif -} - -void test_error_handler() { - controlled_crash(ErrorHandlerTest); -} - -void controlled_crash(int how) { - if (how == 0) return; - - // If asserts are disabled, use the corresponding guarantee instead. - NOT_DEBUG(if (how <= 2) how += 2); - - const char* const str = "hello"; - const size_t num = (size_t)os::vm_page_size(); - - const char* const eol = os::line_separator(); - const char* const msg = "this message should be truncated during formatting"; - char * const dataPtr = NULL; // bad data pointer - const void (*funcPtr)(void) = (const void(*)()) 0xF; // bad function pointer - - // Keep this in sync with test/runtime/ErrorHandling/ErrorHandler.java - switch (how) { - case 1: vmassert(str == NULL, "expected null"); - case 2: vmassert(num == 1023 && *str == 'X', - "num=" SIZE_FORMAT " str=\"%s\"", num, str); - case 3: guarantee(str == NULL, "expected null"); - case 4: guarantee(num == 1023 && *str == 'X', - "num=" SIZE_FORMAT " str=\"%s\"", num, str); - case 5: fatal("expected null"); - case 6: fatal("num=" SIZE_FORMAT " str=\"%s\"", num, str); - case 7: fatal("%s%s# %s%s# %s%s# %s%s# %s%s# " - "%s%s# %s%s# %s%s# %s%s# %s%s# " - "%s%s# %s%s# %s%s# %s%s# %s", - msg, eol, msg, eol, msg, eol, msg, eol, msg, eol, - msg, eol, msg, eol, msg, eol, msg, eol, msg, eol, - msg, eol, msg, eol, msg, eol, msg, eol, msg); - case 8: vm_exit_out_of_memory(num, OOM_MALLOC_ERROR, "ChunkPool::allocate"); - case 9: ShouldNotCallThis(); - case 10: ShouldNotReachHere(); - case 11: Unimplemented(); - // There's no guarantee the bad data pointer will crash us - // so "break" out to the ShouldNotReachHere(). - case 12: *dataPtr = '\0'; break; - // There's no guarantee the bad function pointer will crash us - // so "break" out to the ShouldNotReachHere(). - case 13: (*funcPtr)(); break; - case 14: crash_with_segfault(); break; - case 15: crash_with_sigfpe(); break; - - default: tty->print_cr("ERROR: %d: unexpected test_num value.", how); - } - ShouldNotReachHere(); -} -#endif // !PRODUCT - // ------ helper functions for debugging go here ------------ // All debug entries should be wrapped with a stack allocated @@ -595,7 +494,7 @@ f = f.sender(®_map); tty->print("(guessing starting frame id=" PTR_FORMAT " based on current fp)\n", p2i(f.id())); p->trace_stack_from(vframe::new_vframe(&f, ®_map, p)); - pd_ps(f); + f.pd_ps(); #endif // PRODUCT } --- old/src/share/vm/utilities/debug.hpp 2017-06-28 09:44:07.133070527 -0400 +++ new/src/share/vm/utilities/debug.hpp 2017-06-28 09:44:06.885122133 -0400 @@ -200,32 +200,4 @@ // out of memory reporting void report_java_out_of_memory(const char* message); -// Support for self-destruct -bool is_error_reported(); -void set_error_reported(); - -/* Test vmassert(), fatal(), guarantee(), etc. */ -NOT_PRODUCT(void test_error_handler();) - -// crash in a controlled way: -// how can be one of: -// 1,2 - asserts -// 3,4 - guarantee -// 5-7 - fatal -// 8 - vm_exit_out_of_memory -// 9 - ShouldNotCallThis -// 10 - ShouldNotReachHere -// 11 - Unimplemented -// 12,13 - (not guaranteed) crashes -// 14 - SIGSEGV -// 15 - SIGFPE -NOT_PRODUCT(void controlled_crash(int how);) - -// returns an address which is guaranteed to generate a SIGSEGV on read, -// for test purposes, which is not NULL and contains bits in every word -NOT_PRODUCT(void* get_segfault_address();) - -class frame; -void pd_ps(frame f); - #endif // SHARE_VM_UTILITIES_DEBUG_HPP --- old/src/share/vm/utilities/ostream.cpp 2017-06-28 09:44:15.158811172 -0400 +++ new/src/share/vm/utilities/ostream.cpp 2017-06-28 09:44:14.911932083 -0400 @@ -32,6 +32,7 @@ #include "utilities/defaultStream.hpp" #include "utilities/macros.hpp" #include "utilities/ostream.hpp" +#include "utilities/vmError.hpp" #include "utilities/xmlstream.hpp" extern "C" void jio_print(const char* s); // Declarationtion of jvm method @@ -596,7 +597,7 @@ // if +LogVMOutput is used, because the flags haven't been parsed yet) // For safer printing during fatal error handling, do not init logfile // if a VM error has been reported. - if (!_inited && !is_error_reported()) init(); + if (!_inited && !VMError::is_error_reported()) init(); return _log_file != NULL; } @@ -788,7 +789,7 @@ !SerializeVMOutput || // VM already unhealthy - is_error_reported() || + VMError::is_error_reported() || // safepoint == global lock (for VM only) (SafepointSynchronize::is_synchronizing() && --- old/src/share/vm/utilities/vmError.cpp 2017-06-28 09:44:23.120703657 -0400 +++ new/src/share/vm/utilities/vmError.cpp 2017-06-28 09:44:22.871588498 -0400 @@ -49,6 +49,24 @@ #include "utilities/events.hpp" #include "utilities/vmError.hpp" +bool VMError::_error_reported = false; + +// call this when the VM is dying--it might loosen some asserts +bool VMError::is_error_reported() { return _error_reported; } + +// returns an address which is guaranteed to generate a SIGSEGV on read, +// for test purposes, which is not NULL and contains bits in every word +void* VMError::get_segfault_address() { + return (void*) +#ifdef _LP64 + 0xABC0000000000ABCULL; +#else + 0x00000ABC; +#endif +} + +NOT_PRODUCT(void controlled_crash(int how);) + // List of environment variables that should be reported in error log file. const char *env_list[] = { // All platforms @@ -1259,7 +1277,7 @@ jio_vsnprintf(_detail_msg, sizeof(_detail_msg), detail_fmt, detail_args); // first time - set_error_reported(); + _error_reported = true; reporting_started(); record_reporting_start_time(); @@ -1574,3 +1592,94 @@ } +#ifndef PRODUCT +#include + +typedef void (*voidfun_t)(); +// Crash with an authentic sigfpe +static void crash_with_sigfpe() { + // generate a native synchronous SIGFPE where possible; + // if that did not cause a signal (e.g. on ppc), just + // raise the signal. + volatile int x = 0; + volatile int y = 1/x; +#ifndef _WIN32 + // OSX implements raise(sig) incorrectly so we need to + // explicitly target the current thread + pthread_kill(pthread_self(), SIGFPE); +#endif +} // end: crash_with_sigfpe + +// crash with sigsegv at non-null address. +static void crash_with_segfault() { + + char* const crash_addr = (char*) VMError::get_segfault_address(); + *crash_addr = 'X'; + +} // end: crash_with_segfault + +void VMError::test_error_handler() { + controlled_crash(ErrorHandlerTest); +} + +// crash in a controlled way: +// how can be one of: +// 1,2 - asserts +// 3,4 - guarantee +// 5-7 - fatal +// 8 - vm_exit_out_of_memory +// 9 - ShouldNotCallThis +// 10 - ShouldNotReachHere +// 11 - Unimplemented +// 12,13 - (not guaranteed) crashes +// 14 - SIGSEGV +// 15 - SIGFPE +void controlled_crash(int how) { + if (how == 0) return; + + // If asserts are disabled, use the corresponding guarantee instead. + NOT_DEBUG(if (how <= 2) how += 2); + + const char* const str = "hello"; + const size_t num = (size_t)os::vm_page_size(); + + const char* const eol = os::line_separator(); + const char* const msg = "this message should be truncated during formatting"; + char * const dataPtr = NULL; // bad data pointer + const void (*funcPtr)(void) = (const void(*)()) 0xF; // bad function pointer + + // Keep this in sync with test/runtime/ErrorHandling/ErrorHandler.java + switch (how) { + case 1: vmassert(str == NULL, "expected null"); + case 2: vmassert(num == 1023 && *str == 'X', + "num=" SIZE_FORMAT " str=\"%s\"", num, str); + case 3: guarantee(str == NULL, "expected null"); + case 4: guarantee(num == 1023 && *str == 'X', + "num=" SIZE_FORMAT " str=\"%s\"", num, str); + case 5: fatal("expected null"); + case 6: fatal("num=" SIZE_FORMAT " str=\"%s\"", num, str); + case 7: fatal("%s%s# %s%s# %s%s# %s%s# %s%s# " + "%s%s# %s%s# %s%s# %s%s# %s%s# " + "%s%s# %s%s# %s%s# %s%s# %s", + msg, eol, msg, eol, msg, eol, msg, eol, msg, eol, + msg, eol, msg, eol, msg, eol, msg, eol, msg, eol, + msg, eol, msg, eol, msg, eol, msg, eol, msg); + case 8: vm_exit_out_of_memory(num, OOM_MALLOC_ERROR, "ChunkPool::allocate"); + case 9: ShouldNotCallThis(); + case 10: ShouldNotReachHere(); + case 11: Unimplemented(); + // There's no guarantee the bad data pointer will crash us + // so "break" out to the ShouldNotReachHere(). + case 12: *dataPtr = '\0'; break; + // There's no guarantee the bad function pointer will crash us + // so "break" out to the ShouldNotReachHere(). + case 13: (*funcPtr)(); break; + case 14: crash_with_segfault(); break; + case 15: crash_with_sigfpe(); break; + + default: tty->print_cr("ERROR: %d: unexpected test_num value.", how); + } + ShouldNotReachHere(); +} +#endif // !PRODUCT + --- old/src/share/vm/utilities/vmError.hpp 2017-06-28 09:44:31.034978013 -0400 +++ new/src/share/vm/utilities/vmError.hpp 2017-06-28 09:44:30.743501780 -0400 @@ -86,6 +86,10 @@ // Whether or not the last error reporting step did timeout. static volatile bool _step_did_timeout; + static bool _error_reported; + + public: + // set signal handlers on Solaris/Linux or the default exception filter // on Windows, to handle recursive crashes. static void reset_signal_handlers(); @@ -183,6 +187,14 @@ // Returns true if error reporting has not completed within the ErrorLogTimeout limit. static bool check_timeout(); -}; + // Support for avoiding multiple asserts + static bool is_error_reported(); + // Test vmassert(), fatal(), guarantee(), etc. + NOT_PRODUCT(static void test_error_handler();) + + // returns an address which is guaranteed to generate a SIGSEGV on read, + // for test purposes, which is not NULL and contains bits in every word + static void* get_segfault_address(); +}; #endif // SHARE_VM_UTILITIES_VMERROR_HPP --- old/src/share/vm/utilities/xmlstream.cpp 2017-06-28 09:44:39.052649060 -0400 +++ new/src/share/vm/utilities/xmlstream.cpp 2017-06-28 09:44:38.806852999 -0400 @@ -32,11 +32,12 @@ #include "oops/oop.inline.hpp" #include "runtime/deoptimization.hpp" #include "runtime/vmThread.hpp" +#include "utilities/vmError.hpp" #include "utilities/xmlstream.hpp" // Do not assert this condition if there's already another error reported. #define assert_if_no_error(cond, msg) \ - vmassert((cond) || is_error_reported(), msg) + vmassert((cond) || VMError::is_error_reported(), msg) void xmlStream::initialize(outputStream* out) { _out = out; @@ -198,7 +199,7 @@ _element_depth -= 1; } if (bad_tag && !VMThread::should_terminate() && !VM_Exit::vm_exited() && - !is_error_reported()) + !VMError::is_error_reported()) { assert(false, "bad tag in log"); } --- old/src/cpu/aarch64/vm/debug_aarch64.cpp 2017-06-28 09:44:47.242497179 -0400 +++ /dev/null 2017-06-11 15:38:07.778000227 -0400 @@ -1,34 +0,0 @@ -/* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, Red Hat Inc. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "code/codeCache.hpp" -#include "code/nmethod.hpp" -#include "runtime/frame.hpp" -#include "runtime/init.hpp" -#include "runtime/os.hpp" -#include "utilities/debug.hpp" - -void pd_ps(frame f) {} --- old/src/cpu/arm/vm/debug_arm.cpp 2017-06-28 09:44:51.292826388 -0400 +++ /dev/null 2017-06-11 15:38:07.778000227 -0400 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "code/codeCache.hpp" -#include "code/nmethod.hpp" -#include "runtime/frame.hpp" -#include "runtime/init.hpp" -#include "runtime/os.hpp" -#include "utilities/debug.hpp" - -void pd_ps(frame f) {} --- old/src/cpu/ppc/vm/debug_ppc.cpp 2017-06-28 09:44:55.014440654 -0400 +++ /dev/null 2017-06-11 15:38:07.778000227 -0400 @@ -1,34 +0,0 @@ -/* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2013 SAP SE. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "code/codeCache.hpp" -#include "code/nmethod.hpp" -#include "runtime/frame.hpp" -#include "runtime/init.hpp" -#include "runtime/os.hpp" -#include "utilities/debug.hpp" - -void pd_ps(frame f) {} --- old/src/cpu/s390/vm/debug_s390.cpp 2017-06-28 09:44:58.911487058 -0400 +++ /dev/null 2017-06-11 15:38:07.778000227 -0400 @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016 SAP SE. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "code/codeCache.hpp" -#include "code/nmethod.hpp" -#include "oops/oop.inline.hpp" -#include "runtime/frame.hpp" -#include "runtime/init.hpp" -#include "runtime/os.hpp" -#include "utilities/debug.hpp" - -void pd_ps(frame f) {} --- old/src/cpu/sparc/vm/debug_sparc.cpp 2017-06-28 09:45:02.635715451 -0400 +++ /dev/null 2017-06-11 15:38:07.778000227 -0400 @@ -1,83 +0,0 @@ -/* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "code/codeCache.hpp" -#include "code/nmethod.hpp" -#include "runtime/frame.hpp" -#include "runtime/init.hpp" -#include "runtime/os.hpp" -#include "utilities/debug.hpp" - -#ifndef PRODUCT - -extern "C" void findpc(int x); - - -void pd_ps(frame f) { - intptr_t* sp = f.sp(); - intptr_t* prev_sp = sp - 1; - intptr_t *pc = NULL; - intptr_t *next_pc = NULL; - int count = 0; - tty->print_cr("register window backtrace from " INTPTR_FORMAT ":", p2i(sp)); - while (sp != NULL && ((intptr_t)sp & 7) == 0 && sp > prev_sp && sp < prev_sp+1000) { - pc = next_pc; - next_pc = (intptr_t*) sp[I7->sp_offset_in_saved_window()]; - tty->print("[%d] sp=" INTPTR_FORMAT " pc=", count, p2i(sp)); - findpc((intptr_t)pc); - if (WizardMode && Verbose) { - // print register window contents also - tty->print_cr(" L0..L7: {" - INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " - INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " ", - sp[0+0], sp[0+1], sp[0+2], sp[0+3], - sp[0+4], sp[0+5], sp[0+6], sp[0+7]); - tty->print_cr(" I0..I7: {" - INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " - INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " ", - sp[8+0], sp[8+1], sp[8+2], sp[8+3], - sp[8+4], sp[8+5], sp[8+6], sp[8+7]); - // (and print stack frame contents too??) - - CodeBlob *b = CodeCache::find_blob((address) pc); - if (b != NULL) { - if (b->is_nmethod()) { - Method* m = ((nmethod*)b)->method(); - int nlocals = m->max_locals(); - int nparams = m->size_of_parameters(); - tty->print_cr("compiled java method (locals = %d, params = %d)", nlocals, nparams); - } - } - } - prev_sp = sp; - sp = (intptr_t *)sp[FP->sp_offset_in_saved_window()]; - sp = (intptr_t *)((intptr_t)sp + STACK_BIAS); - count += 1; - } - if (sp != NULL) - tty->print("[%d] sp=" INTPTR_FORMAT " [bogus sp!]", count, p2i(sp)); -} - -#endif // PRODUCT --- old/src/cpu/x86/vm/debug_x86.cpp 2017-06-28 09:45:06.411226541 -0400 +++ /dev/null 2017-06-11 15:38:07.778000227 -0400 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "code/codeCache.hpp" -#include "code/nmethod.hpp" -#include "runtime/frame.hpp" -#include "runtime/init.hpp" -#include "runtime/os.hpp" -#include "utilities/debug.hpp" - -void pd_ps(frame f) {} --- old/src/cpu/zero/vm/debug_zero.cpp 2017-06-28 09:45:10.231743377 -0400 +++ /dev/null 2017-06-11 15:38:07.778000227 -0400 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2007 Red Hat, Inc. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "code/codeCache.hpp" -#include "code/nmethod.hpp" -#include "runtime/frame.hpp" -#include "runtime/init.hpp" -#include "runtime/os.hpp" -#include "utilities/debug.hpp" - -void pd_ps(frame f) { - ShouldNotCallThis(); -}