From 2769b6a97b47928d5a9a6f3cafbd3a3eb38cd75a Mon Sep 17 00:00:00 2001 From: shshahma Date: Wed, 14 Mar 2018 03:19:46 -0700 Subject: [PATCH] 8035074: hs_err improvement: Add time zone information in the hs_err file 8026335: hs_err improvement: Print exact compressed oops mode and the heap base value. 8026331: hs_err improvement: Print if we have seen any OutOfMemoryErrors or StackOverflowErrors Summary: Add requested things to hs_err file. Reviewed-by: dholmes --- .../vm/interpreter/interpreterRuntime.cpp | 4 +- src/share/vm/memory/metaspace.cpp | 19 ++++++-- src/share/vm/memory/metaspace.hpp | 4 +- src/share/vm/memory/universe.cpp | 18 ++++---- src/share/vm/memory/universe.hpp | 4 +- src/share/vm/runtime/os.cpp | 10 +++- src/share/vm/runtime/os.hpp | 2 +- src/share/vm/runtime/sharedRuntime.cpp | 4 +- src/share/vm/utilities/exceptions.cpp | 46 ++++++++++++++++++- src/share/vm/utilities/exceptions.hpp | 15 +++++- src/share/vm/utilities/vmError.cpp | 22 ++++++++- 11 files changed, 122 insertions(+), 26 deletions(-) diff --git a/src/share/vm/interpreter/interpreterRuntime.cpp b/src/share/vm/interpreter/interpreterRuntime.cpp index 877c1ce32..b5a72296f 100644 --- a/src/share/vm/interpreter/interpreterRuntime.cpp +++ b/src/share/vm/interpreter/interpreterRuntime.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, 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 @@ -320,6 +320,8 @@ IRT_ENTRY(void, InterpreterRuntime::throw_StackOverflowError(JavaThread* thread) Handle exception = get_preinitialized_exception( SystemDictionary::StackOverflowError_klass(), CHECK); + // Increment counter for hs_err file reporting + Atomic::inc(&Exceptions::_stack_overflow_errors); THROW_HANDLE(exception); IRT_END diff --git a/src/share/vm/memory/metaspace.cpp b/src/share/vm/memory/metaspace.cpp index 764b425e4..64f1abd82 100644 --- a/src/share/vm/memory/metaspace.cpp +++ b/src/share/vm/memory/metaspace.cpp @@ -3098,13 +3098,24 @@ void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, a initialize_class_space(metaspace_rs); if (PrintCompressedOopsMode || (PrintMiscellaneous && Verbose)) { - gclog_or_tty->print_cr("Narrow klass base: " PTR_FORMAT ", Narrow klass shift: " SIZE_FORMAT, - Universe::narrow_klass_base(), Universe::narrow_klass_shift()); - gclog_or_tty->print_cr("Compressed class space size: " SIZE_FORMAT " Address: " PTR_FORMAT " Req Addr: " PTR_FORMAT, - compressed_class_space_size(), metaspace_rs.base(), requested_addr); + print_compressed_class_space(gclog_or_tty, requested_addr); } } +void Metaspace::print_compressed_class_space(outputStream* st, const char* requested_addr) { + st->print_cr("Narrow klass base: " PTR_FORMAT ", Narrow klass shift: %d", + p2i(Universe::narrow_klass_base()), Universe::narrow_klass_shift()); + if (_class_space_list != NULL) { + address base = (address)_class_space_list->current_virtual_space()->bottom(); + st->print("Compressed class space size: " SIZE_FORMAT " Address: " PTR_FORMAT, + compressed_class_space_size(), p2i(base)); + if (requested_addr != 0) { + st->print(" Req Addr: " PTR_FORMAT, p2i(requested_addr)); + } + st->cr(); + } + } + // For UseCompressedClassPointers the class space is reserved above the top of // the Java heap. The argument passed in is at the base of the compressed space. void Metaspace::initialize_class_space(ReservedSpace rs) { diff --git a/src/share/vm/memory/metaspace.hpp b/src/share/vm/memory/metaspace.hpp index 051f35b0b..36b00a521 100644 --- a/src/share/vm/memory/metaspace.hpp +++ b/src/share/vm/memory/metaspace.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2018, 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 @@ -259,6 +259,8 @@ class Metaspace : public CHeapObj { // Debugging support void verify(); + static void print_compressed_class_space(outputStream* st, const char* requested_addr = 0); + class AllocRecordClosure : public StackObj { public: virtual void doit(address ptr, MetaspaceObj::Type type, int byte_size) = 0; diff --git a/src/share/vm/memory/universe.cpp b/src/share/vm/memory/universe.cpp index 2e1e90f97..efac8e107 100644 --- a/src/share/vm/memory/universe.cpp +++ b/src/share/vm/memory/universe.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, 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 @@ -882,7 +882,7 @@ jint Universe::initialize_heap() { Universe::set_narrow_ptrs_base(Universe::narrow_oop_base()); if (PrintCompressedOopsMode || (PrintMiscellaneous && Verbose)) { - Universe::print_compressed_oops_mode(); + Universe::print_compressed_oops_mode(tty); } } // Universe::narrow_oop_base() is one page below the heap. @@ -904,23 +904,21 @@ jint Universe::initialize_heap() { return JNI_OK; } -void Universe::print_compressed_oops_mode() { - tty->cr(); - tty->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB", +void Universe::print_compressed_oops_mode(outputStream* st) { + st->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB", Universe::heap()->base(), Universe::heap()->reserved_region().byte_size()/M); - tty->print(", Compressed Oops mode: %s", narrow_oop_mode_to_string(narrow_oop_mode())); + st->print(", Compressed Oops mode: %s", narrow_oop_mode_to_string(narrow_oop_mode())); if (Universe::narrow_oop_base() != 0) { - tty->print(":" PTR_FORMAT, Universe::narrow_oop_base()); + st->print(":" PTR_FORMAT, Universe::narrow_oop_base()); } if (Universe::narrow_oop_shift() != 0) { - tty->print(", Oop shift amount: %d", Universe::narrow_oop_shift()); + st->print(", Oop shift amount: %d", Universe::narrow_oop_shift()); } - tty->cr(); - tty->cr(); + st->cr(); } // Reserve the Java heap, which is now the same for all GCs. diff --git a/src/share/vm/memory/universe.hpp b/src/share/vm/memory/universe.hpp index 3c6a89d2c..8909c6d1b 100644 --- a/src/share/vm/memory/universe.hpp +++ b/src/share/vm/memory/universe.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, 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 @@ -375,7 +375,7 @@ class Universe: AllStatic { static void set_narrow_ptrs_base(address a) { _narrow_ptrs_base = a; } static address narrow_ptrs_base() { return _narrow_ptrs_base; } - static void print_compressed_oops_mode(); + static void print_compressed_oops_mode(outputStream* st); // this is set in vm_version on sparc (and then reset in universe afaict) static void set_narrow_oop_shift(int shift) { diff --git a/src/share/vm/runtime/os.cpp b/src/share/vm/runtime/os.cpp index 06e81a554..808fa2716 100644 --- a/src/share/vm/runtime/os.cpp +++ b/src/share/vm/runtime/os.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, 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 @@ -847,7 +847,7 @@ void os::print_cpu_info(outputStream* st) { pd_print_cpu_info(st); } -void os::print_date_and_time(outputStream *st) { +void os::print_date_and_time(outputStream *st, char* buf, size_t buflen) { const int secs_per_day = 86400; const int secs_per_hour = 3600; const int secs_per_min = 60; @@ -856,6 +856,12 @@ void os::print_date_and_time(outputStream *st) { (void)time(&tloc); st->print("time: %s", ctime(&tloc)); // ctime adds newline. + struct tm tz; + if (localtime_pd(&tloc, &tz) != NULL) { + ::strftime(buf, buflen, "%Z", &tz); + st->print_cr("timezone: %s", buf); + } + double t = os::elapsedTime(); // NOTE: It tends to crash after a SEGV if we want to printf("%f",...) in // Linux. Must be a bug in glibc ? Workaround is to round "t" to int diff --git a/src/share/vm/runtime/os.hpp b/src/share/vm/runtime/os.hpp index 6f85ff9c1..03afd1ba2 100644 --- a/src/share/vm/runtime/os.hpp +++ b/src/share/vm/runtime/os.hpp @@ -621,7 +621,7 @@ class os: AllStatic { static void print_register_info(outputStream* st, void* context); static void print_siginfo(outputStream* st, void* siginfo); static void print_signal_handlers(outputStream* st, char* buf, size_t buflen); - static void print_date_and_time(outputStream* st); + static void print_date_and_time(outputStream* st, char* buf, size_t buflen); static void print_location(outputStream* st, intptr_t x, bool verbose = false); static size_t lasterror(char *buf, size_t len); diff --git a/src/share/vm/runtime/sharedRuntime.cpp b/src/share/vm/runtime/sharedRuntime.cpp index 8ffa8ab31..eb270cad2 100644 --- a/src/share/vm/runtime/sharedRuntime.cpp +++ b/src/share/vm/runtime/sharedRuntime.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, 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 @@ -758,6 +758,8 @@ JRT_ENTRY(void, SharedRuntime::throw_StackOverflowError(JavaThread* thread)) if (StackTraceInThrowable) { java_lang_Throwable::fill_in_stack_trace(exception); } + // Increment counter for hs_err file reporting + Atomic::inc(&Exceptions::_stack_overflow_errors); throw_and_post_jvmti_exception(thread, exception); JRT_END diff --git a/src/share/vm/utilities/exceptions.cpp b/src/share/vm/utilities/exceptions.cpp index 5295c9b36..188e09730 100644 --- a/src/share/vm/utilities/exceptions.cpp +++ b/src/share/vm/utilities/exceptions.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2018, 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 @@ -154,6 +154,10 @@ void Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exc return; } + if (h_exception->is_a(SystemDictionary::OutOfMemoryError_klass())) { + count_out_of_memory_exceptions(h_exception); + } + assert(h_exception->is_a(SystemDictionary::Throwable_klass()), "exception is not a subclass of java/lang/Throwable"); // set the pending exception @@ -228,6 +232,8 @@ void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file if (StackTraceInThrowable) { java_lang_Throwable::fill_in_stack_trace(exception, method()); } + // Increment counter for hs_err file reporting + Atomic::inc(&Exceptions::_stack_overflow_errors); } else { // if prior exception, throw that one instead exception = Handle(THREAD, THREAD->pending_exception()); @@ -404,6 +410,44 @@ Handle Exceptions::new_exception(Thread* thread, Symbol* name, h_prot, to_utf8_safe); } + +// Exception counting for hs_err file +volatile int Exceptions::_stack_overflow_errors = 0; +volatile int Exceptions::_out_of_memory_error_java_heap_errors = 0; +volatile int Exceptions::_out_of_memory_error_metaspace_errors = 0; +volatile int Exceptions::_out_of_memory_error_class_metaspace_errors = 0; + +void Exceptions::count_out_of_memory_exceptions(Handle exception) { + if (exception() == Universe::out_of_memory_error_metaspace()) { + Atomic::inc(&_out_of_memory_error_metaspace_errors); + } else if (exception() == Universe::out_of_memory_error_class_metaspace()) { + Atomic::inc(&_out_of_memory_error_class_metaspace_errors); + } else { + // everything else reported as java heap OOM + Atomic::inc(&_out_of_memory_error_java_heap_errors); + } +} + +void print_oom_count(outputStream* st, const char *err, int count) { + if (count > 0) { + st->print_cr("OutOfMemoryError %s=%d", err, count); + } +} + +bool Exceptions::has_exception_counts() { + return (_stack_overflow_errors + _out_of_memory_error_java_heap_errors + + _out_of_memory_error_metaspace_errors + _out_of_memory_error_class_metaspace_errors) > 0; +} + +void Exceptions::print_exception_counts_on_error(outputStream* st) { + print_oom_count(st, "java_heap_errors", _out_of_memory_error_java_heap_errors); + print_oom_count(st, "metaspace_errors", _out_of_memory_error_metaspace_errors); + print_oom_count(st, "class_metaspace_errors", _out_of_memory_error_class_metaspace_errors); + if (_stack_overflow_errors > 0) { + st->print_cr("StackOverflowErrors=%d", _stack_overflow_errors); + } +} + // Implementation of ExceptionMark ExceptionMark::ExceptionMark(Thread*& thread) { diff --git a/src/share/vm/utilities/exceptions.hpp b/src/share/vm/utilities/exceptions.hpp index 3dfe338ea..0a59d5809 100644 --- a/src/share/vm/utilities/exceptions.hpp +++ b/src/share/vm/utilities/exceptions.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2018, 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 @@ -102,6 +102,11 @@ class ThreadShadow: public CHeapObj { class Exceptions { static bool special_exception(Thread *thread, const char* file, int line, Handle exception); static bool special_exception(Thread* thread, const char* file, int line, Symbol* name, const char* message); + + // Count out of memory errors that are interesting in error diagnosis + static volatile int _out_of_memory_error_java_heap_errors; + static volatile int _out_of_memory_error_metaspace_errors; + static volatile int _out_of_memory_error_class_metaspace_errors; public: // this enum is defined to indicate whether it is safe to // ignore the encoding scheme of the original message string. @@ -160,6 +165,14 @@ class Exceptions { static void throw_stack_overflow_exception(Thread* thread, const char* file, int line, methodHandle method); + // Exception counting for error files of interesting exceptions that may have + // caused a problem for the jvm + static volatile int _stack_overflow_errors; + + static bool has_exception_counts(); + static void count_out_of_memory_exceptions(Handle exception); + static void print_exception_counts_on_error(outputStream* st); + // for AbortVMOnException flag NOT_PRODUCT(static void debug_check_abort(Handle exception, const char* message = NULL);) NOT_PRODUCT(static void debug_check_abort(const char *value_string, const char* message = NULL);) diff --git a/src/share/vm/utilities/vmError.cpp b/src/share/vm/utilities/vmError.cpp index 15f6bf484..f5d748085 100644 --- a/src/share/vm/utilities/vmError.cpp +++ b/src/share/vm/utilities/vmError.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2018, 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 @@ -675,6 +675,24 @@ void VMError::report(outputStream* st) { st->cr(); } + STEP(182, "(printing number of OutOfMemoryError and StackOverflow exceptions)") + + if (_verbose && Exceptions::has_exception_counts()) { + st->print_cr("OutOfMemory and StackOverflow Exception counts:"); + Exceptions::print_exception_counts_on_error(st); + st->cr(); + } + + STEP(185, "(printing compressed oops mode") + + if (_verbose && UseCompressedOops) { + Universe::print_compressed_oops_mode(st); + if (UseCompressedClassPointers) { + Metaspace::print_compressed_class_space(st); + } + st->cr(); + } + STEP(190, "(printing heap information)" ) if (_verbose && Universe::is_fully_initialized()) { @@ -780,7 +798,7 @@ void VMError::report(outputStream* st) { STEP(280, "(printing date and time)" ) if (_verbose) { - os::print_date_and_time(st); + os::print_date_and_time(st, buf, sizeof(buf)); st->cr(); } -- GitLab