# HG changeset patch # User jcoomes # Date 1271967795 25200 # Node ID 6b0dd9c75dde9cfa6a63c70a719e8fa083b1b6cd # Parent c51fd0c1d00546b531f94dff7da6999237686089 6888954: argument formatting for assert() and friends Reviewed-by: kvn, twisti, apetrusenko, never, dcubed diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/cpu/sparc/vm/assembler_sparc.hpp --- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Thu Apr 22 13:23:15 2010 -0700 @@ -1065,7 +1065,7 @@ } void assert_not_delayed(const char* msg) { #ifdef CHECK_DELAY - assert_msg ( delay_state == no_delay, msg); + assert(delay_state == no_delay, msg); #endif } diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/os/linux/vm/os_linux.cpp --- a/hotspot/src/os/linux/vm/os_linux.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/os/linux/vm/os_linux.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -3495,7 +3495,8 @@ // libjsig also interposes the sigaction() call below and saves the // old sigaction on it own. } else { - fatal2("Encountered unexpected pre-existing sigaction handler %#lx for signal %d.", (long)oldhand, sig); + fatal(err_msg("Encountered unexpected pre-existing sigaction handler " + "%#lx for signal %d.", (long)oldhand, sig)); } } @@ -3817,7 +3818,8 @@ Linux::set_page_size(sysconf(_SC_PAGESIZE)); if (Linux::page_size() == -1) { - fatal1("os_linux.cpp: os::init: sysconf failed (%s)", strerror(errno)); + fatal(err_msg("os_linux.cpp: os::init: sysconf failed (%s)", + strerror(errno))); } init_page_sizes((size_t) Linux::page_size()); diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/os/solaris/vm/os_solaris.cpp --- a/hotspot/src/os/solaris/vm/os_solaris.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -1567,7 +1567,8 @@ // treat %g2 as a caller-save register, preserving it in a %lN. thread_key_t tk; if (thr_keycreate( &tk, NULL ) ) - fatal1("os::allocate_thread_local_storage: thr_keycreate failed (%s)", strerror(errno)); + fatal(err_msg("os::allocate_thread_local_storage: thr_keycreate failed " + "(%s)", strerror(errno))); return int(tk); } @@ -1585,7 +1586,8 @@ if (errno == ENOMEM) { vm_exit_out_of_memory(SMALLINT, "thr_setspecific: out of swap space"); } else { - fatal1("os::thread_local_storage_at_put: thr_setspecific failed (%s)", strerror(errno)); + fatal(err_msg("os::thread_local_storage_at_put: thr_setspecific failed " + "(%s)", strerror(errno))); } } else { ThreadLocalStorage::set_thread_in_slot ((Thread *) value) ; @@ -1738,7 +1740,7 @@ jlong os::javaTimeMillis() { timeval t; if (gettimeofday( &t, NULL) == -1) - fatal1("os::javaTimeMillis: gettimeofday (%s)", strerror(errno)); + fatal(err_msg("os::javaTimeMillis: gettimeofday (%s)", strerror(errno))); return jlong(t.tv_sec) * 1000 + jlong(t.tv_usec) / 1000; } @@ -4233,7 +4235,8 @@ // libjsig also interposes the sigaction() call below and saves the // old sigaction on it own. } else { - fatal2("Encountered unexpected pre-existing sigaction handler %#lx for signal %d.", (long)oldhand, sig); + fatal(err_msg("Encountered unexpected pre-existing sigaction handler " + "%#lx for signal %d.", (long)oldhand, sig)); } } @@ -4764,7 +4767,8 @@ page_size = sysconf(_SC_PAGESIZE); if (page_size == -1) - fatal1("os_solaris.cpp: os::init: sysconf failed (%s)", strerror(errno)); + fatal(err_msg("os_solaris.cpp: os::init: sysconf failed (%s)", + strerror(errno))); init_page_sizes((size_t) page_size); Solaris::initialize_system_info(); @@ -4775,7 +4779,7 @@ int fd = open("/dev/zero", O_RDWR); if (fd < 0) { - fatal1("os::init: cannot open /dev/zero (%s)", strerror(errno)); + fatal(err_msg("os::init: cannot open /dev/zero (%s)", strerror(errno))); } else { Solaris::set_dev_zero_fd(fd); diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/os/solaris/vm/threadCritical_solaris.cpp --- a/hotspot/src/os/solaris/vm/threadCritical_solaris.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/os/solaris/vm/threadCritical_solaris.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -47,7 +47,8 @@ thread_t owner = thr_self(); if (global_mut_owner != owner) { if (os::Solaris::mutex_lock(&global_mut)) - fatal1("ThreadCritical::ThreadCritical: mutex_lock failed (%s)", strerror(errno)); + fatal(err_msg("ThreadCritical::ThreadCritical: mutex_lock failed (%s)", + strerror(errno))); assert(global_mut_count == 0, "must have clean count"); assert(global_mut_owner == -1, "must have clean owner"); } @@ -66,7 +67,8 @@ if (global_mut_count == 0) { global_mut_owner = -1; if (os::Solaris::mutex_unlock(&global_mut)) - fatal1("ThreadCritical::~ThreadCritical: mutex_unlock failed (%s)", strerror(errno)); + fatal(err_msg("ThreadCritical::~ThreadCritical: mutex_unlock failed " + "(%s)", strerror(errno))); } } else { assert (Threads::number_of_threads() == 0, "valid only during initialization"); diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/os/windows/vm/os_windows.cpp --- a/hotspot/src/os/windows/vm/os_windows.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/os/windows/vm/os_windows.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -724,7 +724,7 @@ java_origin.wMilliseconds = 0; FILETIME jot; if (!SystemTimeToFileTime(&java_origin, &jot)) { - fatal1("Error = %d\nWindows error", GetLastError()); + fatal(err_msg("Error = %d\nWindows error", GetLastError())); } _calculated_offset = jlong_from(jot.dwHighDateTime, jot.dwLowDateTime); _has_calculated_offset = 1; @@ -4095,7 +4095,7 @@ } int err = GetLastError(); if (err != ERROR_NO_MORE_ITEMS && err != ERROR_CALL_NOT_IMPLEMENTED) { - fatal1("heap walk aborted with error %d", err); + fatal(err_msg("heap walk aborted with error %d", err)); } HeapUnlock(heap); } diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp --- a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -153,7 +153,7 @@ if (rslt == ENOMEM) { vm_exit_out_of_memory(0, "pthread_getattr_np"); } else { - fatal1("pthread_getattr_np failed with errno = %d", rslt); + fatal(err_msg("pthread_getattr_np failed with errno = %d", rslt)); } } diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp --- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -680,7 +680,7 @@ if (rslt == ENOMEM) { vm_exit_out_of_memory(0, "pthread_getattr_np"); } else { - fatal1("pthread_getattr_np failed with errno = %d", rslt); + fatal(err_msg("pthread_getattr_np failed with errno = %d", rslt)); } } diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/asm/assembler.cpp --- a/hotspot/src/share/vm/asm/assembler.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/asm/assembler.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -43,7 +43,8 @@ _code_pos = cs->end(); _oop_recorder= code->oop_recorder(); if (_code_begin == NULL) { - vm_exit_out_of_memory1(0, "CodeCache: no room for %s", code->name()); + vm_exit_out_of_memory(0, err_msg("CodeCache: no room for %s", + code->name())); } } diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/classfile/classFileParser.cpp --- a/hotspot/src/share/vm/classfile/classFileParser.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -334,7 +334,8 @@ } break; default: - fatal1("bad constant pool tag value %u", cp->tag_at(index).value()); + fatal(err_msg("bad constant pool tag value %u", + cp->tag_at(index).value())); ShouldNotReachHere(); break; } // end of switch diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/code/exceptionHandlerTable.cpp --- a/hotspot/src/share/vm/code/exceptionHandlerTable.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/code/exceptionHandlerTable.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -221,6 +221,6 @@ for (uint i = 0; i < len(); i++) { if ((*adr(i) > (unsigned int)nm->code_size()) || (*(adr(i)+1) > (unsigned int)nm->code_size())) - fatal1("Invalid offset in ImplicitExceptionTable at %lx", _data); + fatal(err_msg("Invalid offset in ImplicitExceptionTable at " PTR_FORMAT, _data)); } } diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/code/nmethod.cpp --- a/hotspot/src/share/vm/code/nmethod.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/code/nmethod.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -2124,7 +2124,7 @@ ResourceMark rm; if (!CodeCache::contains(this)) { - fatal1("nmethod at " INTPTR_FORMAT " not in zone", this); + fatal(err_msg("nmethod at " INTPTR_FORMAT " not in zone", this)); } if(is_native_method() ) @@ -2132,7 +2132,8 @@ nmethod* nm = CodeCache::find_nmethod(verified_entry_point()); if (nm != this) { - fatal1("findNMethod did not find this nmethod (" INTPTR_FORMAT ")", this); + fatal(err_msg("findNMethod did not find this nmethod (" INTPTR_FORMAT ")", + this)); } for (PcDesc* p = scopes_pcs_begin(); p < scopes_pcs_end(); p++) { diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/code/stubs.cpp --- a/hotspot/src/share/vm/code/stubs.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/code/stubs.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -62,7 +62,9 @@ Mutex* lock, const char* name) : _mutex(lock) { intptr_t size = round_to(buffer_size, 2*BytesPerWord); BufferBlob* blob = BufferBlob::create(name, size); - if( blob == NULL ) vm_exit_out_of_memory1(size, "CodeCache: no room for %s", name); + if( blob == NULL) { + vm_exit_out_of_memory(size, err_msg("CodeCache: no room for %s", name)); + } _stub_interface = stub_interface; _buffer_size = blob->instructions_size(); _buffer_limit = blob->instructions_size(); diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/code/vtableStubs.cpp --- a/hotspot/src/share/vm/code/vtableStubs.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/code/vtableStubs.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -45,7 +45,9 @@ if (_chunk == NULL || _chunk + real_size > _chunk_end) { const int bytes = chunk_factor * real_size + pd_code_alignment(); BufferBlob* blob = BufferBlob::create("vtable chunks", bytes); - if( blob == NULL ) vm_exit_out_of_memory1(bytes, "CodeCache: no room for %s", "vtable chunks"); + if (blob == NULL) { + vm_exit_out_of_memory(bytes, "CodeCache: no room for vtable chunks"); + } _chunk = blob->instructions_begin(); _chunk_end = _chunk + bytes; VTune::register_stub("vtable stub", _chunk, _chunk_end); @@ -189,7 +191,9 @@ instanceKlass* ik = instanceKlass::cast(klass); klassVtable* vt = ik->vtable(); klass->print(); - fatal3("bad compiled vtable dispatch: receiver " INTPTR_FORMAT ", index %d (vtable length %d)", (address)receiver, index, vt->length()); + fatal(err_msg("bad compiled vtable dispatch: receiver " INTPTR_FORMAT ", " + "index %d (vtable length %d)", + (address)receiver, index, vt->length())); } #endif // Product diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp --- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -2339,8 +2339,8 @@ goto opcode_switch; } #endif - fatal2("\t*** Unimplemented opcode: %d = %s\n", - opcode, Bytecodes::name((Bytecodes::Code)opcode)); + fatal(err_msg("Unimplemented opcode %d = %s", opcode, + Bytecodes::name((Bytecodes::Code)opcode))); goto finish; } /* switch(opc) */ diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/interpreter/bytecodes.cpp --- a/hotspot/src/share/vm/interpreter/bytecodes.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/interpreter/bytecodes.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -426,7 +426,9 @@ if (is_defined(i)) { Code code = cast(i); Code java = java_code(code); - if (can_trap(code) && !can_trap(java)) fatal2("%s can trap => %s can trap, too", name(code), name(java)); + if (can_trap(code) && !can_trap(java)) + fatal(err_msg("%s can trap => %s can trap, too", name(code), + name(java))); } } } diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/oops/instanceKlass.cpp --- a/hotspot/src/share/vm/oops/instanceKlass.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -966,7 +966,7 @@ // not found #ifdef ASSERT int index = linear_search(methods, name, signature); - if (index != -1) fatal1("binary search bug: should have found entry %d", index); + assert(index == -1, err_msg("binary search should have found entry %d", index)); #endif return NULL; } else if (res < 0) { @@ -977,7 +977,7 @@ } #ifdef ASSERT int index = linear_search(methods, name, signature); - if (index != -1) fatal1("binary search bug: should have found entry %d", index); + assert(index == -1, err_msg("binary search should have found entry %d", index)); #endif return NULL; } diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/oops/instanceKlassKlass.cpp --- a/hotspot/src/share/vm/oops/instanceKlassKlass.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/oops/instanceKlassKlass.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -712,10 +712,10 @@ int sib_count = 0; while (sib != NULL) { if (sib == ik) { - fatal1("subclass cycle of length %d", sib_count); + fatal(err_msg("subclass cycle of length %d", sib_count)); } if (sib_count >= 100000) { - fatal1("suspiciously long subclass list %d", sib_count); + fatal(err_msg("suspiciously long subclass list %d", sib_count)); } guarantee(sib->as_klassOop()->is_klass(), "should be klass"); guarantee(sib->as_klassOop()->is_perm(), "should be in permspace"); diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/oops/klassVtable.cpp --- a/hotspot/src/share/vm/oops/klassVtable.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/oops/klassVtable.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -1180,8 +1180,8 @@ oop* end_of_obj = (oop*)_klass() + _klass()->size(); oop* end_of_vtable = (oop *)&table()[_length]; if (end_of_vtable > end_of_obj) { - fatal1("klass %s: klass object too short (vtable extends beyond end)", - _klass->internal_name()); + fatal(err_msg("klass %s: klass object too short (vtable extends beyond " + "end)", _klass->internal_name())); } for (int i = 0; i < _length; i++) table()[i].verify(this, st); @@ -1224,7 +1224,7 @@ #ifndef PRODUCT print(); #endif - fatal1("vtableEntry %#lx: method is from subclass", this); + fatal(err_msg("vtableEntry " PTR_FORMAT ": method is from subclass", this)); } } diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/opto/idealGraphPrinter.cpp --- a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -151,7 +151,8 @@ } else { // It would be nice if we could shut down cleanly but it should // be an error if we can't connect to the visualizer. - fatal2("Couldn't connect to visualizer at %s:%d", PrintIdealGraphAddress, PrintIdealGraphPort); + fatal(err_msg("Couldn't connect to visualizer at %s:%d", + PrintIdealGraphAddress, PrintIdealGraphPort)); } } diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/opto/output.cpp --- a/hotspot/src/share/vm/opto/output.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/opto/output.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -2407,7 +2407,7 @@ n->dump(); tty->print_cr("..."); prior_use->dump(); - assert_msg(edge_from_to(prior_use,n),msg); + assert(edge_from_to(prior_use,n),msg); } _reg_node.map(def,NULL); // Kill live USEs } @@ -2446,11 +2446,11 @@ OptoReg::Name reg_lo = _regalloc->get_reg_first(def); OptoReg::Name reg_hi = _regalloc->get_reg_second(def); if( OptoReg::is_valid(reg_lo) ) { - assert_msg(!_reg_node[reg_lo] || edge_from_to(_reg_node[reg_lo],def), msg ); + assert(!_reg_node[reg_lo] || edge_from_to(_reg_node[reg_lo],def), msg); _reg_node.map(reg_lo,n); } if( OptoReg::is_valid(reg_hi) ) { - assert_msg(!_reg_node[reg_hi] || edge_from_to(_reg_node[reg_hi],def), msg ); + assert(!_reg_node[reg_hi] || edge_from_to(_reg_node[reg_hi],def), msg); _reg_node.map(reg_hi,n); } } diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/prims/jni.cpp --- a/hotspot/src/share/vm/prims/jni.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/prims/jni.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -3311,6 +3311,7 @@ OrderAccess::release_store(&vm_created, 0); } + NOT_PRODUCT(test_error_handler(ErrorHandlerTest)); return result; } diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/runtime/globals.hpp --- a/hotspot/src/share/vm/runtime/globals.hpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/runtime/globals.hpp Thu Apr 22 13:23:15 2010 -0700 @@ -652,6 +652,11 @@ product(bool, PrintGCApplicationStoppedTime, false, \ "Print the time the application has been stopped") \ \ + 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.") \ + \ develop(bool, Verbose, false, \ "Prints additional debugging information from other modes") \ \ diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/runtime/memprofiler.cpp --- a/hotspot/src/share/vm/runtime/memprofiler.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/runtime/memprofiler.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -62,7 +62,7 @@ // Create log file _log_fp = fopen(log_name , "w+"); if (_log_fp == NULL) { - fatal1("MemProfiler: Cannot create log file: %s", log_name); + fatal(err_msg("MemProfiler: Cannot create log file: %s", log_name)); } fprintf(_log_fp, "MemProfiler: sizes are in Kb, time is in seconds since startup\n\n"); fprintf(_log_fp, " time, #thr, #cls, heap, heap, perm, perm, code, hndls, rescs, oopmp\n"); diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/runtime/mutex.cpp --- a/hotspot/src/share/vm/runtime/mutex.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/runtime/mutex.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -1288,8 +1288,9 @@ !(this == Safepoint_lock && contains(locks, Terminator_lock) && SafepointSynchronize::is_synchronizing())) { new_owner->print_owned_locks(); - fatal4("acquiring lock %s/%d out of order with lock %s/%d -- possible deadlock", - this->name(), this->rank(), locks->name(), locks->rank()); + fatal(err_msg("acquiring lock %s/%d out of order with lock %s/%d -- " + "possible deadlock", this->name(), this->rank(), + locks->name(), locks->rank())); } this->_next = new_owner->_owned_locks; @@ -1342,7 +1343,8 @@ || rank() == Mutex::special, "wrong thread state for using locks"); if (StrictSafepointChecks) { if (thread->is_VM_thread() && !allow_vm_block()) { - fatal1("VM thread using lock %s (not allowed to block on)", name()); + fatal(err_msg("VM thread using lock %s (not allowed to block on)", + name())); } debug_only(if (rank() != Mutex::special) \ thread->check_for_valid_safepoint_state(false);) diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/runtime/mutexLocker.cpp --- a/hotspot/src/share/vm/runtime/mutexLocker.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -136,7 +136,7 @@ // see if invoker of VM operation owns it VM_Operation* op = VMThread::vm_operation(); if (op != NULL && op->calling_thread() == lock->owner()) return; - fatal1("must own lock %s", lock->name()); + fatal(err_msg("must own lock %s", lock->name())); } // a stronger assertion than the above @@ -144,7 +144,7 @@ if (IgnoreLockingAssertions) return; assert(lock != NULL, "Need non-NULL lock"); if (lock->owned_by_self()) return; - fatal1("must own lock %s", lock->name()); + fatal(err_msg("must own lock %s", lock->name())); } #endif diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/runtime/os.cpp --- a/hotspot/src/share/vm/runtime/os.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/runtime/os.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -406,8 +406,10 @@ #ifdef ASSERT inline size_t get_size(void* obj) { size_t size = *size_addr_from_obj(obj); - if (size < 0 ) - fatal2("free: size field of object #%p was overwritten (%lu)", obj, size); + if (size < 0) { + fatal(err_msg("free: size field of object #" PTR_FORMAT " was overwritten (" + SIZE_FORMAT ")", obj, size)); + } return size; } diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/runtime/safepoint.cpp --- a/hotspot/src/share/vm/runtime/safepoint.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/runtime/safepoint.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -594,7 +594,7 @@ break; default: - fatal1("Illegal threadstate encountered: %d", state); + fatal(err_msg("Illegal threadstate encountered: %d", state)); } // Check for pending. async. exceptions or suspends - except if the diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/runtime/signature.cpp --- a/hotspot/src/share/vm/runtime/signature.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/runtime/signature.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -57,7 +57,7 @@ } void SignatureIterator::expect(char c) { - if (_signature->byte_at(_index) != c) fatal1("expecting %c", c); + if (_signature->byte_at(_index) != c) fatal(err_msg("expecting %c", c)); _index++; } diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/runtime/stubRoutines.cpp --- a/hotspot/src/share/vm/runtime/stubRoutines.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/runtime/stubRoutines.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -118,7 +118,10 @@ ResourceMark rm; TraceTime timer("StubRoutines generation 1", TraceStartupTime); _code1 = BufferBlob::create("StubRoutines (1)", code_size1); - if( _code1 == NULL) vm_exit_out_of_memory1(code_size1, "CodeCache: no room for %s", "StubRoutines (1)"); + if (_code1 == NULL) { + vm_exit_out_of_memory(code_size1, + "CodeCache: no room for StubRoutines (1)"); + } CodeBuffer buffer(_code1->instructions_begin(), _code1->instructions_size()); StubGenerator_generate(&buffer, false); } @@ -164,7 +167,10 @@ ResourceMark rm; TraceTime timer("StubRoutines generation 2", TraceStartupTime); _code2 = BufferBlob::create("StubRoutines (2)", code_size2); - if( _code2 == NULL) vm_exit_out_of_memory1(code_size2, "CodeCache: no room for %s", "StubRoutines (2)"); + if (_code2 == NULL) { + vm_exit_out_of_memory(code_size2, + "CodeCache: no room for StubRoutines (2)"); + } CodeBuffer buffer(_code2->instructions_begin(), _code2->instructions_size()); StubGenerator_generate(&buffer, true); } diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/runtime/vmThread.cpp --- a/hotspot/src/share/vm/runtime/vmThread.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/runtime/vmThread.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -593,7 +593,8 @@ // Check the VM operation allows nested VM operation. This normally not the case, e.g., the compiler // does not allow nested scavenges or compiles. if (!prev_vm_operation->allow_nested_vm_operations()) { - fatal2("Nested VM operation %s requested by operation %s", op->name(), vm_operation()->name()); + fatal(err_msg("Nested VM operation %s requested by operation %s", + op->name(), vm_operation()->name())); } op->set_calling_thread(prev_vm_operation->calling_thread(), prev_vm_operation->priority()); } diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/utilities/debug.cpp --- a/hotspot/src/share/vm/utilities/debug.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/utilities/debug.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -72,7 +72,7 @@ // assert/guarantee/... may happen very early during VM initialization. // Don't rely on anything that is initialized by Threads::create_vm(). For // example, don't use tty. -bool assert_is_suppressed(const char* file_name, int line_no) { +bool error_is_suppressed(const char* file_name, int line_no) { // The following 1-element cache requires that passed-in // file names are always only constant literals. if (file_name == last_file_name && line_no == last_line_no) return true; @@ -163,38 +163,30 @@ #else // Place-holder for non-existent suppression check: -#define assert_is_suppressed(file_name, line_no) (false) +#define error_is_suppressed(file_name, line_no) (false) #endif //PRODUCT -void report_assertion_failure(const char* file_name, int line_no, const char* message) { - if (Debugging || assert_is_suppressed(file_name, line_no)) return; - VMError err(ThreadLocalStorage::get_thread_slow(), message, file_name, line_no); +void report_vm_error(const char* file, int line, const char* error_msg, + const char* detail_msg) +{ + if (Debugging || error_is_suppressed(file, line)) return; + Thread* const thread = ThreadLocalStorage::get_thread_slow(); + VMError err(thread, file, line, error_msg, detail_msg); err.report_and_die(); } -void report_fatal(const char* file_name, int line_no, const char* message) { - if (Debugging || assert_is_suppressed(file_name, line_no)) return; - VMError err(ThreadLocalStorage::get_thread_slow(), message, file_name, line_no); - err.report_and_die(); +void report_fatal(const char* file, int line, const char* message) +{ + report_vm_error(file, line, "fatal error", message); } -void report_fatal_vararg(const char* file_name, int line_no, const char* format, ...) { - char buffer[256]; - va_list ap; - va_start(ap, format); - jio_vsnprintf(buffer, sizeof(buffer), format, ap); - va_end(ap); - report_fatal(file_name, line_no, buffer); -} - - // Used by report_vm_out_of_memory to detect recursion. static jint _exiting_out_of_mem = 0; -// Just passing the flow to VMError to handle error -void report_vm_out_of_memory(const char* file_name, int line_no, size_t size, const char* message) { - if (Debugging || assert_is_suppressed(file_name, line_no)) return; +void report_vm_out_of_memory(const char* file, int line, size_t size, + const char* message) { + if (Debugging || error_is_suppressed(file, line)) return; // We try to gather additional information for the first out of memory // error only; gathering additional data might cause an allocation and a @@ -206,46 +198,28 @@ if (first_time_here) { Thread* thread = ThreadLocalStorage::get_thread_slow(); - VMError(thread, size, message, file_name, line_no).report_and_die(); + VMError(thread, file, line, size, message).report_and_die(); } // Dump core and abort vm_abort(true); } -void report_vm_out_of_memory_vararg(const char* file_name, int line_no, size_t size, const char* format, ...) { - char buffer[256]; - va_list ap; - va_start(ap, format); - jio_vsnprintf(buffer, sizeof(buffer), format, ap); - va_end(ap); - report_vm_out_of_memory(file_name, line_no, size, buffer); +void report_should_not_call(const char* file, int line) { + report_vm_error(file, line, "ShouldNotCall()"); } -void report_should_not_call(const char* file_name, int line_no) { - if (Debugging || assert_is_suppressed(file_name, line_no)) return; - VMError err(ThreadLocalStorage::get_thread_slow(), "ShouldNotCall()", file_name, line_no); - err.report_and_die(); +void report_should_not_reach_here(const char* file, int line) { + report_vm_error(file, line, "ShouldNotReachHere()"); } - -void report_should_not_reach_here(const char* file_name, int line_no) { - if (Debugging || assert_is_suppressed(file_name, line_no)) return; - VMError err(ThreadLocalStorage::get_thread_slow(), "ShouldNotReachHere()", file_name, line_no); - err.report_and_die(); +void report_unimplemented(const char* file, int line) { + report_vm_error(file, line, "Unimplemented()"); } - -void report_unimplemented(const char* file_name, int line_no) { - if (Debugging || assert_is_suppressed(file_name, line_no)) return; - VMError err(ThreadLocalStorage::get_thread_slow(), "Unimplemented()", file_name, line_no); - err.report_and_die(); -} - - -void report_untested(const char* file_name, int line_no, const char* msg) { +void report_untested(const char* file, int line, const char* message) { #ifndef PRODUCT - warning("Untested: %s in %s: %d\n", msg, file_name, line_no); + warning("Untested: %s in %s: %d\n", message, file, line); #endif // PRODUCT } @@ -284,6 +258,51 @@ return error_reported; } +#ifndef PRODUCT +#include + +void test_error_handler(size_t test_num) +{ + if (test_num == 0) return; + + // If asserts are disabled, use the corresponding guarantee instead. + size_t n = test_num; + NOT_DEBUG(if (n <= 2) n += 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"; + + // Keep this in sync with test/runtime/6888954/vmerrors.sh. + switch (n) { + case 1: assert(str == NULL, "expected null"); + case 2: assert(num == 1023 && *str == 'X', + err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str)); + case 3: guarantee(str == NULL, "expected null"); + case 4: guarantee(num == 1023 && *str == 'X', + err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str)); + case 5: fatal("expected null"); + case 6: fatal(err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str)); + case 7: fatal(err_msg("%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, "ChunkPool::allocate"); + case 9: ShouldNotCallThis(); + case 10: ShouldNotReachHere(); + case 11: Unimplemented(); + // This is last because it does not generate an hs_err* file on Windows. + case 12: os::signal_raise(SIGSEGV); + + default: ShouldNotReachHere(); + } +} +#endif // #ifndef PRODUCT + // ------ helper functions for debugging go here ------------ #ifndef PRODUCT diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/utilities/debug.hpp --- a/hotspot/src/share/vm/utilities/debug.hpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/utilities/debug.hpp Thu Apr 22 13:23:15 2010 -0700 @@ -22,28 +22,54 @@ * */ +#include + +// Simple class to format the ctor arguments into a fixed-sized buffer. +template +class FormatBuffer { +public: + inline FormatBuffer(const char * format, ...); + operator const char *() const { return _buf; } + +private: + FormatBuffer(const FormatBuffer &); // prevent copies + +private: + char _buf[bufsz]; +}; + +template +FormatBuffer::FormatBuffer(const char * format, ...) { + va_list argp; + va_start(argp, format); + vsnprintf(_buf, bufsz, format, argp); + va_end(argp); +} + +// Used to format messages for assert(), guarantee(), fatal(), etc. +typedef FormatBuffer<> err_msg; + // assertions #ifdef ASSERT -// Turn this off by default: -//#define USE_REPEATED_ASSERTS -#ifdef USE_REPEATED_ASSERTS - #define assert(p,msg) \ - { for (int __i = 0; __i < AssertRepeat; __i++) { \ - if (!(p)) { \ - report_assertion_failure(__FILE__, __LINE__, \ - "assert(" XSTR(p) ",\"" msg "\")");\ - BREAKPOINT; \ - } \ - } \ - } -#else - #define assert(p,msg) \ - if (!(p)) { \ - report_assertion_failure(__FILE__, __LINE__, \ - "assert(" XSTR(p) ",\"" msg "\")");\ - BREAKPOINT; \ - } -#endif +#ifndef USE_REPEATED_ASSERTS +#define assert(p, msg) \ +do { \ + if (!(p)) { \ + report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", msg); \ + BREAKPOINT; \ + } \ +} while (0) +#else // #ifndef USE_REPEATED_ASSERTS +#define assert(p, msg) +do { \ + for (int __i = 0; __i < AssertRepeat; __i++) { \ + if (!(p)) { \ + report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", msg); \ + BREAKPOINT; \ + } \ + } \ +} while (0) +#endif // #ifndef USE_REPEATED_ASSERTS // This version of assert is for use with checking return status from // library calls that return actual error values eg. EINVAL, @@ -52,70 +78,83 @@ // what status was actually returned, so we pass the status variable as // an extra arg and use strerror to convert it to a meaningful string // like "Invalid argument", "out of memory" etc -#define assert_status(p, status, msg) \ - do { \ - if (!(p)) { \ - char buf[128]; \ - snprintf(buf, 127, \ - "assert_status(" XSTR(p) ", error: %s(%d), \"" msg "\")" , \ - strerror((status)), (status)); \ - report_assertion_failure(__FILE__, __LINE__, buf); \ - BREAKPOINT; \ - } \ - } while (0) - -// Another version of assert where the message is not a string literal -// The boolean condition is not printed out because cpp doesn't like it. -#define assert_msg(p, msg) \ - if (!(p)) { \ - report_assertion_failure(__FILE__, __LINE__, msg); \ - BREAKPOINT; \ - } +#define assert_status(p, status, msg) \ +do { \ + if (!(p)) { \ + report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", \ + err_msg("error %s(%d) %s", strerror(status), \ + status, msg)); \ + BREAKPOINT; \ + } \ +} while (0) // Do not assert this condition if there's already another error reported. #define assert_if_no_error(cond,msg) assert((cond) || is_error_reported(), msg) -#else +#else // #ifdef ASSERT #define assert(p,msg) #define assert_status(p,status,msg) #define assert_if_no_error(cond,msg) - #define assert_msg(cond,msg) -#endif - - -// fatals -#define fatal(m) { report_fatal(__FILE__, __LINE__, m ); BREAKPOINT; } -#define fatal1(m,x1) { report_fatal_vararg(__FILE__, __LINE__, m, x1 ); BREAKPOINT; } -#define fatal2(m,x1,x2) { report_fatal_vararg(__FILE__, __LINE__, m, x1, x2 ); BREAKPOINT; } -#define fatal3(m,x1,x2,x3) { report_fatal_vararg(__FILE__, __LINE__, m, x1, x2, x3 ); BREAKPOINT; } -#define fatal4(m,x1,x2,x3,x4) { report_fatal_vararg(__FILE__, __LINE__, m, x1, x2, x3, x4 ); BREAKPOINT; } - -// out of memory -#define vm_exit_out_of_memory(s,m) { report_vm_out_of_memory(__FILE__, __LINE__, s, m ); BREAKPOINT; } -#define vm_exit_out_of_memory1(s,m,x1) { report_vm_out_of_memory_vararg(__FILE__, __LINE__, s, m, x1 ); BREAKPOINT; } -#define vm_exit_out_of_memory2(s,m,x1,x2) { report_vm_out_of_memory_vararg(__FILE__, __LINE__, s, m, x1, x2 ); BREAKPOINT; } -#define vm_exit_out_of_memory3(s,m,x1,x2,x3) { report_vm_out_of_memory_vararg(__FILE__, __LINE__, s, m, x1, x2, x3 ); BREAKPOINT; } -#define vm_exit_out_of_memory4(s,m,x1,x2,x3,x4) { report_vm_out_of_memory_vararg(__FILE__, __LINE__, s, m, x1, x2, x3, x4); BREAKPOINT; } +#endif // #ifdef ASSERT // guarantee is like assert except it's always executed -- use it for -// cheap tests that catch errors that would otherwise be hard to find +// cheap tests that catch errors that would otherwise be hard to find. // guarantee is also used for Verify options. -#define guarantee(b,msg) { if (!(b)) fatal("guarantee(" XSTR(b) ",\"" msg "\")"); } +#define guarantee(p, msg) \ +do { \ + if (!(p)) { \ + report_vm_error(__FILE__, __LINE__, "guarantee(" #p ") failed", msg); \ + BREAKPOINT; \ + } \ +} while (0) + +#define fatal(msg) \ +do { \ + report_fatal(__FILE__, __LINE__, msg); \ + BREAKPOINT; \ +} while (0) + +// out of memory +#define vm_exit_out_of_memory(size, msg) \ +do { \ + report_vm_out_of_memory(__FILE__, __LINE__, size, msg); \ + BREAKPOINT; \ +} while (0) -#define ShouldNotCallThis() { report_should_not_call (__FILE__, __LINE__); BREAKPOINT; } -#define ShouldNotReachHere() { report_should_not_reach_here (__FILE__, __LINE__); BREAKPOINT; } -#define Unimplemented() { report_unimplemented (__FILE__, __LINE__); BREAKPOINT; } -#define Untested(msg) { report_untested (__FILE__, __LINE__, msg); BREAKPOINT; } +#define ShouldNotCallThis() \ +do { \ + report_should_not_call(__FILE__, __LINE__); \ + BREAKPOINT; \ +} while (0) + +#define ShouldNotReachHere() \ +do { \ + report_should_not_reach_here(__FILE__, __LINE__); \ + BREAKPOINT; \ +} while (0) + +#define Unimplemented() \ +do { \ + report_unimplemented(__FILE__, __LINE__); \ + BREAKPOINT; \ +} while (0) + +#define Untested(msg) \ +do { \ + report_untested(__FILE__, __LINE__, msg); \ + BREAKPOINT; \ +} while (0); // error reporting helper functions -void report_assertion_failure(const char* file_name, int line_no, const char* message); -void report_fatal_vararg(const char* file_name, int line_no, const char* format, ...); -void report_fatal(const char* file_name, int line_no, const char* message); -void report_vm_out_of_memory_vararg(const char* file_name, int line_no, size_t size, const char* format, ...); -void report_vm_out_of_memory(const char* file_name, int line_no, size_t size, const char* message); -void report_should_not_call(const char* file_name, int line_no); -void report_should_not_reach_here(const char* file_name, int line_no); -void report_unimplemented(const char* file_name, int line_no); -void report_untested(const char* file_name, int line_no, const char* msg); +void report_vm_error(const char* file, int line, const char* error_msg, + const char* detail_msg = NULL); +void report_fatal(const char* file, int line, const char* message); +void report_vm_out_of_memory(const char* file, int line, size_t size, + const char* message); +void report_should_not_call(const char* file, int line); +void report_should_not_reach_here(const char* file, int line); +void report_unimplemented(const char* file, int line); +void report_untested(const char* file, int line, const char* message); + void warning(const char* format, ...); // out of memory reporting @@ -125,5 +164,8 @@ bool is_error_reported(); void set_error_reported(); +/* Test assert(), fatal(), guarantee(), etc. */ +NOT_PRODUCT(void test_error_handler(size_t test_num);) + void pd_ps(frame f); void pd_obfuscate_location(char *buf, size_t buflen); diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/utilities/exceptions.cpp --- a/hotspot/src/share/vm/utilities/exceptions.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/utilities/exceptions.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -378,7 +378,7 @@ void Exceptions::debug_check_abort(const char *value_string) { if (AbortVMOnException != NULL && value_string != NULL && strstr(value_string, AbortVMOnException)) { - fatal1("Saw %s, aborting", value_string); + fatal(err_msg("Saw %s, aborting", value_string)); } } diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/utilities/macros.hpp --- a/hotspot/src/share/vm/utilities/macros.hpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/utilities/macros.hpp Thu Apr 22 13:23:15 2010 -0700 @@ -188,6 +188,4 @@ #define NOT_SPARC(code) code #endif -#define FIX_THIS(code) report_assertion_failure("FIX_THIS",__FILE__, __LINE__, "") - #define define_pd_global(type, name, value) const type pd_##name = value; diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/utilities/vmError.cpp --- a/hotspot/src/share/vm/utilities/vmError.cpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/utilities/vmError.cpp Thu Apr 22 13:23:15 2010 -0700 @@ -65,7 +65,8 @@ _current_step = 0; _current_step_info = NULL; - _message = ""; + _message = NULL; + _detail_msg = NULL; _filename = NULL; _lineno = 0; @@ -73,31 +74,36 @@ } // Constructor for internal errors -VMError::VMError(Thread* thread, const char* message, const char* filename, int lineno) { +VMError::VMError(Thread* thread, const char* filename, int lineno, + const char* message, const char * detail_msg) +{ + _thread = thread; + _id = internal_error; // Value that's not an OS exception/signal + _filename = filename; + _lineno = lineno; + _message = message; + _detail_msg = detail_msg; + + _verbose = false; + _current_step = 0; + _current_step_info = NULL; + + _pc = NULL; + _siginfo = NULL; + _context = NULL; + + _size = 0; +} + +// Constructor for OOM errors +VMError::VMError(Thread* thread, const char* filename, int lineno, size_t size, + const char* message) { _thread = thread; - _id = internal_error; // set it to a value that's not an OS exception/signal + _id = oom_error; // Value that's not an OS exception/signal _filename = filename; _lineno = lineno; _message = message; - - _verbose = false; - _current_step = 0; - _current_step_info = NULL; - - _pc = NULL; - _siginfo = NULL; - _context = NULL; - - _size = 0; -} - -// Constructor for OOM errors -VMError::VMError(Thread* thread, size_t size, const char* message, const char* filename, int lineno) { - _thread = thread; - _id = oom_error; // set it to a value that's not an OS exception/signal - _filename = filename; - _lineno = lineno; - _message = message; + _detail_msg = NULL; _verbose = false; _current_step = 0; @@ -114,10 +120,11 @@ // Constructor for non-fatal errors VMError::VMError(const char* message) { _thread = NULL; - _id = internal_error; // set it to a value that's not an OS exception/signal + _id = internal_error; // Value that's not an OS exception/signal _filename = NULL; _lineno = 0; _message = message; + _detail_msg = NULL; _verbose = false; _current_step = 0; @@ -191,22 +198,27 @@ "%s (0x%x) at pc=" PTR_FORMAT ", pid=%d, tid=" UINTX_FORMAT, signame, _id, _pc, os::current_process_id(), os::current_thread_id()); + } else if (_filename != NULL && _lineno > 0) { + // skip directory names + char separator = os::file_separator()[0]; + const char *p = strrchr(_filename, separator); + int n = jio_snprintf(buf, buflen, + "Internal Error at %s:%d, pid=%d, tid=" UINTX_FORMAT, + p ? p + 1 : _filename, _lineno, + os::current_process_id(), os::current_thread_id()); + if (n >= 0 && n < buflen && _message) { + if (_detail_msg) { + jio_snprintf(buf + n, buflen - n, "%s%s: %s", + os::line_separator(), _message, _detail_msg); + } else { + jio_snprintf(buf + n, buflen - n, "%sError: %s", + os::line_separator(), _message); + } + } } else { - if (_filename != NULL && _lineno > 0) { - // skip directory names - char separator = os::file_separator()[0]; - const char *p = strrchr(_filename, separator); - - jio_snprintf(buf, buflen, - "Internal Error at %s:%d, pid=%d, tid=" UINTX_FORMAT " \nError: %s", - p ? p + 1 : _filename, _lineno, - os::current_process_id(), os::current_thread_id(), - _message ? _message : ""); - } else { - jio_snprintf(buf, buflen, - "Internal Error (0x%x), pid=%d, tid=" UINTX_FORMAT, - _id, os::current_process_id(), os::current_thread_id()); - } + jio_snprintf(buf, buflen, + "Internal Error (0x%x), pid=%d, tid=" UINTX_FORMAT, + _id, os::current_process_id(), os::current_thread_id()); } return buf; @@ -369,7 +381,9 @@ STEP(40, "(printing error message)") // error message - if (_message && _message[0] != '\0') { + if (_detail_msg) { + st->print_cr("# %s: %s", _message ? _message : "Error", _detail_msg); + } else if (_message) { st->print_cr("# Error: %s", _message); } diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/src/share/vm/utilities/vmError.hpp --- a/hotspot/src/share/vm/utilities/vmError.hpp Sun Oct 11 16:19:25 2009 -0700 +++ b/hotspot/src/share/vm/utilities/vmError.hpp Thu Apr 22 13:23:15 2010 -0700 @@ -37,6 +37,7 @@ // 0x8xxxxxxx system warnings const char * _message; + const char * _detail_msg; Thread * _thread; // NULL if it's native thread @@ -75,16 +76,19 @@ char* buf, int buflen, bool verbose = false); // accessor - const char* message() { return _message; } + const char* message() const { return _message; } + const char* detail_msg() const { return _detail_msg; } public: // Constructor for crashes VMError(Thread* thread, int sig, address pc, void* siginfo, void* context); // Constructor for VM internal errors - VMError(Thread* thread, const char* message, const char* filename, int lineno); + VMError(Thread* thread, const char* filename, int lineno, + const char* message, const char * detail_msg); - // Constructors for VM OOM errors - VMError(Thread* thread, size_t size, const char* message, const char* filename, int lineno); + // Constructor for VM OOM errors + VMError(Thread* thread, const char* filename, int lineno, size_t size, + const char* message); // Constructor for non-fatal errors VMError(const char* message); diff -r c51fd0c1d005 -r 6b0dd9c75dde hotspot/test/runtime/6888954/vmerrors.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/6888954/vmerrors.sh Thu Apr 22 13:23:15 2010 -0700 @@ -0,0 +1,71 @@ +# @test +# @bug 6888954 +# @summary exercise HotSpot error handling code +# @author John Coomes +# @run shell vmerrors.sh + +# Repeatedly invoke java with a command-line option that causes HotSpot to +# produce an error report and terminate just after initialization. Each +# invocation is identified by a small integer, , which provokes a different +# error (assertion failure, guarantee failure, fatal error, etc.). The output +# from stdout/stderr is written to .out and the hs_err_pidXXX.log file is +# renamed to .log. +# +# The automated checking done by this script is minimal. When updating the +# fatal error handler it is more useful to run it manually or to use the -retain +# option with the jtreg so that test directories are not removed automatically. +# To run stand-alone: +# +# TESTJAVA=/java/home/dir +# TESTVMOPTS=... +# export TESTJAVA TESTVMOPTS +# sh test/runtime/6888954/vmerrors.sh + +ulimit -c 0 # no core files + +i=1 +rc=0 + +assert_re='(assert|guarantee)[(](str|num).*failed: *' +guarantee_re='guarantee[(](str|num).*failed: *' +fatal_re='fatal error: *' +signal_re='(SIGSEGV|EXCEPTION_ACCESS_VIOLATION).* at pc=' +tail_1='.*expected null' +tail_2='.*num=' + +for re in \ + "${assert_re}${tail_1}" "${assert_re}${tail_2}" \ + "${guarantee_re}${tail_1}" "${guarantee_re}${tail_2}" \ + "${fatal_re}${tail_1}" "${fatal_re}${tail_2}" \ + "${fatal_re}.*truncated" "ChunkPool::allocate" \ + "ShouldNotCall" "ShouldNotReachHere" \ + "Unimplemented" "$signal_re" + +do + i2=$i + [ $i -lt 10 ] && i2=0$i + + "$TESTJAVA/bin/java" $TESTVMOPTS -XX:+IgnoreUnrecognizedVMOptions \ + -XX:ErrorHandlerTest=${i} -version > ${i2}.out 2>&1 + + # If ErrorHandlerTest is ignored (product build), stop. + # + # Using the built-in variable $! to get the pid does not work reliably on + # windows; use a wildcard instead. + mv hs_err_pid*.log ${i2}.log || exit $rc + + for f in ${i2}.log ${i2}.out + do + egrep -- "$re" $f > $$ + if [ $? -ne 0 ] + then + echo "ErrorHandlerTest=$i failed ($f)" + rc=1 + fi + done + rm -f $$ + + i=$(expr $i + 1) +done + +exit $rc