8306510: Print number of threads and stack sizes in error reports

Reviewed-by: gziemski, dholmes
This commit is contained in:
Thomas Stuefe 2023-05-02 12:18:23 +00:00
parent a8d16dea8e
commit ea9201f420
4 changed files with 32 additions and 10 deletions

View file

@ -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);

View file

@ -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");
}

View file

@ -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() {

View file

@ -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<JavaThread*>* get_pending_threads(ThreadsList * t_list,