Skip to content
Permalink
Browse files
8267666: Add option to jcmd GC.heap_dump to use existing file
Backport-of: 7cbb67a3f8adc83a5b51c092a66480d7b22a6bea
  • Loading branch information
RealCLanger committed Jul 23, 2021
1 parent de786bb commit 9b6aa5304c4768b1200cd1f0990fee4d0e9a2600
Showing 11 changed files with 27 additions and 23 deletions.
@@ -2665,9 +2665,7 @@ int os::open(const char *path, int oflag, int mode) {
// create binary file, rewriting existing file if required
int os::create_binary_file(const char* path, bool rewrite_existing) {
int oflags = O_WRONLY | O_CREAT;
if (!rewrite_existing) {
oflags |= O_EXCL;
}
oflags |= rewrite_existing ? O_TRUNC : O_EXCL;
return ::open64(path, oflags, S_IREAD | S_IWRITE);
}

@@ -2355,9 +2355,7 @@ int os::open(const char *path, int oflag, int mode) {
// create binary file, rewriting existing file if required
int os::create_binary_file(const char* path, bool rewrite_existing) {
int oflags = O_WRONLY | O_CREAT;
if (!rewrite_existing) {
oflags |= O_EXCL;
}
oflags |= rewrite_existing ? O_TRUNC : O_EXCL;
return ::open(path, oflags, S_IREAD | S_IWRITE);
}

@@ -4968,9 +4968,7 @@ int os::open(const char *path, int oflag, int mode) {
// create binary file, rewriting existing file if required
int os::create_binary_file(const char* path, bool rewrite_existing) {
int oflags = O_WRONLY | O_CREAT;
if (!rewrite_existing) {
oflags |= O_EXCL;
}
oflags |= rewrite_existing ? O_TRUNC : O_EXCL;
return ::open64(path, oflags, S_IREAD | S_IWRITE);
}

@@ -4732,9 +4732,7 @@ bool os::dir_is_empty(const char* path) {
// create binary file, rewriting existing file if required
int os::create_binary_file(const char* path, bool rewrite_existing) {
int oflags = _O_CREAT | _O_WRONLY | _O_BINARY;
if (!rewrite_existing) {
oflags |= _O_EXCL;
}
oflags |= rewrite_existing ? _O_TRUNC : _O_EXCL;
return ::open(path, oflags, _S_IREAD | _S_IWRITE);
}

@@ -468,10 +468,13 @@ HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) :
"BOOLEAN", false, "false"),
_gzip("-gz", "If specified, the heap dump is written in gzipped format "
"using the given compression level. 1 (recommended) is the fastest, "
"9 the strongest compression.", "INT", false, "1") {
"9 the strongest compression.", "INT", false, "1"),
_overwrite("-overwrite", "If specified, the dump file will be overwritten if it exists",
"BOOLEAN", false, "false") {
_dcmdparser.add_dcmd_option(&_all);
_dcmdparser.add_dcmd_argument(&_filename);
_dcmdparser.add_dcmd_option(&_gzip);
_dcmdparser.add_dcmd_option(&_overwrite);
}

void HeapDumpDCmd::execute(DCmdSource source, TRAPS) {
@@ -490,7 +493,7 @@ void HeapDumpDCmd::execute(DCmdSource source, TRAPS) {
// 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);
dumper.dump(_filename.value(), output(), (int) level, _overwrite.value());
}

ClassHistogramDCmd::ClassHistogramDCmd(outputStream* output, bool heap) :
@@ -314,6 +314,7 @@ class HeapDumpDCmd : public DCmdWithParser {
DCmdArgument<char*> _filename;
DCmdArgument<bool> _all;
DCmdArgument<jlong> _gzip;
DCmdArgument<bool> _overwrite;
public:
HeapDumpDCmd(outputStream* output, bool heap);
static const char* name() {
@@ -1905,7 +1905,7 @@ void VM_HeapDumper::dump_stack_traces() {
}

// dump the heap to given path.
int HeapDumper::dump(const char* path, outputStream* out, int compression) {
int HeapDumper::dump(const char* path, outputStream* out, int compression, bool overwrite) {
assert(path != NULL && strlen(path) > 0, "path missing");

// print message in interactive case
@@ -1928,7 +1928,7 @@ int HeapDumper::dump(const char* path, outputStream* out, int compression) {
}
}

DumpWriter writer(new (std::nothrow) FileWriter(path), compressor);
DumpWriter writer(new (std::nothrow) FileWriter(path, overwrite), compressor);

if (writer.error() != NULL) {
set_error(writer.error());
@@ -71,7 +71,7 @@ class HeapDumper : public StackObj {
// dumps the heap to the specified file, returns 0 if success.
// additional info is written to out if not NULL.
// compression >= 0 creates a gzipped file with the given compression level.
int dump(const char* path, outputStream* out = NULL, int compression = -1);
int dump(const char* path, outputStream* out = NULL, int compression = -1, bool overwrite = false);

// returns error message (resource allocated), or NULL if no error
char* error_as_C_string() const;
@@ -34,7 +34,7 @@
char const* FileWriter::open_writer() {
assert(_fd < 0, "Must not already be open");

_fd = os::create_binary_file(_path, false); // don't replace existing file
_fd = os::create_binary_file(_path, _overwrite);

if (_fd < 0) {
return os::strerror(errno);
@@ -61,10 +61,11 @@ class AbstractWriter : public CHeapObj<mtInternal> {
class FileWriter : public AbstractWriter {
private:
char const* _path;
bool _overwrite;
int _fd;

public:
FileWriter(char const* path) : _path(path), _fd(-1) { }
FileWriter(char const* path, bool overwrite) : _path(path), _overwrite(overwrite), _fd(-1) { }

~FileWriter();

@@ -50,13 +50,15 @@
public class HeapDumpTest {
protected String heapDumpArgs = "";

public void run(CommandExecutor executor) throws IOException {
public void run(CommandExecutor executor, boolean overwrite) throws IOException {
File dump = new File("jcmd.gc.heap_dump." + System.currentTimeMillis() + ".hprof");
if (dump.exists()) {
if (!overwrite && dump.exists()) {
dump.delete();
} else if (overwrite) {
dump.createNewFile();
}

String cmd = "GC.heap_dump " + heapDumpArgs + " " + dump.getAbsolutePath();
String cmd = "GC.heap_dump " + (overwrite ? "-overwrite " : "") + heapDumpArgs + " " + dump.getAbsolutePath();
executor.execute(cmd);

verifyHeapDump(dump);
@@ -85,7 +87,12 @@ private void verifyHeapDump(File dump) {
/* GC.heap_dump is not available over JMX, running jcmd pid executor instead */
@Test
public void pid() throws IOException {
run(new PidJcmdExecutor());
run(new PidJcmdExecutor(), false);
}

@Test
public void pidRewrite() throws IOException {
run(new PidJcmdExecutor(), true);
}
}

1 comment on commit 9b6aa53

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 9b6aa53 Jul 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.