8035074: hs_err improvement: Add time zone information in the hs_err file
authorcoleenp
Tue, 09 Jun 2015 10:26:25 -0400
changeset 31335 60081f497e75
parent 31334 d55c96b36b5f
child 31337 98b10897ee17
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: ctornqvi, dholmes
hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
hotspot/src/share/vm/memory/metaspace.cpp
hotspot/src/share/vm/memory/metaspace.hpp
hotspot/src/share/vm/memory/universe.cpp
hotspot/src/share/vm/memory/universe.hpp
hotspot/src/share/vm/runtime/os.cpp
hotspot/src/share/vm/runtime/os.hpp
hotspot/src/share/vm/runtime/sharedRuntime.cpp
hotspot/src/share/vm/utilities/exceptions.cpp
hotspot/src/share/vm/utilities/exceptions.hpp
hotspot/src/share/vm/utilities/vmError.cpp
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Mon Jun 08 15:40:28 2015 +0200
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Tue Jun 09 10:26:25 2015 -0400
@@ -309,6 +309,8 @@
   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
 
--- a/hotspot/src/share/vm/memory/metaspace.cpp	Mon Jun 08 15:40:28 2015 +0200
+++ b/hotspot/src/share/vm/memory/metaspace.cpp	Tue Jun 09 10:26:25 2015 -0400
@@ -3132,10 +3132,21 @@
   initialize_class_space(metaspace_rs);
 
   if (PrintCompressedOopsMode || (PrintMiscellaneous && Verbose)) {
-    gclog_or_tty->print_cr("Narrow klass base: " PTR_FORMAT ", Narrow klass shift: %d",
-                            p2i(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(), p2i(metaspace_rs.base()), p2i(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();
   }
 }
 
--- a/hotspot/src/share/vm/memory/metaspace.hpp	Mon Jun 08 15:40:28 2015 +0200
+++ b/hotspot/src/share/vm/memory/metaspace.hpp	Tue Jun 09 10:26:25 2015 -0400
@@ -254,6 +254,8 @@
   // 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;
--- a/hotspot/src/share/vm/memory/universe.cpp	Mon Jun 08 15:40:28 2015 +0200
+++ b/hotspot/src/share/vm/memory/universe.cpp	Tue Jun 09 10:26:25 2015 -0400
@@ -754,7 +754,7 @@
     Universe::set_narrow_ptrs_base(Universe::narrow_oop_base());
 
     if (PrintCompressedOopsMode || (PrintMiscellaneous && Verbose)) {
-      Universe::print_compressed_oops_mode();
+      Universe::print_compressed_oops_mode(tty);
     }
 
     // Tell tests in which mode we run.
@@ -781,27 +781,24 @@
   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",
               p2i(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, p2i(Universe::narrow_oop_base()));
+    st->print(": " PTR_FORMAT, p2i(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());
   }
 
   if (!Universe::narrow_oop_use_implicit_null_checks()) {
-    tty->print(", no protected page in front of the heap");
+    st->print(", no protected page in front of the heap");
   }
-
-  tty->cr();
-  tty->cr();
+  st->cr();
 }
 
 ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
--- a/hotspot/src/share/vm/memory/universe.hpp	Mon Jun 08 15:40:28 2015 +0200
+++ b/hotspot/src/share/vm/memory/universe.hpp	Tue Jun 09 10:26:25 2015 -0400
@@ -398,7 +398,7 @@
   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)         {
--- a/hotspot/src/share/vm/runtime/os.cpp	Mon Jun 08 15:40:28 2015 +0200
+++ b/hotspot/src/share/vm/runtime/os.cpp	Tue Jun 09 10:26:25 2015 -0400
@@ -843,7 +843,7 @@
   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;
@@ -852,6 +852,12 @@
   (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
--- a/hotspot/src/share/vm/runtime/os.hpp	Mon Jun 08 15:40:28 2015 +0200
+++ b/hotspot/src/share/vm/runtime/os.hpp	Tue Jun 09 10:26:25 2015 -0400
@@ -596,7 +596,7 @@
   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);
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Mon Jun 08 15:40:28 2015 +0200
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Tue Jun 09 10:26:25 2015 -0400
@@ -732,6 +732,8 @@
   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
 
--- a/hotspot/src/share/vm/utilities/exceptions.cpp	Mon Jun 08 15:40:28 2015 +0200
+++ b/hotspot/src/share/vm/utilities/exceptions.cpp	Tue Jun 09 10:26:25 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, 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 @@
     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 @@
     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 @@
                                    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) {
--- a/hotspot/src/share/vm/utilities/exceptions.hpp	Mon Jun 08 15:40:28 2015 +0200
+++ b/hotspot/src/share/vm/utilities/exceptions.hpp	Tue Jun 09 10:26:25 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, 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 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 @@
 
   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);)
--- a/hotspot/src/share/vm/utilities/vmError.cpp	Mon Jun 08 15:40:28 2015 +0200
+++ b/hotspot/src/share/vm/utilities/vmError.cpp	Tue Jun 09 10:26:25 2015 -0400
@@ -714,6 +714,24 @@
        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()) {
@@ -819,7 +837,7 @@
   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();
      }