8385110: JFR: Race when accessing Recording::getSettings()

Reviewed-by: mgronlun
This commit is contained in:
Erik Gahlin 2026-05-21 15:02:28 +00:00
parent dc677e9517
commit 0a9e343d03
4 changed files with 12 additions and 8 deletions

View File

@ -222,7 +222,7 @@ public final class Recording implements Closeable {
* @return recording settings, not {@code null}
*/
public Map<String, String> getSettings() {
return new HashMap<>(internal.getSettings());
return internal.getSettingsCopy();
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, 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
@ -25,7 +25,6 @@
package jdk.jfr.internal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -92,7 +91,7 @@ public final class OldObjectSample {
}
public static Map<String, String> createSettingsForSnapshot(PlatformRecording recording, Boolean pathToGcRoots) {
Map<String, String> settings = new HashMap<>(recording.getSettings());
Map<String, String> settings = recording.getSettingsCopy();
updateSettingPathToGcRoots(settings, pathToGcRoots);
return settings;
}

View File

@ -585,7 +585,7 @@ public final class PlatformRecorder {
boolean register = !isDestroyed() && r.getState() != RecordingState.CLOSED;
Recording newRec = access.newRecording(register);
PlatformRecording copy = access.getPlatformRecording(newRec);
copy.setSettings(r.getSettings());
copy.setSettings(r.getSettingsCopy());
copy.setMaxAge(r.getMaxAge());
copy.setMaxSize(r.getMaxSize());
copy.setDumpOnExit(r.getDumpOnExit());

View File

@ -253,9 +253,14 @@ public final class PlatformRecording implements AutoCloseable {
}
}
public Map<String, String> getSettings() {
Map<String, String> getSettings() {
assert Thread.holdsLock(recorder) : "Must have recorder lock when accessing recorder.settings";
return settings;
}
public Map<String, String> getSettingsCopy() {
synchronized (recorder) {
return settings;
return new LinkedHashMap<>(settings);
}
}
@ -371,7 +376,7 @@ public final class PlatformRecording implements AutoCloseable {
clone.setStartTime(getStartTime());
}
if (pathToGcRoots == null) {
clone.setSettings(getSettings()); // needed for old object sample
clone.setSettings(getSettingsCopy()); // needed for old object sample
clone.stop(reason); // dumps to destination path here
} else {
// Risk of violating lock order here, since