8233790: Forward output from heap dumper to jcmd/jmap
Reviewed-by: stuefe, sspitsyn, cjplummer
--- 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;