Skip to content

Commit

Permalink
SapMachine #1670: jcmd GC.heap_dump without options should write to l…
Browse files Browse the repository at this point in the history
…ocation given by -XX:HeapDumpPath, if set
  • Loading branch information
MBaesken authored and RealCLanger committed Jun 20, 2024
1 parent 16c51e0 commit 8741e34
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 13 deletions.
8 changes: 5 additions & 3 deletions src/hotspot/share/runtime/globals.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -693,10 +693,12 @@ const int ObjectAlignmentInBytes = 8;
"Dump heap to file when java.lang.OutOfMemoryError is thrown " \
"from JVM") \
\
/* SapMachine 2024-05-10: HeapDumpPath for jcmd */ \
product(ccstr, HeapDumpPath, nullptr, MANAGEABLE, \
"When HeapDumpOnOutOfMemoryError is on, the path (filename or " \
"directory) of the dump file (defaults to java_pid<pid>.hprof " \
"in the working directory)") \
"When HeapDumpOnOutOfMemoryError is on, or a heap dump is " \
"triggered by jcmd GC.heap_dump without specifying a path, " \
"the path (filename or directory) of the dump file. " \
"(defaults to java_pid<pid>.hprof in the working directory)") \
\
product(intx, HeapDumpGzipLevel, 0, MANAGEABLE, \
"When HeapDumpOnOutOfMemoryError is on, the gzip compression " \
Expand Down
25 changes: 22 additions & 3 deletions src/hotspot/share/services/diagnosticCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,8 @@ void FinalizerInfoDCmd::execute(DCmdSource source, TRAPS) {
#if INCLUDE_SERVICES // Heap dumping/inspection supported
HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) :
DCmdWithParser(output, heap),
_filename("filename","Name of the dump file", "STRING",true),
// SapMachine 2024-05-10: HeapDumpPath for jcmd
_filename("filename", "Name of the dump file", "STRING", false, "if no filename was specified, but -XX:HeapDumpPath=<hdp> is set, path <hdp> is taken"),
_all("-all", "Dump all objects, including unreachable objects",
"BOOLEAN", false, "false"),
_gzip("-gz", "If specified, the heap dump is written in gzipped format "
Expand All @@ -499,6 +500,8 @@ HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) :

void HeapDumpDCmd::execute(DCmdSource source, TRAPS) {
jlong level = -1; // -1 means no compression.
// SapMachine 2024-05-10: HeapDumpPath for jcmd
bool use_heapdump_path = false;

if (_gzip.is_set()) {
level = _gzip.value();
Expand All @@ -509,11 +512,27 @@ void HeapDumpDCmd::execute(DCmdSource source, TRAPS) {
}
}

// SapMachine 2024-05-10: HeapDumpPath for jcmd
if (!_filename.is_set()) {
if (HeapDumpPath != nullptr) {
// use HeapDumpPath (file or directory is possible)
use_heapdump_path = true;
} else {
output()->print_cr("Filename or -XX:HeapDumpPath must be set!");
return;
}
}

// Request a full GC before heap dump if _all is false
// 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*/);
dumper.dump(_filename.value(), output(), (int) level, _overwrite.value());
// SapMachine 2024-05-10: HeapDumpPath for jcmd
if (use_heapdump_path) {
HeapDumper::dump_heap(!_all.value(), output(), (int) level, _overwrite.value());
} else {
HeapDumper dumper(!_all.value() /* request GC if _all is false*/);
dumper.dump(_filename.value(), output(), (int) level, _overwrite.value());
}
}

ClassHistogramDCmd::ClassHistogramDCmd(outputStream* output, bool heap) :
Expand Down
24 changes: 18 additions & 6 deletions src/hotspot/share/services/heapDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2605,7 +2605,8 @@ void HeapDumper::set_error(char const* error) {
// Called by out-of-memory error reporting by a single Java thread
// outside of a JVM safepoint
void HeapDumper::dump_heap_from_oome() {
HeapDumper::dump_heap(true);
// SapMachine 2024-05-10: HeapDumpPath for jcmd
HeapDumper::dump_heap(false, true);
}

// Called by error reporting by a single Java thread outside of a JVM safepoint,
Expand All @@ -2614,17 +2615,26 @@ void HeapDumper::dump_heap_from_oome() {
// general use, however, this method will need modification to prevent
// inteference when updating the static variables base_path and dump_file_seq below.
void HeapDumper::dump_heap() {
HeapDumper::dump_heap(false);
// SapMachine 2024-05-10: HeapDumpPath for jcmd
HeapDumper::dump_heap(false, false);
}

void HeapDumper::dump_heap(bool oome) {
// SapMachine 2024-05-10: HeapDumpPath for jcmd
void HeapDumper::dump_heap(bool gc_before_heap_dump, outputStream* out, int compression, bool overwrite) {
HeapDumper::dump_heap(gc_before_heap_dump, false, out, compression, overwrite);
}

// SapMachine 2024-05-10: HeapDumpPath for jcmd
void HeapDumper::dump_heap(bool gc_before_heap_dump, bool oome, outputStream* out, int compression, bool overwrite) {
static char base_path[JVM_MAXPATHLEN] = {'\0'};
static uint dump_file_seq = 0;
char* my_path;
const int max_digit_chars = 20;

const char* dump_file_name = "java_pid";
const char* dump_file_ext = HeapDumpGzipLevel > 0 ? ".hprof.gz" : ".hprof";
// SapMachine 2024-05-10: HeapDumpPath for jcmd
const int ziplevel = compression < 0 ? HeapDumpGzipLevel : compression;
const char* dump_file_ext = ziplevel > 0 ? ".hprof.gz" : ".hprof";

// The dump file defaults to java_pid<pid>.hprof in the current working
// directory. HeapDumpPath=<file> can be used to specify an alternative
Expand Down Expand Up @@ -2689,8 +2699,10 @@ void HeapDumper::dump_heap(bool oome) {
}
dump_file_seq++; // increment seq number for next time we dump

HeapDumper dumper(false /* no GC before heap dump */,
// SapMachine 2024-05-10: HeapDumpPath for jcmd
HeapDumper dumper(gc_before_heap_dump /* GC before heap dump */,
oome /* pass along out-of-memory-error flag */);
dumper.dump(my_path, tty, HeapDumpGzipLevel);
// SapMachine 2024-05-10: HeapDumpPath for jcmd
dumper.dump(my_path, out, ziplevel, overwrite);
os::free(my_path);
}
7 changes: 6 additions & 1 deletion src/hotspot/share/services/heapDumper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ class HeapDumper : public StackObj {
// internal timer.
elapsedTimer* timer() { return &_t; }

static void dump_heap(bool oome);
// SapMachine 2024-05-10: HeapDumpPath for jcmd
static void dump_heap(bool gc_before_heap_dump, bool oome, outputStream* out = tty, int compression = -1, bool overwrite = false);

public:
HeapDumper(bool gc_before_heap_dump) :
Expand All @@ -80,6 +81,10 @@ class HeapDumper : public StackObj {
static void dump_heap() NOT_SERVICES_RETURN;

static void dump_heap_from_oome() NOT_SERVICES_RETURN;

// SapMachine 2024-05-10: HeapDumpPath for jcmd
static void dump_heap(bool gc_before_heap_dump, outputStream* out, int compression, bool overwrite) NOT_SERVICES_RETURN;

};

#endif // SHARE_SERVICES_HEAPDUMPER_HPP
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2024 SAP SE. 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

/**
* @test
* @summary Test jcmd GC.heap_dump without path option; path is set via HeapDumpPath
* @library /test/lib
* @run main/othervm -XX:HeapDumpPath=testjcmd.hprof HeapDumpJcmdPresetPathTest
*/

import java.io.File;

import jdk.test.lib.Asserts;
import jdk.test.lib.dcmd.PidJcmdExecutor;
import jdk.test.lib.process.OutputAnalyzer;

public class HeapDumpJcmdPresetPathTest {

public static void main(String[] args) throws Exception {
PidJcmdExecutor executor = new PidJcmdExecutor();
OutputAnalyzer output = executor.execute("GC.heap_dump");
output.shouldContain("Dumping heap to testjcmd.hprof");
output.shouldContain("Heap dump file created");

Asserts.assertTrue(new File("testjcmd.hprof").exists());
}
}

0 comments on commit 8741e34

Please sign in to comment.