Skip to content

Commit f3885f4

Browse files
authored
Merge pull request #21071 from tajila/jfr
Prevent doube stop of JFR recording
2 parents 6410fb4 + 2cdab8d commit f3885f4

File tree

5 files changed

+109
-11
lines changed

5 files changed

+109
-11
lines changed

jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/DiagnosticUtils.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,9 @@ private static DiagnosticProperties doJFR(String diagnosticCommand) {
484484
Timer timer = new Timer();
485485
TimerTask jfrDumpTask = new TimerTask() {
486486
public void run() {
487-
VM.stopJFR();
487+
if (VM.isJFRRecordingStarted()) {
488+
VM.stopJFR();
489+
}
488490
}
489491
};
490492
timer.schedule(jfrDumpTask, duration);

runtime/jcl/common/com_ibm_oti_vm_VM.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,10 @@ Java_com_ibm_oti_vm_VM_startJFR(JNIEnv *env, jclass unused)
255255
J9JavaVM *vm = currentThread->javaVM;
256256
J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;
257257

258-
/* this is to initalize JFR late after VM startup */
259-
rc = vmFuncs->initializeJFR(vm, TRUE);
258+
if (!vmFuncs->isJFRRecordingStarted(vm)) {
259+
/* this is to initalize JFR late after VM startup */
260+
rc = vmFuncs->initializeJFR(vm, TRUE);
261+
}
260262

261263
return rc;
262264
}
@@ -268,12 +270,14 @@ Java_com_ibm_oti_vm_VM_stopJFR(JNIEnv *env, jclass unused)
268270
J9JavaVM *vm = currentThread->javaVM;
269271
J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;
270272

271-
vmFuncs->internalEnterVMFromJNI(currentThread);
272-
vmFuncs->acquireExclusiveVMAccess(currentThread);
273-
vmFuncs->jfrDump(currentThread, TRUE);
274-
vmFuncs->releaseExclusiveVMAccess(currentThread);
275-
vmFuncs->tearDownJFR(vm);
276-
vmFuncs->internalExitVMToJNI(currentThread);
273+
if (vmFuncs->isJFRRecordingStarted(vm)) {
274+
vmFuncs->internalEnterVMFromJNI(currentThread);
275+
vmFuncs->acquireExclusiveVMAccess(currentThread);
276+
vmFuncs->jfrDump(currentThread, TRUE);
277+
vmFuncs->releaseExclusiveVMAccess(currentThread);
278+
vmFuncs->tearDownJFR(vm);
279+
vmFuncs->internalExitVMToJNI(currentThread);
280+
}
277281
}
278282

279283
void JNICALL

test/functional/cmdLineTests/jfr/jfr.xml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex
2424

2525
<!DOCTYPE suite SYSTEM "cmdlinetester.dtd">
2626

27-
<suite id="JFR Tests" timeout="1800">
27+
<suite id="JFR Tests" timeout="2400">
2828
<envvar name="OPENJ9_METADATA_BLOB_FILE_PATH" value="$METADATA_BLOB_PATH$" />
2929
<test id="triggerExecutionSample">
3030
<command>$EXE$ -XX:StartFlightRecording --add-exports java.base/com.ibm.oti.vm=ALL-UNNAMED -cp $RESJAR$ org.openj9.test.TriggerExecutionSample</command>
@@ -45,6 +45,16 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex
4545
<output type="success" caseSensitive="yes" regex="no">All runs complete.</output>
4646
<output type="failure" caseSensitive="yes" regex="no">Failed</output>
4747
</test>
48+
<test id="VM API Test aggressive start and stop - approx 2mins">
49+
<command>$EXE$ --add-exports java.base/com.ibm.oti.vm=ALL-UNNAMED -cp $RESJAR$ org.openj9.test.VMAPITest 1</command>
50+
<output type="success" caseSensitive="yes" regex="no">All runs complete.</output>
51+
<output type="failure" caseSensitive="yes" regex="no">Failed</output>
52+
</test>
53+
<test id="VM API Test2 - approx 2mins">
54+
<command>$EXE$ --add-exports java.base/com.ibm.oti.vm=ALL-UNNAMED -cp $RESJAR$ org.openj9.test.VMAPITest2</command>
55+
<output type="success" caseSensitive="yes" regex="no">All runs complete.</output>
56+
<output type="failure" caseSensitive="yes" regex="no">Failed</output>
57+
</test>
4858
<test id="Test JFR enablement 1">
4959
<command>$EXE$ --add-exports java.base/com.ibm.oti.vm=ALL-UNNAMED -cp $RESJAR$ org.openj9.test.JFRCMDLineTest</command>
5060
<output type="required" caseSensitive="yes" regex="no">All runs complete</output>

test/functional/cmdLineTests/jfr/src/org/openj9/test/VMAPITest.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@
2626
public class VMAPITest {
2727
public static void main(String[] args) throws Throwable {
2828
final WorkLoad workLoad = new WorkLoad(200, 20000, 200);
29+
int sleepDuration = 1000;
30+
31+
if (args.length > 1) {
32+
sleepDuration = Integer.parseInt(args[0]);
33+
}
2934

3035
if (VM.isJFRRecordingStarted()) {
3136
System.out.println("Failed should not be recording.");
@@ -55,7 +60,7 @@ public static void main(String[] args) throws Throwable {
5560
return;
5661
}
5762

58-
Thread.sleep(1000);
63+
Thread.sleep(sleepDuration);
5964
VM.jfrDump();
6065
VM.stopJFR();
6166

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright IBM Corp. and others 2024
3+
*
4+
* This program and the accompanying materials are made available under
5+
* the terms of the Eclipse Public License 2.0 which accompanies this
6+
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7+
* or the Apache License, Version 2.0 which accompanies this distribution and
8+
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9+
*
10+
* This Source Code may also be made available under the following
11+
* Secondary Licenses when the conditions for such availability set
12+
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13+
* General Public License, version 2 with the GNU Classpath
14+
* Exception [1] and GNU General Public License, version 2 with the
15+
* OpenJDK Assembly Exception [2].
16+
*
17+
* [1] https://www.gnu.org/software/classpath/license.html
18+
* [2] https://openjdk.org/legal/assembly-exception.html
19+
*
20+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
21+
*/
22+
package org.openj9.test;
23+
24+
import com.ibm.oti.vm.VM;
25+
26+
public class VMAPITest2 {
27+
public static void main(String[] args) throws Throwable {
28+
final WorkLoad workLoad = new WorkLoad(200, 20000, 200);
29+
30+
Thread app = new Thread(() -> {
31+
workLoad.runWork();
32+
});
33+
app.start();
34+
35+
try {
36+
Thread.sleep(3000);
37+
} catch(Throwable t) {
38+
t.printStackTrace();
39+
}
40+
41+
if (VM.isJFRRecordingStarted()) {
42+
System.out.println("Failed should not be recording 1.");
43+
System.exit(0);
44+
}
45+
46+
/* attempt a stop recording before it has started */
47+
VM.stopJFR();
48+
49+
if (VM.isJFRRecordingStarted()) {
50+
System.out.println("Failed should not be recording 2.");
51+
System.exit(0);
52+
}
53+
54+
VM.startJFR();
55+
if (!VM.isJFRRecordingStarted()) {
56+
System.out.println("Failed should be recording 3.");
57+
System.exit(0);
58+
}
59+
60+
61+
/* attempt another start recording after one has already started */
62+
VM.startJFR();
63+
if (!VM.isJFRRecordingStarted()) {
64+
System.out.println("Failed should be recording 4.");
65+
System.exit(0);
66+
}
67+
68+
VM.stopJFR();
69+
if (VM.isJFRRecordingStarted()) {
70+
System.out.println("Failed should not be recording 5.");
71+
System.exit(0);
72+
}
73+
74+
/* attempt a stop recording before it has started */
75+
VM.stopJFR();
76+
}
77+
}

0 commit comments

Comments
 (0)