# HG changeset patch # User rschmelter # Date 1573470382 -3600 # Node ID d3f1cb09b7045002c6a55f570d0f2a885d61b1ef # Parent 01d47d511f5f0017f7390642668fbe0a4495cba7 8233790: Forward output from heap dumper to jcmd/jmap Reviewed-by: stuefe, sspitsyn, cjplummer diff -r 01d47d511f5f -r d3f1cb09b704 src/hotspot/share/services/attachListener.cpp --- 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; } diff -r 01d47d511f5f -r d3f1cb09b704 src/hotspot/share/services/diagnosticCommand.cpp --- 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() { diff -r 01d47d511f5f -r d3f1cb09b704 src/hotspot/share/services/heapDumper.cpp --- 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); } diff -r 01d47d511f5f -r d3f1cb09b704 src/hotspot/share/services/heapDumper.hpp --- 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;