8227031: Print NMT statistics on fatal errors
authorstuefe
Thu, 11 Jul 2019 06:49:49 +0200
changeset 55652 2d1acda7555a
parent 55651 45fc36beb0aa
child 55653 3243c42d737d
8227031: Print NMT statistics on fatal errors Reviewed-by: mbaesken, mdoerr
src/hotspot/share/services/memTracker.cpp
src/hotspot/share/services/memTracker.hpp
src/hotspot/share/utilities/vmError.cpp
--- a/src/hotspot/share/services/memTracker.cpp	Wed Jul 10 16:23:59 2019 -0700
+++ b/src/hotspot/share/services/memTracker.cpp	Thu Jul 11 06:49:49 2019 +0200
@@ -175,6 +175,22 @@
   return true;
 }
 
+
+static volatile bool g_final_report_did_run = false;
+void MemTracker::final_report(outputStream* output) {
+  // This function is called during both error reporting and normal VM exit.
+  // However, it should only ever run once.  E.g. if the VM crashes after
+  // printing the final report during normal VM exit, it should not print
+  // the final report again. In addition, it should be guarded from
+  // recursive calls in case NMT reporting itself crashes.
+  if (Atomic::cmpxchg(true, &g_final_report_did_run, false) == false) {
+    NMT_TrackingLevel level = tracking_level();
+    if (level >= NMT_summary) {
+      report(level == NMT_summary, output);
+    }
+  }
+}
+
 void MemTracker::report(bool summary_only, outputStream* output) {
  assert(output != NULL, "No output stream");
   MemBaseline baseline;
@@ -186,12 +202,9 @@
       MemDetailReporter rpt(baseline, output);
       rpt.report();
       output->print("Metaspace:");
-      // Metadata reporting requires a safepoint, so avoid it if VM is not in good state.
-      assert(!VMError::fatal_error_in_progress(), "Do not report metadata in error report");
-      VM_PrintMetadata vmop(output, K,
-          MetaspaceUtils::rf_show_loaders |
-          MetaspaceUtils::rf_break_down_by_spacetype);
-      VMThread::execute(&vmop);
+      // The basic metaspace report avoids any locking and should be safe to
+      // be called at any time.
+      MetaspaceUtils::print_basic_report(output, K);
     }
   }
 }
--- a/src/hotspot/share/services/memTracker.hpp	Wed Jul 10 16:23:59 2019 -0700
+++ b/src/hotspot/share/services/memTracker.hpp	Thu Jul 11 06:49:49 2019 +0200
@@ -271,13 +271,7 @@
     }
    }
 
-  static void final_report(outputStream* output) {
-    NMT_TrackingLevel level = tracking_level();
-    if (level >= NMT_summary) {
-      report(level == NMT_summary, output);
-    }
-  }
-
+  static void final_report(outputStream* output);
 
   // Stored baseline
   static inline MemBaseline& get_baseline() {
--- a/src/hotspot/share/utilities/vmError.cpp	Wed Jul 10 16:23:59 2019 -0700
+++ b/src/hotspot/share/utilities/vmError.cpp	Thu Jul 11 06:49:49 2019 +0200
@@ -1523,6 +1523,11 @@
     log.set_fd(-1);
   }
 
+  if (PrintNMTStatistics) {
+    fdStream fds(fd_out);
+    MemTracker::final_report(&fds);
+  }
+
   static bool skip_replay = ReplayCompiles; // Do not overwrite file during replay
   if (DumpReplayDataOnError && _thread && _thread->is_Compiler_thread() && !skip_replay) {
     skip_replay = true;