diff --git a/src/hotspot/share/runtime/javaThread.cpp b/src/hotspot/share/runtime/javaThread.cpp index 473ce59c751..98141707ca2 100644 --- a/src/hotspot/share/runtime/javaThread.cpp +++ b/src/hotspot/share/runtime/javaThread.cpp @@ -1515,12 +1515,13 @@ void JavaThread::print_on_error(outputStream* st, char *buf, int buflen) const { st->print("%s \"%s\"", type_name(), get_thread_name_string(buf, buflen)); Thread* current = Thread::current_or_null_safe(); assert(current != nullptr, "cannot be called by a detached thread"); + st->fill_to(60); if (!current->is_Java_thread() || JavaThread::cast(current)->is_oop_safe()) { // Only access threadObj() if current thread is not a JavaThread // or if it is a JavaThread that can safely access oops. oop thread_obj = threadObj(); if (thread_obj != nullptr) { - if (java_lang_Thread::is_daemon(thread_obj)) st->print(" daemon"); + st->print(java_lang_Thread::is_daemon(thread_obj) ? " daemon" : " "); } } st->print(" ["); @@ -1528,8 +1529,9 @@ void JavaThread::print_on_error(outputStream* st, char *buf, int buflen) const { if (osthread()) { st->print(", id=%d", osthread()->thread_id()); } - st->print(", stack(" PTR_FORMAT "," PTR_FORMAT ")", - p2i(stack_end()), p2i(stack_base())); + st->print(", stack(" PTR_FORMAT "," PTR_FORMAT ") (" PROPERFMT ")", + p2i(stack_end()), p2i(stack_base()), + PROPERFMTARGS(stack_size())); st->print("]"); ThreadsSMRSupport::print_info_on(this, st); diff --git a/src/hotspot/share/runtime/thread.cpp b/src/hotspot/share/runtime/thread.cpp index 047584ccda1..206a231143c 100644 --- a/src/hotspot/share/runtime/thread.cpp +++ b/src/hotspot/share/runtime/thread.cpp @@ -483,10 +483,11 @@ void Thread::print_on_error(outputStream* st, char* buf, int buflen) const { OSThread* os_thr = osthread(); if (os_thr != nullptr) { + st->fill_to(67); if (os_thr->get_state() != ZOMBIE) { - st->print(" [stack: " PTR_FORMAT "," PTR_FORMAT "]", - p2i(stack_end()), p2i(stack_base())); - st->print(" [id=%d]", osthread()->thread_id()); + st->print(" [id=%d, stack(" PTR_FORMAT "," PTR_FORMAT ") (" PROPERFMT ")]", + osthread()->thread_id(), p2i(stack_end()), p2i(stack_base()), + PROPERFMTARGS(stack_size())); } else { st->print(" terminated"); } diff --git a/src/hotspot/share/runtime/threads.cpp b/src/hotspot/share/runtime/threads.cpp index 0517150feed..ff1a41f00e6 100644 --- a/src/hotspot/share/runtime/threads.cpp +++ b/src/hotspot/share/runtime/threads.cpp @@ -1298,14 +1298,19 @@ class PrintOnErrorClosure : public ThreadClosure { char* _buf; int _buflen; bool* _found_current; + unsigned _num_printed; 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) {} + _st(st), _current(current), _buf(buf), _buflen(buflen), _found_current(found_current), + _num_printed(0) {} virtual void do_thread(Thread* thread) { + _num_printed++; Threads::print_on_error(thread, _st, _current, _buf, _buflen, _found_current); } + + unsigned num_printed() const { return _num_printed; } }; // Threads::print_on_error() is called by fatal error handler. It's possible @@ -1319,12 +1324,18 @@ void Threads::print_on_error(outputStream* st, Thread* current, char* buf, bool found_current = false; st->print_cr("Java Threads: ( => current thread )"); + unsigned num_java = 0; ALL_JAVA_THREADS(thread) { print_on_error(thread, st, current, buf, buflen, &found_current); + num_java++; } + st->print_cr("Total: %u", num_java); st->cr(); st->print_cr("Other Threads:"); + unsigned num_other = ((VMThread::vm_thread() != nullptr) ? 1 : 0) + + ((WatcherThread::watcher_thread() != nullptr) ? 1 : 0) + + ((AsyncLogWriter::instance() != nullptr) ? 1 : 0); print_on_error(VMThread::vm_thread(), st, current, buf, buflen, &found_current); print_on_error(WatcherThread::watcher_thread(), st, current, buf, buflen, &found_current); print_on_error(AsyncLogWriter::instance(), st, current, buf, buflen, &found_current); @@ -1332,21 +1343,26 @@ void Threads::print_on_error(outputStream* st, Thread* current, char* buf, if (Universe::heap() != nullptr) { PrintOnErrorClosure print_closure(st, current, buf, buflen, &found_current); Universe::heap()->gc_threads_do(&print_closure); + num_other += print_closure.num_printed(); } if (!found_current) { st->cr(); st->print("=>" PTR_FORMAT " (exited) ", p2i(current)); current->print_on_error(st, buf, buflen); + num_other++; st->cr(); } + st->print_cr("Total: %u", num_other); st->cr(); st->print_cr("Threads with active compile tasks:"); - print_threads_compiling(st, buf, buflen); + unsigned num = print_threads_compiling(st, buf, buflen); + st->print_cr("Total: %u", num); } -void Threads::print_threads_compiling(outputStream* st, char* buf, int buflen, bool short_form) { +unsigned Threads::print_threads_compiling(outputStream* st, char* buf, int buflen, bool short_form) { + unsigned num = 0; ALL_JAVA_THREADS(thread) { if (thread->is_Compiler_thread()) { CompilerThread* ct = (CompilerThread*) thread; @@ -1360,9 +1376,11 @@ void Threads::print_threads_compiling(outputStream* st, char* buf, int buflen, b thread->print_name_on_error(st, buf, buflen); st->print(" "); task->print(st, nullptr, short_form, true); + num++; } } } + return num; } void Threads::verify() { diff --git a/src/hotspot/share/runtime/threads.hpp b/src/hotspot/share/runtime/threads.hpp index 520404e2e7c..b81c74caa13 100644 --- a/src/hotspot/share/runtime/threads.hpp +++ b/src/hotspot/share/runtime/threads.hpp @@ -128,7 +128,8 @@ public: 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, bool short_form = false); + // Print threads busy compiling, and returns the number of printed threads. + static unsigned print_threads_compiling(outputStream* st, char* buf, int buflen, bool short_form = false); // Get Java threads that are waiting to enter a monitor. static GrowableArray* get_pending_threads(ThreadsList * t_list,