8233790: Forward output from heap dumper to jcmd/jmap
authorrschmelter
Mon, 11 Nov 2019 12:06:22 +0100
changeset 59006 d3f1cb09b704
parent 59005 01d47d511f5f
child 59008 333c2b653434
8233790: Forward output from heap dumper to jcmd/jmap Reviewed-by: stuefe, sspitsyn, cjplummer
src/hotspot/share/services/attachListener.cpp
src/hotspot/share/services/diagnosticCommand.cpp
src/hotspot/share/services/heapDumper.cpp
src/hotspot/share/services/heapDumper.hpp
--- a/src/hotspot/share/services/attachListener.cpp	Mon Nov 11 11:25:15 2019 +0100
+++ b/src/hotspot/share/services/attachListener.cpp	Mon Nov 11 12:06:22 2019 +0100
@@ -237,19 +237,7 @@
     // This helps reduces the amount of unreachable objects in the dump
     // and makes it easier to browse.
     HeapDumper dumper(live_objects_only /* request GC */);
-    int res = dumper.dump(op->arg(0));
-    if (res == 0) {
-      out->print_cr("Heap dump file created");
-    } else {
-      // heap dump failed
-      ResourceMark rm;
-      char* error = dumper.error_as_C_string();
-      if (error == NULL) {
-        out->print_cr("Dump failed - reason unknown");
-      } else {
-        out->print_cr("%s", error);
-      }
-    }
+    dumper.dump(op->arg(0), out);
   }
   return JNI_OK;
 }
--- a/src/hotspot/share/services/diagnosticCommand.cpp	Mon Nov 11 11:25:15 2019 +0100
+++ b/src/hotspot/share/services/diagnosticCommand.cpp	Mon Nov 11 12:06:22 2019 +0100
@@ -516,19 +516,7 @@
   // This helps reduces the amount of unreachable objects in the dump
   // and makes it easier to browse.
   HeapDumper dumper(!_all.value() /* request GC if _all is false*/);
-  int res = dumper.dump(_filename.value());
-  if (res == 0) {
-    output()->print_cr("Heap dump file created");
-  } else {
-    // heap dump failed
-    ResourceMark rm;
-    char* error = dumper.error_as_C_string();
-    if (error == NULL) {
-      output()->print_cr("Dump failed - reason unknown");
-    } else {
-      output()->print_cr("%s", error);
-    }
-  }
+  dumper.dump(_filename.value(), output());
 }
 
 int HeapDumpDCmd::num_arguments() {
--- a/src/hotspot/share/services/heapDumper.cpp	Mon Nov 11 11:25:15 2019 +0100
+++ b/src/hotspot/share/services/heapDumper.cpp	Mon Nov 11 12:06:22 2019 +0100
@@ -1969,12 +1969,12 @@
 }
 
 // dump the heap to given path.
-int HeapDumper::dump(const char* path) {
+int HeapDumper::dump(const char* path, outputStream* out) {
   assert(path != NULL && strlen(path) > 0, "path missing");
 
   // print message in interactive case
-  if (print_to_tty()) {
-    tty->print_cr("Dumping heap to %s ...", path);
+  if (out != NULL) {
+    out->print_cr("Dumping heap to %s ...", path);
     timer()->start();
   }
 
@@ -1982,8 +1982,8 @@
   DumpWriter writer(path);
   if (!writer.is_open()) {
     set_error(writer.error());
-    if (print_to_tty()) {
-      tty->print_cr("Unable to create %s: %s", path,
+    if (out != NULL) {
+      out->print_cr("Unable to create %s: %s", path,
         (error() != NULL) ? error() : "reason unknown");
     }
     return -1;
@@ -2003,13 +2003,13 @@
   set_error(writer.error());
 
   // print message in interactive case
-  if (print_to_tty()) {
+  if (out != NULL) {
     timer()->stop();
     if (error() == NULL) {
-      tty->print_cr("Heap dump file created [" JULONG_FORMAT " bytes in %3.3f secs]",
+      out->print_cr("Heap dump file created [" JULONG_FORMAT " bytes in %3.3f secs]",
                     writer.bytes_written(), timer()->seconds());
     } else {
-      tty->print_cr("Dump file is incomplete: %s", writer.error());
+      out->print_cr("Dump file is incomplete: %s", writer.error());
     }
   }
 
@@ -2137,8 +2137,7 @@
   dump_file_seq++;   // increment seq number for next time we dump
 
   HeapDumper dumper(false /* no GC before heap dump */,
-                    true  /* send to tty */,
                     oome  /* pass along out-of-memory-error flag */);
-  dumper.dump(my_path);
+  dumper.dump(my_path, tty);
   os::free(my_path);
 }
--- a/src/hotspot/share/services/heapDumper.hpp	Mon Nov 11 11:25:15 2019 +0100
+++ b/src/hotspot/share/services/heapDumper.hpp	Mon Nov 11 12:06:22 2019 +0100
@@ -41,24 +41,22 @@
 //  }
 //
 
+class outputStream;
+
 class HeapDumper : public StackObj {
  private:
   char* _error;
-  bool _print_to_tty;
   bool _gc_before_heap_dump;
   bool _oome;
   elapsedTimer _t;
 
-  HeapDumper(bool gc_before_heap_dump, bool print_to_tty, bool oome) :
-    _error(NULL), _print_to_tty(print_to_tty), _gc_before_heap_dump(gc_before_heap_dump), _oome(oome) { }
+  HeapDumper(bool gc_before_heap_dump, bool oome) :
+    _error(NULL), _gc_before_heap_dump(gc_before_heap_dump), _oome(oome) { }
 
   // string representation of error
   char* error() const                   { return _error; }
   void set_error(char* error);
 
-  // indicates if progress messages can be sent to tty
-  bool print_to_tty() const             { return _print_to_tty; }
-
   // internal timer.
   elapsedTimer* timer()                 { return &_t; }
 
@@ -66,12 +64,13 @@
 
  public:
   HeapDumper(bool gc_before_heap_dump) :
-    _error(NULL), _print_to_tty(false), _gc_before_heap_dump(gc_before_heap_dump), _oome(false) { }
+    _error(NULL), _gc_before_heap_dump(gc_before_heap_dump), _oome(false) { }
 
   ~HeapDumper();
 
   // dumps the heap to the specified file, returns 0 if success.
-  int dump(const char* path);
+  // additional info is written to out if not NULL.
+  int dump(const char* path, outputStream* out = NULL);
 
   // returns error message (resource allocated), or NULL if no error
   char* error_as_C_string() const;