8308819: add JDWP and JDI virtual thread support for ThreadReference.ForceEarlyReturn
Reviewed-by: sspitsyn, alanb
This commit is contained in:
parent
e42a4b659a
commit
5531f6ba1b
@ -2104,10 +2104,10 @@ JDWP "Java(tm) Debug Wire Protocol"
|
|||||||
"command and resumption of thread execution, the "
|
"command and resumption of thread execution, the "
|
||||||
"state of the stack is undefined. "
|
"state of the stack is undefined. "
|
||||||
"<p>"
|
"<p>"
|
||||||
"The target VM may not support, or may only provide limited support, for "
|
"This command may be used to force a return from the current frame "
|
||||||
"this command when the thread is a virtual thread. It may, for example, "
|
"of a virtual thread when it is suspended at an event. "
|
||||||
"only support this command when the virtual thread is suspended at a "
|
"An implementation may support forcing a return from the current frame "
|
||||||
"breakpoint or singlestep event."
|
"of a suspended virtual thread in other cases."
|
||||||
"<p>"
|
"<p>"
|
||||||
"No further instructions are executed in the called "
|
"No further instructions are executed in the called "
|
||||||
"method. Specifically, finally blocks are not executed. Note: "
|
"method. Specifically, finally blocks are not executed. Note: "
|
||||||
@ -2147,7 +2147,7 @@ JDWP "Java(tm) Debug Wire Protocol"
|
|||||||
(Error THREAD_NOT_SUSPENDED)
|
(Error THREAD_NOT_SUSPENDED)
|
||||||
(Error OPAQUE_FRAME "Attempted to return early from a frame "
|
(Error OPAQUE_FRAME "Attempted to return early from a frame "
|
||||||
"corresponding to a native method, "
|
"corresponding to a native method, "
|
||||||
"the thread is a virtual thread and the target "
|
"the thread is a suspended virtual thread and the target "
|
||||||
"VM is unable to force its current frame to return, "
|
"VM is unable to force its current frame to return, "
|
||||||
"or the implementation is unable to provide this "
|
"or the implementation is unable to provide this "
|
||||||
"functionality on this frame.")
|
"functionality on this frame.")
|
||||||
|
@ -436,10 +436,10 @@ public interface ThreadReference extends ObjectReference {
|
|||||||
* this method and resumption of thread execution, the
|
* this method and resumption of thread execution, the
|
||||||
* state of the stack is undefined.
|
* state of the stack is undefined.
|
||||||
* <p>
|
* <p>
|
||||||
* The target VM may not support, or may only provide limited support,
|
* This method may be used to force a return from the current frame
|
||||||
* for forcing a method to return when the thread is a virtual thread.
|
* of a virtual thread when it is suspended at an event.
|
||||||
* It may, for example, only support this operation when the virtual
|
* An implementation may support forcing a return from the current frame
|
||||||
* thread is suspended at a breakpoint or singlestep event.
|
* of a suspended virtual thread in other cases.
|
||||||
* <p>
|
* <p>
|
||||||
* No further instructions are executed in the called
|
* No further instructions are executed in the called
|
||||||
* method. Specifically, finally blocks are not executed. Note:
|
* method. Specifically, finally blocks are not executed. Note:
|
||||||
@ -484,7 +484,7 @@ public interface ThreadReference extends ObjectReference {
|
|||||||
* @throws IncompatibleThreadStateException if this
|
* @throws IncompatibleThreadStateException if this
|
||||||
* thread is not suspended.
|
* thread is not suspended.
|
||||||
*
|
*
|
||||||
* @throws OpaqueFrameException if this thread is a virtual thread and the
|
* @throws OpaqueFrameException if this thread is a suspended virtual thread and the
|
||||||
* target VM is unable to force the method to return.
|
* target VM is unable to force the method to return.
|
||||||
*
|
*
|
||||||
* @throws NativeMethodException if the frame to be returned from
|
* @throws NativeMethodException if the frame to be returned from
|
||||||
|
@ -597,11 +597,10 @@ public class ThreadReferenceImpl extends ObjectReferenceImpl
|
|||||||
} catch (JDWPException exc) {
|
} catch (JDWPException exc) {
|
||||||
switch (exc.errorCode()) {
|
switch (exc.errorCode()) {
|
||||||
case JDWP.Error.OPAQUE_FRAME:
|
case JDWP.Error.OPAQUE_FRAME:
|
||||||
if (meth.isNative()) {
|
if (isVirtual() && !meth.isNative()) {
|
||||||
throw new NativeMethodException();
|
|
||||||
} else {
|
|
||||||
assert isVirtual(); // can only happen with virtual threads
|
|
||||||
throw new OpaqueFrameException();
|
throw new OpaqueFrameException();
|
||||||
|
} else {
|
||||||
|
throw new NativeMethodException();
|
||||||
}
|
}
|
||||||
case JDWP.Error.THREAD_NOT_SUSPENDED:
|
case JDWP.Error.THREAD_NOT_SUSPENDED:
|
||||||
throw new IncompatibleThreadStateException(
|
throw new IncompatibleThreadStateException(
|
||||||
|
@ -105,16 +105,6 @@ vmTestbase/nsk/jdb/repeat/repeat001/repeat001.java 8300707 generic-all
|
|||||||
|
|
||||||
vmTestbase/nsk/jdi/ExceptionEvent/catchLocation/location002/TestDescription.java 8278470 generic-all
|
vmTestbase/nsk/jdi/ExceptionEvent/catchLocation/location002/TestDescription.java 8278470 generic-all
|
||||||
|
|
||||||
####
|
|
||||||
## JVMTI ForceEarlyReturn not supported for vthreads (JVMTI_ERROR_OPAQUE_FRAME)
|
|
||||||
## Note forceEarlyReturn002 was converted to support vthreads. The rest were not
|
|
||||||
## since there is no added value (JVMTI_ERROR_OPAQUE_FRAME is expected).
|
|
||||||
|
|
||||||
vmTestbase/nsk/jdi/ThreadReference/forceEarlyReturn/forceEarlyReturn002/forceEarlyReturn002.java
|
|
||||||
vmTestbase/nsk/jdi/ThreadReference/forceEarlyReturn/forceEarlyReturn014/forceEarlyReturn014.java 8285415 generic-all
|
|
||||||
vmTestbase/nsk/jdi/stress/serial/forceEarlyReturn001/TestDescription.java 8285415 generic-all
|
|
||||||
vmTestbase/nsk/jdi/stress/serial/forceEarlyReturn002/TestDescription.java 8285415 generic-all
|
|
||||||
|
|
||||||
###
|
###
|
||||||
# This test always times out on windows. This is due to the test forcing OOME in the
|
# This test always times out on windows. This is due to the test forcing OOME in the
|
||||||
# debuggee, which has the side affect of making the Read-Poller thread exit. Because
|
# debuggee, which has the side affect of making the Read-Poller thread exit. Because
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -147,30 +147,17 @@ public class forceEarlyReturn002 extends ForceEarlyReturnDebugger {
|
|||||||
|
|
||||||
// get value for early return
|
// get value for early return
|
||||||
ObjectReference returnValue = (ObjectReference) referenceType.getValue(referenceType.fieldByName("expectedValue"));
|
ObjectReference returnValue = (ObjectReference) referenceType.getValue(referenceType.fieldByName("expectedValue"));
|
||||||
boolean vthreadMode = "Virtual".equals(System.getProperty("main.wrapper"));
|
|
||||||
try {
|
try {
|
||||||
// don't expect any exception, except for vthreads expect OpaqueFrameException
|
// don't expect any exception
|
||||||
threadReference.forceEarlyReturn(returnValue);
|
threadReference.forceEarlyReturn(returnValue);
|
||||||
if (vthreadMode) {
|
|
||||||
setSuccess(false);
|
|
||||||
log.complain("Expected OpaqueFrameException");
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (vthreadMode && (e instanceof OpaqueFrameException)) {
|
setSuccess(false);
|
||||||
// pass
|
log.complain("Unexpected exception: " + e);
|
||||||
} else {
|
e.printStackTrace(log.getOutStream());
|
||||||
setSuccess(false);
|
|
||||||
log.complain("Unexpected exception: " + e);
|
|
||||||
e.printStackTrace(log.getOutStream());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vthreadMode) {
|
testMethodExitEvent(threadReference, ClassUsingTestClass.breakpointMethodName);
|
||||||
// MethodExit event won't be as expected if using vthreads, so just resume
|
|
||||||
threadReference.resume();
|
|
||||||
} else {
|
|
||||||
testMethodExitEvent(threadReference, ClassUsingTestClass.breakpointMethodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isDebuggeeReady())
|
if (!isDebuggeeReady())
|
||||||
return;
|
return;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -83,9 +83,7 @@ public class forceEarlyReturn002a extends AbstractJDIDebuggee {
|
|||||||
classUsingTestClass.createExpectedValue();
|
classUsingTestClass.createExpectedValue();
|
||||||
Object value = classUsingTestClass.testClassMethod();
|
Object value = classUsingTestClass.testClassMethod();
|
||||||
|
|
||||||
boolean vthreadMode = "Virtual".equals(System.getProperty("main.wrapper"));
|
if (ClassUsingTestClass.expectedValue != value) {
|
||||||
// expectedValue should be set as expected unless in vthread mode
|
|
||||||
if (vthreadMode == (ClassUsingTestClass.expectedValue == value)) {
|
|
||||||
setSuccess(false);
|
setSuccess(false);
|
||||||
log.complain("Unexpected result of testClassMethod: " + value);
|
log.complain("Unexpected result of testClassMethod: " + value);
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@ com/sun/jdi/EATests.java#id0 8264699 generic-
|
|||||||
#
|
#
|
||||||
|
|
||||||
com/sun/jdi/DeferredStepTest.java 8285422 generic-all
|
com/sun/jdi/DeferredStepTest.java 8285422 generic-all
|
||||||
com/sun/jdi/EarlyReturnTest.java 8285422 generic-all
|
|
||||||
com/sun/jdi/ExceptionEvents.java 8285422 generic-all
|
com/sun/jdi/ExceptionEvents.java 8285422 generic-all
|
||||||
com/sun/jdi/JdbMethodExitTest.java 8285422 generic-all
|
com/sun/jdi/JdbMethodExitTest.java 8285422 generic-all
|
||||||
com/sun/jdi/JdbStepTest.java 8285422 generic-all
|
com/sun/jdi/JdbStepTest.java 8285422 generic-all
|
||||||
|
263
test/jdk/com/sun/jdi/ForceEarlyReturnTest.java
Normal file
263
test/jdk/com/sun/jdi/ForceEarlyReturnTest.java
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023, 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @summary Call forceEarlyReturn() on threads in various states not covered
|
||||||
|
* well by other tests. Most notably, this test includes a
|
||||||
|
* test case for a suspended but unmounted virtual thread.
|
||||||
|
*
|
||||||
|
* @run build TestScaffold VMConnection TargetListener TargetAdapter
|
||||||
|
* @run compile -g ForceEarlyReturnTest.java
|
||||||
|
* @run driver ForceEarlyReturnTest NATIVE
|
||||||
|
* @run driver ForceEarlyReturnTest LOOP
|
||||||
|
* @run driver ForceEarlyReturnTest SLEEP
|
||||||
|
*/
|
||||||
|
import com.sun.jdi.*;
|
||||||
|
import com.sun.jdi.event.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There are three test modes covered by this test:
|
||||||
|
* NATIVE: the debuggee sits in a native method.
|
||||||
|
* SLEEP: the debuggee blocks in Thread.sleep().
|
||||||
|
* LOOP: the debuggee sits in a tight loop.
|
||||||
|
*
|
||||||
|
* In all cases the thread is suspended and errors such as IllegalArgumentException
|
||||||
|
* and InvalidStackFrameException should not happen. The forceEarlyReturn() calls should
|
||||||
|
* either pass, or produce OpaqueFrameException or NativeMethodException.
|
||||||
|
*
|
||||||
|
* Call stacks for each test mode (and expected result):
|
||||||
|
*
|
||||||
|
* NATIVE (NativeMethodException):
|
||||||
|
* nativeMethod() <-- native method, which sleeps
|
||||||
|
* loopOrSleep()
|
||||||
|
* main()
|
||||||
|
*
|
||||||
|
* LOOP (no exception):
|
||||||
|
* loopOrSleep() <-- tight loop
|
||||||
|
* main()
|
||||||
|
*
|
||||||
|
* SLEEP (NativeMethodException for platform thread or OpaqueFrameException
|
||||||
|
* for virtual thread. See explanation in runTests().):
|
||||||
|
* Thread.sleep() + methods called by Thread.sleep()
|
||||||
|
* loopOrSleep()
|
||||||
|
* main()
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ForceEarlyReturnTestTarg {
|
||||||
|
static TestMode mode;
|
||||||
|
|
||||||
|
static {
|
||||||
|
System.loadLibrary("ForceEarlyReturnTestTarg");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loopOrSleep() {
|
||||||
|
switch (mode) {
|
||||||
|
case TestMode.LOOP:
|
||||||
|
while (true);
|
||||||
|
case TestMode.SLEEP:
|
||||||
|
try {
|
||||||
|
Thread.sleep(10000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TestMode.NATIVE:
|
||||||
|
nativeMethod();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static native void nativeMethod(); // native method that does a very long sleep
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println(" debuggee: Howdy!");
|
||||||
|
|
||||||
|
// We expect just one argument, which is the test mode, such as SLEEP.
|
||||||
|
if (args.length != 1) {
|
||||||
|
throw new RuntimeException("Must pass 1 arguments to ForceEarlyReturnTestTarg");
|
||||||
|
}
|
||||||
|
System.out.println(" debuggee: args[0]: " + args[0]);
|
||||||
|
mode = Enum.valueOf(TestMode.class, args[0]); // convert test mode string to an enum
|
||||||
|
System.out.println(" debuggee: test mode: " + mode);
|
||||||
|
|
||||||
|
loopOrSleep();
|
||||||
|
|
||||||
|
System.out.println(" debuggee: Goodbye from ForceEarlyReturnTest!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The different modes the test can be run in. See test description comment above.
|
||||||
|
*/
|
||||||
|
enum TestMode {
|
||||||
|
NATIVE,
|
||||||
|
SLEEP,
|
||||||
|
LOOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********** test program **********/
|
||||||
|
|
||||||
|
public class ForceEarlyReturnTest extends TestScaffold {
|
||||||
|
private static TestMode mode;
|
||||||
|
|
||||||
|
ForceEarlyReturnTest(String args[]) {
|
||||||
|
super(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
// We should get one argument that indicates the test mode, such as SLEEP.
|
||||||
|
if (args.length != 1) {
|
||||||
|
throw new RuntimeException("Must pass one argument to ForceEarlyReturnTestTarg");
|
||||||
|
}
|
||||||
|
mode = Enum.valueOf(TestMode.class, args[0]); // convert test mode string to an enum
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The @run command looks something like:
|
||||||
|
* @run driver ForceEarlyReturnTest SLEEP
|
||||||
|
* We need to pass SLEEP to the debuggee. We also need to insert
|
||||||
|
* -Djava.library.path so the native method can be accessed if called.
|
||||||
|
*/
|
||||||
|
String nativePath = "-Djava.library.path=" + System.getProperty("java.library.path");
|
||||||
|
String[] newArgs = new String[2];
|
||||||
|
newArgs[0] = nativePath;
|
||||||
|
newArgs[1] = args[0]; // pass test mode, such as SLEEP_NONATIVE
|
||||||
|
|
||||||
|
new ForceEarlyReturnTest(newArgs).startTests();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printStack(ThreadReference thread, String msg) throws Exception {
|
||||||
|
System.out.println(msg);
|
||||||
|
List<StackFrame> stack_frames = thread.frames();
|
||||||
|
int i = 0;
|
||||||
|
String sourceName;
|
||||||
|
for (StackFrame f : stack_frames) {
|
||||||
|
try {
|
||||||
|
sourceName = f.location().sourceName();
|
||||||
|
} catch (AbsentInformationException aie) {
|
||||||
|
sourceName = "Unknown source";
|
||||||
|
}
|
||||||
|
System.out.println("frame[" + i++ +"]: " + f.location().method() +
|
||||||
|
" (bci:"+ f.location().codeIndex() + ")" +
|
||||||
|
" (" + sourceName + ":"+ f.location().lineNumber() + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/********** test core **********/
|
||||||
|
|
||||||
|
protected void runTests() throws Exception {
|
||||||
|
BreakpointEvent bpe = startTo("ForceEarlyReturnTestTarg", "loopOrSleep", "()V");
|
||||||
|
ThreadReference mainThread = bpe.thread();
|
||||||
|
boolean is_vthread_mode = "Virtual".equals(System.getProperty("main.wrapper"));
|
||||||
|
|
||||||
|
// Resume main thread until it is in Thread.sleep() or the infinite loop.
|
||||||
|
mainThread.resume();
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000); // give thread chance to get into Thread.sleep() or loop
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
mainThread.suspend(); // Suspend thread while in Thread.sleep() or loop
|
||||||
|
printStack(mainThread, "Debuggee stack before forceEarlyReturn():");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Figure out which exception forceEarlyReturn() should throw.
|
||||||
|
*/
|
||||||
|
Class expected_exception;
|
||||||
|
switch(mode) {
|
||||||
|
case NATIVE:
|
||||||
|
/*
|
||||||
|
* There is a native frame on the top of the stack, so we expect NativeMethodException.
|
||||||
|
*/
|
||||||
|
expected_exception = NativeMethodException.class;
|
||||||
|
break;
|
||||||
|
case LOOP:
|
||||||
|
/*
|
||||||
|
* There is a java frame on the top of the stack, so we expect no exception.
|
||||||
|
*/
|
||||||
|
expected_exception = null;
|
||||||
|
break;
|
||||||
|
case SLEEP:
|
||||||
|
/*
|
||||||
|
* For platform threads, Thread.sleep() results in the Thread.sleep0() native
|
||||||
|
* frame on the stack, so the end result is NativeMethodException. For virtual
|
||||||
|
* threads it is not quite so simple. If the thead is pinned (such as when
|
||||||
|
* there is already a native method on the stack), you end up in
|
||||||
|
* VirtualThread.parkOnCarrierThread(), which calls Unsafe.park(), which is a
|
||||||
|
* native method, so again this results in NativeMethodException. However, for
|
||||||
|
* a virtual thread that is not pinned (which is true for this test case), you
|
||||||
|
* end up with no native methods on the stack due to how Continuation.yield()
|
||||||
|
* works. So you have an unmounted virtual thread with no native frames, which
|
||||||
|
* results in OpaqueFrameException being thrown.
|
||||||
|
*/
|
||||||
|
if (is_vthread_mode) {
|
||||||
|
expected_exception = OpaqueFrameException.class;
|
||||||
|
} else {
|
||||||
|
expected_exception = NativeMethodException.class;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("Bad test mode: " + mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call ThreadReference.forceEarlyReturn() and check for errors.
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
if (is_vthread_mode && mode == TestMode.SLEEP) {
|
||||||
|
// For this test case with virtual threads, the topmost frame is for
|
||||||
|
// Continuation.yield0(), which returns a boolean.
|
||||||
|
BooleanValue theValue = vm().mirrorOf(true);
|
||||||
|
mainThread.forceEarlyReturn(theValue);
|
||||||
|
} else {
|
||||||
|
// For all other cases, the topmost frame will be one that returns void.
|
||||||
|
VoidValue theValue = vm().mirrorOfVoid();
|
||||||
|
mainThread.forceEarlyReturn(theValue);
|
||||||
|
}
|
||||||
|
if (expected_exception != null) {
|
||||||
|
failure("failure: forceEarlyReturn() did not get expected exception: " + expected_exception);
|
||||||
|
} else {
|
||||||
|
System.out.println("success: no exception for forceEarlyReturn()");
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
if (expected_exception == ex.getClass()) {
|
||||||
|
System.out.println("success: forceEarlyReturn() got expected exception: " + ex);
|
||||||
|
} else {
|
||||||
|
failure("failure: forceEarlyReturn() got unexpected exception: " + ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Most tests do a listenUntilVMDisconnect() here, but there is no real need for it
|
||||||
|
* with this test, and doing so would require finding a way to get the debuggee
|
||||||
|
* to exit the endless loop it might be in. When we return, TestScaffold will
|
||||||
|
* call TestScaffold.shutdown(), causing the debuggee process to be terminated quickly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (testFailed) {
|
||||||
|
throw new Exception("ForceEarlyReturnTest failed");
|
||||||
|
}
|
||||||
|
System.out.println("Passed:");
|
||||||
|
}
|
||||||
|
}
|
37
test/jdk/com/sun/jdi/libForceEarlyReturnTestTarg.c
Normal file
37
test/jdk/com/sun/jdi/libForceEarlyReturnTestTarg.c
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023, 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "jni.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: NativeMethod
|
||||||
|
* Method: nativeMethod
|
||||||
|
* Signature: ()V
|
||||||
|
*/
|
||||||
|
JNIEXPORT void JNICALL Java_ForceEarlyReturnTestTarg_nativeMethod(JNIEnv *env, jobject obj) {
|
||||||
|
/* Just spin. We don't need to ever return from here. */
|
||||||
|
while(JNI_TRUE);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user