# HG changeset patch # User drwhite # Date 1460581254 14400 # Node ID 5d721e36f744a03e7da722959a0a769f72a82a7e # Parent 8af1deb0c87978c6fbcead242a4fe2c68ed4f8b6 8152905: hs_err file is missing gc threads Summary: List the GC threads in the hs_err file in the "Other Threads" section Reviewed-by: dcubed, coleenp diff -r 8af1deb0c879 -r 5d721e36f744 hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp --- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Tue Apr 12 14:46:02 2016 -0400 +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Wed Apr 13 17:00:54 2016 -0400 @@ -2742,7 +2742,7 @@ _cmThread->print_on(st); st->cr(); _cm->print_worker_threads_on(st); - _cg1r->print_worker_threads_on(st); + _cg1r->print_worker_threads_on(st); // also prints the sample thread if (G1StringDedup::is_enabled()) { G1StringDedup::print_worker_threads_on(st); } @@ -2751,7 +2751,8 @@ void G1CollectedHeap::gc_threads_do(ThreadClosure* tc) const { workers()->threads_do(tc); tc->do_thread(_cmThread); - _cg1r->threads_do(tc); + _cm->threads_do(tc); + _cg1r->threads_do(tc); // also iterates over the sample thread if (G1StringDedup::is_enabled()) { G1StringDedup::threads_do(tc); } diff -r 8af1deb0c879 -r 5d721e36f744 hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp --- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp Tue Apr 12 14:46:02 2016 -0400 +++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp Wed Apr 13 17:00:54 2016 -0400 @@ -2112,6 +2112,10 @@ _parallel_workers->print_worker_threads_on(st); } +void G1ConcurrentMark::threads_do(ThreadClosure* tc) const { + _parallel_workers->threads_do(tc); +} + void G1ConcurrentMark::print_on_error(outputStream* st) const { st->print_cr("Marking Bits (Prev, Next): (CMBitMap*) " PTR_FORMAT ", (CMBitMap*) " PTR_FORMAT, p2i(_prevMarkBitMap), p2i(_nextMarkBitMap)); diff -r 8af1deb0c879 -r 5d721e36f744 hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp --- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp Tue Apr 12 14:46:02 2016 -0400 +++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp Wed Apr 13 17:00:54 2016 -0400 @@ -621,6 +621,7 @@ void print_summary_info(); void print_worker_threads_on(outputStream* st) const; + void threads_do(ThreadClosure* tc) const; void print_on_error(outputStream* st) const; diff -r 8af1deb0c879 -r 5d721e36f744 hotspot/src/share/vm/runtime/thread.cpp --- a/hotspot/src/share/vm/runtime/thread.cpp Tue Apr 12 14:46:02 2016 -0400 +++ b/hotspot/src/share/vm/runtime/thread.cpp Wed Apr 13 17:00:54 2016 -0400 @@ -818,13 +818,17 @@ // Thread::print_on_error() is called by fatal error handler. Don't use // any lock or allocate memory. void Thread::print_on_error(outputStream* st, char* buf, int buflen) const { - if (is_VM_thread()) st->print("VMThread"); - else if (is_Compiler_thread()) st->print("CompilerThread"); - else if (is_Java_thread()) st->print("JavaThread"); - else if (is_GC_task_thread()) st->print("GCTaskThread"); - else if (is_Watcher_thread()) st->print("WatcherThread"); - else if (is_ConcurrentGC_thread()) st->print("ConcurrentGCThread"); - else st->print("Thread"); + assert(!(is_Compiler_thread() || is_Java_thread()), "Can't call name() here if it allocates"); + + if (is_VM_thread()) { st->print("VMThread"); } + else if (is_GC_task_thread()) { st->print("GCTaskThread"); } + else if (is_Watcher_thread()) { st->print("WatcherThread"); } + else if (is_ConcurrentGC_thread()) { st->print("ConcurrentGCThread"); } + else { st->print("Thread"); } + + if (is_Named_thread()) { + st->print(" \"%s\"", name()); + } st->print(" [stack: " PTR_FORMAT "," PTR_FORMAT "]", p2i(stack_end()), p2i(stack_base())); @@ -4498,6 +4502,36 @@ st->flush(); } +void Threads::print_on_error(Thread* this_thread, outputStream* st, Thread* current, char* buf, + int buflen, bool* found_current) { + if (this_thread != NULL) { + bool is_current = (current == this_thread); + *found_current = *found_current || is_current; + st->print("%s", is_current ? "=>" : " "); + + st->print(PTR_FORMAT, p2i(this_thread)); + st->print(" "); + this_thread->print_on_error(st, buf, buflen); + st->cr(); + } +} + +class PrintOnErrorClosure : public ThreadClosure { + outputStream* _st; + Thread* _current; + char* _buf; + int _buflen; + bool* _found_current; + public: + PrintOnErrorClosure(outputStream* st, Thread* current, char* buf, + int buflen, bool* found_current) : + _st(st), _current(current), _buf(buf), _buflen(buflen), _found_current(found_current) {} + + virtual void do_thread(Thread* thread) { + Threads::print_on_error(thread, _st, _current, _buf, _buflen, _found_current); + } +}; + // Threads::print_on_error() is called by fatal error handler. It's possible // that VM is not at safepoint and/or current thread is inside signal handler. // Don't print stack trace, as the stack may not be walkable. Don't allocate @@ -4507,40 +4541,17 @@ bool found_current = false; st->print_cr("Java Threads: ( => current thread )"); ALL_JAVA_THREADS(thread) { - bool is_current = (current == thread); - found_current = found_current || is_current; - - st->print("%s", is_current ? "=>" : " "); - - st->print(PTR_FORMAT, p2i(thread)); - st->print(" "); - thread->print_on_error(st, buf, buflen); - st->cr(); + print_on_error(thread, st, current, buf, buflen, &found_current); } st->cr(); st->print_cr("Other Threads:"); - if (VMThread::vm_thread()) { - bool is_current = (current == VMThread::vm_thread()); - found_current = found_current || is_current; - st->print("%s", current == VMThread::vm_thread() ? "=>" : " "); - - st->print(PTR_FORMAT, p2i(VMThread::vm_thread())); - st->print(" "); - VMThread::vm_thread()->print_on_error(st, buf, buflen); - st->cr(); - } - WatcherThread* wt = WatcherThread::watcher_thread(); - if (wt != NULL) { - bool is_current = (current == wt); - found_current = found_current || is_current; - st->print("%s", is_current ? "=>" : " "); - - st->print(PTR_FORMAT, p2i(wt)); - st->print(" "); - wt->print_on_error(st, buf, buflen); - st->cr(); - } + print_on_error(VMThread::vm_thread(), st, current, buf, buflen, &found_current); + print_on_error(WatcherThread::watcher_thread(), st, current, buf, buflen, &found_current); + + PrintOnErrorClosure print_closure(st, current, buf, buflen, &found_current); + Universe::heap()->gc_threads_do(&print_closure); + if (!found_current) { st->cr(); st->print("=>" PTR_FORMAT " (exited) ", p2i(current)); diff -r 8af1deb0c879 -r 5d721e36f744 hotspot/src/share/vm/runtime/thread.hpp --- a/hotspot/src/share/vm/runtime/thread.hpp Tue Apr 12 14:46:02 2016 -0400 +++ b/hotspot/src/share/vm/runtime/thread.hpp Wed Apr 13 17:00:54 2016 -0400 @@ -2156,6 +2156,8 @@ print_on(tty, print_stacks, internal_format, false /* no concurrent lock printed */); } static void print_on_error(outputStream* st, Thread* current, char* buf, int buflen); + static void print_on_error(Thread* this_thread, outputStream* st, Thread* current, char* buf, + int buflen, bool* found_current); static void print_threads_compiling(outputStream* st, char* buf, int buflen); // Get Java threads that are waiting to enter a monitor. If doLock