8294151: JFR: Unclear exception message when dumping stopped in memory recording

Reviewed-by: mgronlun
This commit is contained in:
Erik Gahlin 2022-10-05 11:49:53 +00:00
parent 8ebebbce32
commit 13a5000d48
4 changed files with 47 additions and 10 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. 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
@ -348,7 +348,7 @@ public final class Recording implements Closeable {
/**
* Returns a clone of this recording, with a new recording ID and name.
*
* <p>
* Clones are useful for dumping data without stopping the recording. After
* a clone is created, the amount of data to copy is constrained
* with the {@link #setMaxAge(Duration)} method and the {@link #setMaxSize(long)}method.
@ -364,21 +364,26 @@ public final class Recording implements Closeable {
/**
* Writes recording data to a file.
* <p>
* Recording must be started, but not necessarily stopped.
* For a dump to succeed, the recording must either be 1) running, or 2) stopped
* and to disk. If the recording is in any other state, an
* {@link IOException} is thrown.
*
* @param destination the location where recording data is written, not
* {@code null}
*
* @throws IOException if the recording can't be copied to the specified
* location
* @throws IOException if recording data can't be copied to the specified
* location, for example, if the recording is closed or the
* destination path is not writable
*
* @throws SecurityException if a security manager exists and the caller doesn't
* have {@code FilePermission} to write to the destination path
*
* @see #getState()
* @see #isToDisk()
*/
public void dump(Path destination) throws IOException {
Objects.requireNonNull(destination, "destination");
internal.dump(new WriteableUserPath(destination));
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. 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
@ -321,7 +321,12 @@ public final class PlatformRecording implements AutoCloseable {
if (state == RecordingState.DELAYED || state == RecordingState.NEW) {
throw new IOException("Recording \"" + name + "\" (id=" + id + ") has not started, no content to write");
}
if (state == RecordingState.STOPPED) {
if (!isToDisk()) {
throw new IOException("Recording \"" + name + "\" (id=" + id + ")"
+ " is an in memory recording. No data to copy after it has been stopped.");
}
PlatformRecording clone = recorder.newTemporaryRecording();
for (RepositoryChunk r : chunks) {
clone.add(r);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. 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
@ -136,7 +136,11 @@ public final class WriteableUserPath {
} catch (Throwable t) {
// prevent malicious user to propagate exception callback
// in the wrong context
throw new IOException("Unexpected error during I/O operation");
Throwable cause = null;
if (System.getSecurityManager() == null) {
cause = t;
}
throw new IOException("Unexpected error during I/O operation", cause);
} finally {
inPrivileged = false;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. 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
@ -29,6 +29,8 @@ import jdk.test.lib.Asserts;
import jdk.test.lib.jfr.Events;
import jdk.test.lib.jfr.SimpleEvent;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.List;
/**
@ -82,6 +84,27 @@ public class TestRecordingCopy {
runningCopy.stop();
runningCopy.close();
stoppedCopy.close();
testMemoryCopy();
}
private static void testMemoryCopy() throws Exception {
try (Recording memory = new Recording()) {
memory.setToDisk(false);
memory.enable(SimpleEvent.class);
memory.start();
Recording unstopped = memory.copy(false);
unstopped.dump(Paths.get("unstopped-memory.jfr"));
Recording stopped = memory.copy(true);
try {
stopped.dump(Paths.get("stopped-memory.jfr"));
throw new Exception("Should not be able to dump stopped in memory recording");
} catch (IOException ioe) {
// As expected
}
}
}
/**