Skip to content
Permalink
Browse files
8267666: Add option to jcmd GC.heap_dump to use existing file
Reviewed-by: rschmelter, goetz, stuefe
Backport-of: 7cbb67a
  • Loading branch information
RealCLanger committed Jul 23, 2021
1 parent 63c4ec2 commit 6762216121699e1b8234cced6cd6410b5de92c09
Showing 9 changed files with 27 additions and 24 deletions.
@@ -3789,9 +3789,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);
}

@@ -3628,9 +3628,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);
}

@@ -5743,9 +5743,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);
}

@@ -4600,9 +4600,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);
}

@@ -506,17 +506,20 @@ HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) :
DCmdWithParser(output, heap),
_filename("filename","Name of the dump file", "STRING",true),
_all("-all", "Dump all objects, including unreachable objects",
"BOOLEAN", false, "false") {
"BOOLEAN", false, "false"),
_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(&_overwrite);
}

void HeapDumpDCmd::execute(DCmdSource source, TRAPS) {
// 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*/);
int res = dumper.dump(_filename.value());
int res = dumper.dump(_filename.value(), _overwrite.value());
if (res == 0) {
output()->print_cr("Heap dump file created");
} else {
@@ -331,6 +331,7 @@ class HeapDumpDCmd : public DCmdWithParser {
protected:
DCmdArgument<char*> _filename;
DCmdArgument<bool> _all;
DCmdArgument<bool> _overwrite;
public:
HeapDumpDCmd(outputStream* output, bool heap);
static const char* name() {
@@ -406,7 +406,7 @@ class DumpWriter : public StackObj {
void write_internal(void* s, size_t len);

public:
DumpWriter(const char* path);
DumpWriter(const char* path, bool overwrite);
~DumpWriter();

void close();
@@ -444,7 +444,7 @@ class DumpWriter : public StackObj {
void write_id(u4 x);
};

DumpWriter::DumpWriter(const char* path) {
DumpWriter::DumpWriter(const char* path, bool overwrite) {
// try to allocate an I/O buffer of io_buffer_size. If there isn't
// sufficient memory then reduce size until we can allocate something.
_size = io_buffer_size;
@@ -459,7 +459,7 @@ DumpWriter::DumpWriter(const char* path) {
_error = NULL;
_bytes_written = 0L;
_dump_start = (jlong)-1;
_fd = os::create_binary_file(path, false); // don't replace existing file
_fd = os::create_binary_file(path, overwrite);

// if the open failed we record the error
if (_fd < 0) {
@@ -1935,7 +1935,7 @@ void VM_HeapDumper::dump_stack_traces() {
}

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

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

// create the dump writer. If the file can be opened then bail
DumpWriter writer(path);
DumpWriter writer(path, overwrite);
if (!writer.is_open()) {
set_error(writer.error());
if (print_to_tty()) {
@@ -71,7 +71,7 @@ class HeapDumper : public StackObj {
~HeapDumper();

// dumps the heap to the specified file, returns 0 if success.
int dump(const char* path);
int dump(const char* path, bool overwrite = false);

// returns error message (resource allocated), or NULL if no error
char* error_as_C_string() const;
@@ -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 6762216

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 6762216 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.