8199371: [TESTBUG] Open source vm testbase JDWP tests
Reviewed-by: sspitsyn, mseledtsov
--- a/test/hotspot/jtreg/ProblemList.txt Wed May 30 16:18:56 2018 -0700
+++ b/test/hotspot/jtreg/ProblemList.txt Wed May 30 20:54:45 2018 -0700
@@ -172,4 +172,6 @@
vmTestbase/heapdump/JMapHeapCore/TestDescription.java 8023376,8001227,8051445 generic-all
vmTestbase/heapdump/JMapMetaspaceCore/TestDescription.java 8023376,8001227,8051445 generic-all
+vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn001/forceEarlyReturn001.java 7199837 generic-all
+
#############################################################################
--- a/test/hotspot/jtreg/TEST.groups Wed May 30 16:18:56 2018 -0700
+++ b/test/hotspot/jtreg/TEST.groups Wed May 30 20:54:45 2018 -0700
@@ -1750,6 +1750,122 @@
vmTestbase/nsk/jvmti/unit/GetAllStackTraces/getallstktr001/TestDescription.java \
vmTestbase/nsk/jvmti/unit/GetConstantPool/getcpool001/TestDescription.java
+# JDWP tests
+vmTestbase_nsk_jdwp = \
+ vmTestbase/nsk/jdwp
+
+vmTestbase_nsk_jdwp_quick = \
+ vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues002/TestDescription.java \
+ vmTestbase/nsk/jdwp/ArrayReference/Length/length001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ArrayReference/SetValues/setvalues001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ArrayType/NewInstance/newinstance001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ClassLoaderReference/VisibleClasses/visibclasses001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ClassObjectReference/ReflectedType/reflectype001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ClassType/InvokeMethod/invokemeth001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ClassType/NewInstance/newinst001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ClassType/SetValues/setvalues001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ClassType/Superclass/superclass001/TestDescription.java \
+ vmTestbase/nsk/jdwp/Event/BREAKPOINT/breakpoint001/TestDescription.java \
+ vmTestbase/nsk/jdwp/Event/EXCEPTION/exception001/TestDescription.java \
+ vmTestbase/nsk/jdwp/Event/FIELD_ACCESS/fldaccess001/TestDescription.java \
+ vmTestbase/nsk/jdwp/Event/FIELD_MODIFICATION/fldmodification001/TestDescription.java \
+ vmTestbase/nsk/jdwp/Event/CLASS_PREPARE/clsprepare001/TestDescription.java \
+ vmTestbase/nsk/jdwp/Event/CLASS_UNLOAD/clsunload001/TestDescription.java \
+ vmTestbase/nsk/jdwp/Event/METHOD_ENTRY/methentry001/TestDescription.java \
+ vmTestbase/nsk/jdwp/Event/METHOD_EXIT/methexit001/TestDescription.java \
+ vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep001/TestDescription.java \
+ vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep002/TestDescription.java \
+ vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep003/TestDescription.java \
+ vmTestbase/nsk/jdwp/Event/THREAD_DEATH/thrdeath001/TestDescription.java \
+ vmTestbase/nsk/jdwp/Event/THREAD_START/thrstart001/TestDescription.java \
+ vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath001/TestDescription.java \
+ vmTestbase/nsk/jdwp/Event/VM_START/vmstart001/TestDescription.java \
+ vmTestbase/nsk/jdwp/Event/Composite/composite001/TestDescription.java \
+ vmTestbase/nsk/jdwp/EventRequest/Clear/clear001/TestDescription.java \
+ vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp001/TestDescription.java \
+ vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp002/TestDescription.java \
+ vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp003/TestDescription.java \
+ vmTestbase/nsk/jdwp/EventRequest/Set/set001/TestDescription.java \
+ vmTestbase/nsk/jdwp/EventRequest/Set/set002/TestDescription.java \
+ vmTestbase/nsk/jdwp/Method/LineTable/linetable001/TestDescription.java \
+ vmTestbase/nsk/jdwp/Method/VariableTable/vartable001/TestDescription.java \
+ vmTestbase/nsk/jdwp/Method/Bytecodes/bytecodes001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ObjectReference/DisableCollection/disablecol001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ObjectReference/EnableCollection/enablecol001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ObjectReference/GetValues/getvalues001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ObjectReference/InvokeMethod/invokemeth001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ObjectReference/IsCollected/iscollected001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ObjectReference/MonitorInfo/monitorinfo001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ObjectReference/ReferenceType/referencetype001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ObjectReference/SetValues/setvalues001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ReferenceType/ClassLoader/classloader001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ReferenceType/ClassObject/classobj001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ReferenceType/Fields/fields001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ReferenceType/GetValues/getvalues001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ReferenceType/Interfaces/interfaces001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ReferenceType/Methods/methods001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ReferenceType/Modifiers/modifiers001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ReferenceType/NestedTypes/nestedtypes001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ReferenceType/Signature/signature001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ReferenceType/SourceFile/srcfile001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ReferenceType/Status/status001/TestDescription.java \
+ vmTestbase/nsk/jdwp/StackFrame/GetValues/getvalues001/TestDescription.java \
+ vmTestbase/nsk/jdwp/StackFrame/SetValues/setvalues001/TestDescription.java \
+ vmTestbase/nsk/jdwp/StackFrame/ThisObject/thisobject001/TestDescription.java \
+ vmTestbase/nsk/jdwp/StringReference/Value/value001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ThreadGroupReference/Children/children001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ThreadGroupReference/Name/name001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ThreadGroupReference/Parent/parent001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ThreadReference/CurrentContendedMonitor/curcontmonitor001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ThreadReference/Frames/frames001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ThreadReference/FrameCount/framecnt001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ThreadReference/Interrupt/interrupt001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ThreadReference/Name/name001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitors/ownmonitors001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ThreadReference/Resume/resume001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ThreadReference/Status/status001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ThreadReference/Stop/stop001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ThreadReference/Suspend/suspend001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ThreadReference/SuspendCount/suspendcnt001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ThreadReference/ThreadGroup/threadgroup001/TestDescription.java \
+ vmTestbase/nsk/jdwp/VirtualMachine/AllThreads/allthreads001/TestDescription.java \
+ vmTestbase/nsk/jdwp/VirtualMachine/Capabilities/capabilities001/TestDescription.java \
+ vmTestbase/nsk/jdwp/VirtualMachine/ClassPaths/classpaths001/TestDescription.java \
+ vmTestbase/nsk/jdwp/VirtualMachine/ClassesBySignature/classbysig001/TestDescription.java \
+ vmTestbase/nsk/jdwp/VirtualMachine/CreateString/createstr001/TestDescription.java \
+ vmTestbase/nsk/jdwp/VirtualMachine/Dispose/dispose001/TestDescription.java \
+ vmTestbase/nsk/jdwp/VirtualMachine/DisposeObjects/disposeobj001/TestDescription.java \
+ vmTestbase/nsk/jdwp/VirtualMachine/Exit/exit001/TestDescription.java \
+ vmTestbase/nsk/jdwp/VirtualMachine/HoldEvents/holdevents001/TestDescription.java \
+ vmTestbase/nsk/jdwp/VirtualMachine/IDSizes/idsizes001/TestDescription.java \
+ vmTestbase/nsk/jdwp/VirtualMachine/TopLevelThreadGroups/threadgroups001/TestDescription.java \
+ vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents001/TestDescription.java \
+ vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents002/TestDescription.java \
+ vmTestbase/nsk/jdwp/VirtualMachine/Resume/resume001/TestDescription.java \
+ vmTestbase/nsk/jdwp/VirtualMachine/Version/version001/TestDescription.java \
+ vmTestbase/nsk/jdwp/VirtualMachine/Version/version002/TestDescription.java \
+ vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath002/TestDescription.java \
+ vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete001/TestDescription.java \
+ vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete002/TestDescription.java \
+ vmTestbase/nsk/jdwp/ReferenceType/SourceDebugExtension/srcdebugext001/TestDescription.java \
+ vmTestbase/nsk/jdwp/StackFrame/PopFrames/popframes001/TestDescription.java \
+ vmTestbase/nsk/jdwp/VirtualMachine/CapabilitiesNew/capabilitiesnew001/TestDescription.java \
+ vmTestbase/nsk/jdwp/VirtualMachine/RedefineClasses/redefinecls001/TestDescription.java \
+ vmTestbase/nsk/jdwp/VirtualMachine/SetDefaultStratum/setdefstrat001/TestDescription.java \
+ vmTestbase/nsk/jdwp/Method/VariableTableWithGeneric/vartblwithgen001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001/TestDescription.java \
+ vmTestbase/nsk/jdwp/ReferenceType/Instances/instances001/instances001.java \
+ vmTestbase/nsk/jdwp/ReferenceType/Instances/instances002/instances002.java \
+ vmTestbase/nsk/jdwp/ObjectReference/ReferringObjects/referringObjects001/referringObjects001.java \
+ vmTestbase/nsk/jdwp/ObjectReference/ReferringObjects/referringObjects002/referringObjects002.java \
+ vmTestbase/nsk/jdwp/VirtualMachine/InstanceCounts/instanceCounts001/instanceCounts001.java \
+ vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/forceEarlyReturn002.java \
+ vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitorsStackDepthInfo/ownedMonitorsStackDepthInfo001/ownedMonitorsStackDepthInfo001.java \
+ vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitorsStackDepthInfo/ownedMonitorsStackDepthInfo002/ownedMonitorsStackDepthInfo002.java
+
vmTestbase_nsk_stress = \
vmTestbase/nsk/stress
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ArrayReference.GetValues;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ArrayReference.GetValues.
+ *
+ * See getvalues001.README for description of test execution.
+ *
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class getvalues001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ArrayReference.GetValues";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "getvalues001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ArrayReference.GetValues";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ArrayReference.GetValues;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the static field in the tested class with the tested object value
+ static final String ARRAY_FIELD_NAME = getvalues001a.ARRAY_FIELD_NAME;
+ static final int ARRAY_LENGTH = getvalues001a.ARRAY_LENGTH;
+
+ // first index and number of array components to get
+ static final int ARRAY_FIRST_INDEX = 4;
+ static final int ARRAY_ITEMS_COUNT = 10;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new getvalues001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debugee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debugee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debugee for TypeID of tested class
+ log.display("Getting ReferenceTypeID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for arrayID value from static field
+ log.display("Getting arrayID value from static field: "
+ + ARRAY_FIELD_NAME);
+ long arrayID = queryObjectID(classID,
+ ARRAY_FIELD_NAME, JDWP.Tag.ARRAY);
+ log.display(" got arrayID: " + arrayID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(arrayID);
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ e.printStackTrace(out);
+ success = false;
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception:\n" + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received form debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for objectID value of static class field.
+ */
+ long queryObjectID(long classID, String fieldName, byte tag) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != tag) {
+ throw new Failure("Wrong objectID tag received from field \"" + fieldName
+ + "\": " + value.getTag() + " (expected: " + tag + ")");
+ }
+
+ // extract threadID from the value
+ long objectID = ((Long)value.getValue()).longValue();
+ return objectID;
+ }
+
+ /**
+ * Perform testing JDWP command for specified objectID.
+ */
+ void testCommand(long arrayID) {
+ // create command packet
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+
+ // add out data to the command packet
+ log.display(" arrayID: " + arrayID);
+ command.addObjectID(arrayID);
+ log.display(" firstIndex: " + ARRAY_FIRST_INDEX);
+ command.addInt(ARRAY_FIRST_INDEX);
+ log.display(" length: " + ARRAY_ITEMS_COUNT);
+ command.addInt(ARRAY_ITEMS_COUNT);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet: " + e.getMessage());
+ success = false;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract values tag
+ byte tag = (byte)0;
+ try {
+ tag = reply.getByte();
+ log.display(" tag: " + tag);
+
+ } catch (BoundException e) {
+ log.complain("Unable to extract values tag from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ }
+
+ // check if number of values are as expected
+ if (tag != JDWP.Tag.INT) {
+ log.complain("Unexpected values tag received:" + tag
+ + " (expected: " + JDWP.Tag.INT + ")");
+ success = false;
+ }
+
+ // extract number of values
+ int values = 0;
+ try {
+ values = reply.getInt();
+ log.display(" values: " + values);
+
+ } catch (BoundException e) {
+ log.complain("Unable to extract number of values from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ }
+
+ // check if number of values are as expected
+ if (values < 0) {
+ log.complain("Negative number of values received:" + values
+ + " (expected: " + ARRAY_ITEMS_COUNT + ")");
+ success = false;
+ } else if (values != ARRAY_ITEMS_COUNT) {
+ log.complain("Unexpected number of values received:" + values
+ + " (expected: " + ARRAY_ITEMS_COUNT + ")");
+ success = false;
+ }
+
+ // extract and check each value
+ for (int i = 0; i < values; i++ ) {
+ int index = i + ARRAY_FIRST_INDEX;
+ log.display(" value #" + i + " (index: " + index + ")");
+
+ // extract value
+ JDWP.UntaggedValue value = null;
+ try {
+ value = reply.getUntaggedValue(JDWP.Tag.INT);
+ log.display(" untagged_value: " + value);
+ } catch (BoundException e) {
+ log.complain("Unable to extract " + i + " value from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ break;
+ }
+
+ // check that extracted value is as expected
+ int intValue = ((Integer)value.getValue()).intValue();
+ if (intValue != index * 10) {
+ log.complain("Unexpected value for " + index + " component received: "
+ + intValue + " (expected: " + (index * 10) + ")");
+ success = false;
+ }
+ }
+
+ // check for extra data in reply packet
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + "0x" + reply.toHexString(reply.currentDataPosition(), 4));
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ArrayReference/GetValues/getvalues001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ArrayReference
+ * command: GetValues
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * the returned values of requested array components are equal
+ * to the expected ones. Tested array contains primitive values.
+ * Test consists of two compoments:
+ * debugger: getvalues001
+ * debuggee: getvalues001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization messages.
+ * Next, debugger obtains from debuggee classID for the tested class and
+ * arrayID as the value of the class static field. Checked array in
+ * debuggee is filled with the regular integer values.
+ * Then, debugger creates command packet for GetValues command with the
+ * found arrayID and start index and number of components as arguments,
+ * writes packet to the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts values of the array components. Also test checks
+ * that extracted values are equal to the expected ones.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ArrayReference.GetValues.getvalues001
+ * nsk.jdwp.ArrayReference.GetValues.getvalues001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ArrayReference.GetValues.getvalues001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ArrayReference.GetValues;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class getvalues001a {
+
+ public static final String ARRAY_FIELD_NAME = "array";
+ public static final int ARRAY_LENGTH = 16;
+
+ public static void main(String args[]) {
+ getvalues001a _getvalues001a = new getvalues001a();
+ System.exit(getvalues001.JCK_STATUS_BASE + _getvalues001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // meke communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // ensure tested class loaded
+ log.display("Creating and fille tested array");
+ TestedClass.setArrayValues();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + getvalues001.READY);
+ pipe.println(getvalues001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + getvalues001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (! signal.equals(getvalues001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + getvalues001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return getvalues001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return getvalues001.PASSED;
+ }
+
+ // tested class with own static fields values
+ public static class TestedClass {
+
+ // static field with tested array
+ public static int array[] = null;
+
+ public static void setArrayValues() {
+ array = new int[ARRAY_LENGTH];
+ for (int i = 0; i < ARRAY_LENGTH; i++) {
+ array[i] = i * 10;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues002.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,527 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ArrayReference.GetValues;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ArrayReference.GetValues.
+ *
+ * See getvalues002.README for description of test execution.
+ *
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class getvalues002 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ArrayReference.GetValues";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "getvalues002";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ArrayReference.GetValues";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ArrayReference.GetValues;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the static field in the tested class with the tested object value
+ static final String ARRAY_FIELD_NAME = getvalues002a.ARRAY_FIELD_NAME;
+ static final int ARRAY_LENGTH = getvalues002a.ARRAY_LENGTH;
+
+ // names of the statc fields with object values
+ static final int FIELDS_COUNT = getvalues002a.FIELDS_COUNT;
+ static final String FIELD_NAMES[] = {
+ "nullObject",
+ "baseObject",
+ "derivedObject",
+ "stringObject",
+ "primitiveArrayObject",
+ "objectArrayObject",
+ "threadObject",
+ "threadGroupObject",
+ "classObject",
+ "classLoaderObject",
+ };
+ static final byte FIELD_TAGS[] = {
+ JDWP.Tag.OBJECT, // nullObject
+ JDWP.Tag.OBJECT, // baseobject
+ JDWP.Tag.OBJECT, // derivedObject
+ JDWP.Tag.STRING, // stringObject
+ JDWP.Tag.ARRAY, // primitiveArrayObject
+ JDWP.Tag.ARRAY, // objectArrayObject
+ JDWP.Tag.THREAD, // threadObject
+ JDWP.Tag.THREAD_GROUP, // threadGroupObject
+ JDWP.Tag.CLASS_OBJECT, // classObject
+ JDWP.Tag.CLASS_LOADER // classLoaderObject
+ };
+
+ // first index and number of array components to get
+ static final int ARRAY_FIRST_INDEX = getvalues002a.ARRAY_FIRST_INDEX;
+ static final int ARRAY_ITEMS_COUNT = FIELDS_COUNT;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new getvalues002().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debugee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debugee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debugee for TypeID of tested class
+ log.display("Getting ReferenceTypeID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debugee for fieldIDs of the class static fields
+ log.display("Getting fieldIDs for static fields of the class");
+ long fieldIDs[] = queryClassFieldIDs(classID);
+ log.display(" got fields: " + fieldIDs.length);
+
+ // query debugee for object values of the fields
+ log.display("Getting objectID values of the static fields");
+ long objectIDs[] = queryClassFieldValues(classID, fieldIDs);
+ log.display(" got objectIDs: " + objectIDs.length);
+
+ // query debuggee for arrayID value from static field
+ log.display("Getting arrayID value from static field: "
+ + ARRAY_FIELD_NAME);
+ long arrayID = queryObjectID(classID,
+ ARRAY_FIELD_NAME, JDWP.Tag.ARRAY);
+ log.display(" got arrayID: " + arrayID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(arrayID, objectIDs);
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ e.printStackTrace(out);
+ success = false;
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception:\n" + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received form debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debugee for fieldID's of the class static fields.
+ */
+ long[] queryClassFieldIDs(long classID) {
+
+ long[] fieldIDs = new long[FIELDS_COUNT];
+ for (int i = 0; i < FIELDS_COUNT; i++) {
+ fieldIDs[i] = 0;
+ }
+
+ // compose ReferenceType.Fields command packet
+ CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.Fields);
+ command.addReferenceTypeID(classID);
+ command.setLength();
+
+ // send the command and receive reply
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+
+ // extract fieldIDs from the reply packet
+ try {
+ reply.resetPosition();
+
+ int declared = reply.getInt();
+
+ for (int i = 0; i < declared; i++ ) {
+ long fieldID = reply.getFieldID();
+ String name = reply.getString();
+ String signature = reply.getString();
+ int modBits = reply.getInt();
+
+ for (int j = 0; j < FIELDS_COUNT; j++) {
+ if (FIELD_NAMES[j].equals(name)) {
+ fieldIDs[j] = fieldID;
+ }
+ }
+ }
+
+ for (int i = 0; i < FIELDS_COUNT; i++) {
+ if (fieldIDs[i] == 0) {
+ log.complain("Not found fieldID for static field: " + FIELD_NAMES[i]);
+ throw new Failure("Error occured while getting static fieldIDs for classID: "
+ + classID);
+ }
+ }
+
+ } catch (BoundException e) {
+ log.complain("Unable to parse reply packet for ReferenceType.Fields command:\n\t"
+ + e);
+ log.complain("Received reply packet:\n"
+ + reply);
+ throw new Failure("Error occured while getting static fieldIDs for classID: " + classID);
+ }
+
+ return fieldIDs;
+ }
+
+ /**
+ * Query debugee for objectID values of the class fields.
+ */
+ long[] queryClassFieldValues(long classID, long fieldIDs[]) {
+ String error = "Error occured while getting object values for static fields of classID: "
+ + classID;
+
+ // compose ReferenceType.Fields command packet
+ CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.GetValues);
+ command.addReferenceTypeID(classID);
+ command.addInt(FIELDS_COUNT);
+ for (int i = 0; i < FIELDS_COUNT; i++) {
+ command.addFieldID(fieldIDs[i]);
+ }
+ command.setLength();
+
+ // send the command and receive reply
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+
+ // extract values from the reply packet
+ try {
+ reply.resetPosition();
+
+ int valuesCount = reply.getInt();
+ if (valuesCount != FIELDS_COUNT) {
+ log.complain("Unexpected number of values for static fields: " + valuesCount
+ + " (expected: " + FIELDS_COUNT + ")");
+ throw new Failure(error);
+ }
+
+ long objectIDs[] = new long[valuesCount];
+ for (int i = 0; i < valuesCount; i++ ) {
+ JDWP.Value value = reply.getValue();
+ byte tag = value.getTag();
+ if (tag != FIELD_TAGS[i]) {
+ log.complain("Unexpected tag of oblectID value for static field "
+ + FIELD_NAMES[i] + ": " + tag
+ + " (expected: " + FIELD_TAGS[i] + ")");
+ throw new Failure(error);
+ }
+ long objectID = ((Long)value.getValue()).longValue();
+ objectIDs[i] = objectID;
+ }
+ return objectIDs;
+ } catch (BoundException e) {
+ log.complain("Unable to parse reply packet for ReferenceType.GetValues command:\n\t"
+ + e);
+ log.complain("Received reply packet:\n"
+ + reply);
+ throw new Failure("Error occured while getting static fields values for classID: " + classID);
+ }
+ }
+
+ /**
+ * Query debuggee for objectID value of static class field.
+ */
+ long queryObjectID(long classID, String fieldName, byte tag) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != tag) {
+ throw new Failure("Wrong objectID tag received from field \"" + fieldName
+ + "\": " + value.getTag() + " (expected: " + tag + ")");
+ }
+
+ // extract threadID from the value
+ long objectID = ((Long)value.getValue()).longValue();
+ return objectID;
+ }
+
+ /**
+ * Perform testing JDWP command for specified objectID.
+ */
+ void testCommand(long arrayID, long objectIDs[]) {
+ // create command packet
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+
+ // add out data to the command packet
+ log.display(" arrayID: " + arrayID);
+ command.addObjectID(arrayID);
+ log.display(" firstIndex: " + ARRAY_FIRST_INDEX);
+ command.addInt(ARRAY_FIRST_INDEX);
+ log.display(" length: " + ARRAY_ITEMS_COUNT);
+ command.addInt(ARRAY_ITEMS_COUNT);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet: " + e.getMessage());
+ success = false;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract values tag
+ byte tag = (byte)0;
+ try {
+ tag = reply.getByte();
+ log.display(" tag: " + tag);
+
+ } catch (BoundException e) {
+ log.complain("Unable to extract values tag from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ }
+
+ // check if number of values are as expected
+ if (tag != JDWP.Tag.OBJECT) {
+ log.complain("Unexpected values tag received:" + tag
+ + " (expected: " + JDWP.Tag.OBJECT + ")");
+ success = false;
+ }
+
+ // extract number of values
+ int values = 0;
+ try {
+ values = reply.getInt();
+ log.display(" values: " + values);
+
+ } catch (BoundException e) {
+ log.complain("Unable to extract number of values from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ }
+
+ // check if number of values are as expected
+ if (values < 0) {
+ log.complain("Negative number of values received:" + values
+ + " (expected: " + ARRAY_ITEMS_COUNT + ")");
+ success = false;
+ } else if (values != ARRAY_ITEMS_COUNT) {
+ log.complain("Unexpected number of values received:" + values
+ + " (expected: " + ARRAY_ITEMS_COUNT + ")");
+ success = false;
+ }
+
+ // extract and check each value
+ for (int i = 0; i < values; i++ ) {
+ int index = i + ARRAY_FIRST_INDEX;
+ log.display(" value #" + i + " (index: " + index + ")");
+
+ // extract value
+ JDWP.Value value = null;
+ try {
+ value = reply.getValue();
+ log.display(" value: " + value);
+ } catch (BoundException e) {
+ log.complain("Unable to extract " + i + " value from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ break;
+ }
+
+ // check that value's tag is as expected
+ byte valueTag = value.getTag();
+ if (valueTag != FIELD_TAGS[i]) {
+ log.complain("Unexpected value tag for " + index + " component ("
+ + FIELD_NAMES[i] + ") received: " + valueTag
+ + " (expected: " + FIELD_TAGS[i] + ")");
+ success = false;
+ }
+
+ // check that value's objectID is as expected
+ long objectID = ((Long)value.getValue()).longValue();
+ if (objectID != objectIDs[i]) {
+ log.complain("Unexpected objectID for " + index + " component ("
+ + FIELD_NAMES[i] + ") received: " + objectID
+ + " (expected: " + objectIDs[i] + ")");
+ success = false;
+ }
+ }
+
+ // check for extra data in reply packet
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + "0x" + reply.toHexString(reply.currentDataPosition(), 4));
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues002/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ArrayReference/GetValues/getvalues002.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ArrayReference
+ * command: GetValues
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * the returned values of requested array components are equal
+ * to the expected ones. Tested array contains object values
+ * of several kinds (objects, strings, arrays, threads, etc.)
+ * Test consists of two compoments:
+ * debugger: getvalues002
+ * debuggee: getvalues002a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization messages.
+ * Next, debugger obtains from debuggee classID for the tested class and
+ * arrayID as the value of the class static field. Also debugger obtains
+ * object values from static fileds. These values are the same as components
+ * of the tested array.
+ * Then, debugger creates command packet for GetValues command with the
+ * found arrayID and start index and number of components as arguments,
+ * writes packet to the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts values of the array components. Also test checks
+ * that extracted object values are equal to the expected ones.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ArrayReference.GetValues.getvalues002
+ * nsk.jdwp.ArrayReference.GetValues.getvalues002a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ArrayReference.GetValues.getvalues002
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/GetValues/getvalues002a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ArrayReference.GetValues;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class getvalues002a {
+
+ public static final String ARRAY_FIELD_NAME = "array";
+ public static final int FIELDS_COUNT = 10;
+ public static final int ARRAY_FIRST_INDEX = 4;
+ public static final int ARRAY_LENGTH = ARRAY_FIRST_INDEX + FIELDS_COUNT + 5;
+
+ public static void main(String args[]) {
+ getvalues002a _getvalues002a = new getvalues002a();
+ System.exit(getvalues002.JCK_STATUS_BASE + _getvalues002a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // meke communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // ensure tested class loaded
+ log.display("Creating and fille tested array");
+ TestedClass.setArrayValues();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + getvalues002.READY);
+ pipe.println(getvalues002.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + getvalues002.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (! signal.equals(getvalues002.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + getvalues002.QUIT + ")");
+ log.display("Debugee FAILED");
+ return getvalues002.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return getvalues002.PASSED;
+ }
+
+ // tested class with own static fields values
+ public static class TestedClass {
+
+ // static field with tested array
+ public static Object array[] = null;
+
+ // static fields with object values
+ public static Object nullObject = null;
+ public static Object baseObject = new Object();
+ public static TestedClass derivedObject = new TestedClass();
+ public static String stringObject = new String("string");
+ public static int[] primitiveArrayObject = new int[10];
+ public static Object[] objectArrayObject = new Object[10];
+ public static Thread threadObject = Thread.currentThread();
+ public static ThreadGroup threadGroupObject = threadObject.getThreadGroup();
+ public static Class classObject = derivedObject.getClass();
+ public static ClassLoader classLoaderObject = classObject.getClassLoader();
+
+ public static void setArrayValues() {
+ array = new Object[ARRAY_LENGTH];
+ for (int i = 0; i < ARRAY_LENGTH; i++) {
+ array[i] = null;
+ }
+
+ int i = ARRAY_FIRST_INDEX;
+ array[i + 0] = nullObject;
+ array[i + 1] = baseObject;
+ array[i + 2] = derivedObject;
+ array[i + 3] = stringObject;
+ array[i + 4] = primitiveArrayObject;
+ array[i + 5] = objectArrayObject;
+ array[i + 6] = threadObject;
+ array[i + 7] = threadGroupObject;
+ array[i + 8] = classObject;
+ array[i + 9] = classLoaderObject;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/Length/length001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ArrayReference.Length;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ArrayReference.Length.
+ *
+ * See length001.README for description of test execution.
+ *
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class length001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ArrayReference.Length";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "length001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ArrayReference.Length";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ArrayReference.Length;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the static field in the tested class with the tested object value
+ static final String ARRAY_FIELD_NAME = length001a.ARRAY_FIELD_NAME;
+ static final int ARRAY_LENGTH = length001a.ARRAY_LENGTH;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new length001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debugee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debugee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debugee for TypeID of tested class
+ log.display("Getting ReferenceTypeID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for arrayID value from static field
+ log.display("Getting arrayID value from static field: "
+ + ARRAY_FIELD_NAME);
+ long arrayID = queryObjectID(classID,
+ ARRAY_FIELD_NAME, JDWP.Tag.ARRAY);
+ log.display(" got arrayID: " + arrayID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(arrayID);
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ e.printStackTrace(out);
+ success = false;
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception:\n" + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received form debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for objectID value of static class field.
+ */
+ long queryObjectID(long classID, String fieldName, byte tag) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != tag) {
+ throw new Failure("Wrong objectID tag received from field \"" + fieldName
+ + "\": " + value.getTag() + " (expected: " + tag + ")");
+ }
+
+ // extract threadID from the value
+ long objectID = ((Long)value.getValue()).longValue();
+ return objectID;
+ }
+
+ /**
+ * Perform testing JDWP command for specified arrayID.
+ */
+ void testCommand(long arrayID) {
+ // create command packet
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+
+ // add out data to the command packet
+ log.display(" arrayID: " + arrayID);
+ command.addObjectID(arrayID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet: " + e.getMessage());
+ success = false;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract array length
+ int arrayLength = 0;
+ try {
+ arrayLength = reply.getInt();
+ log.display(" arrayLength: " + arrayLength);
+
+ } catch (BoundException e) {
+ log.complain("Unable to extract arrayLength from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ }
+
+ // check if arrayLength is as expected
+ if (arrayLength < 0) {
+ log.complain("Negative number of arrayLength received:" + arrayLength
+ + " (expected: " + ARRAY_LENGTH + ")");
+ success = false;
+ } else if (arrayLength != ARRAY_LENGTH) {
+ log.complain("Unexpected number of values received:" + arrayLength
+ + " (expected: " + ARRAY_LENGTH + ")");
+ success = false;
+ }
+
+ // check for extra data in reply packet
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + "0x" + reply.toHexString(reply.currentDataPosition(), 4));
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/Length/length001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ArrayReference/Length/length001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ArrayReference
+ * command: Length
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * the returned array length is equal to the expected one.
+ * Test consists of two compoments:
+ * debugger: length001
+ * debuggee: length001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization messages.
+ * Next, debugger obtains from debuggee classID for the tested class and
+ * arrayID as the value of the class static field. Checked array in
+ * debuggee is filled with the regular integer values.
+ * Then, debugger creates command packet for Length command with the
+ * found arrayID and start index and number of components as arguments,
+ * writes packet to the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts array length value. Also test checks that extracted array
+ * length is equal to the expected one.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ArrayReference.Length.length001
+ * nsk.jdwp.ArrayReference.Length.length001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ArrayReference.Length.length001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/Length/length001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ArrayReference.Length;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class length001a {
+
+ public static final String ARRAY_FIELD_NAME = "array";
+ public static final int ARRAY_LENGTH = 16;
+
+ public static void main(String args[]) {
+ length001a _length001a = new length001a();
+ System.exit(length001.JCK_STATUS_BASE + _length001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // meke communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // ensure tested class loaded
+ log.display("Creating and fille tested array");
+ TestedClass.setArrayValues();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + length001.READY);
+ pipe.println(length001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + length001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (! signal.equals(length001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + length001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return length001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return length001.PASSED;
+ }
+
+ // tested class with own static fields values
+ public static class TestedClass {
+
+ // static field with tested array
+ public static int array[] = null;
+
+ public static void setArrayValues() {
+ array = new int[ARRAY_LENGTH];
+ for (int i = 0; i < ARRAY_LENGTH; i++) {
+ array[i] = i * 10;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/SetValues/setvalues001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ArrayReference.SetValues;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ArrayReference.SetValues.
+ *
+ * See setvalues001.README for description of test execution.
+ *
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class setvalues001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String RUN = "run";
+ static final String DONE = "done";
+ static final String ERROR = "error";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ArrayReference.SetValues";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "setvalues001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ArrayReference.SetValues";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ArrayReference.SetValues;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the static field in the tested class with the tested object value
+ static final String ARRAY_FIELD_NAME = setvalues001a.ARRAY_FIELD_NAME;
+
+ // length, first index and number of array components to get
+ static final int ARRAY_LENGTH = setvalues001a.ARRAY_LENGTH;
+ static final int ARRAY_FIRST_INDEX = setvalues001a.ARRAY_FIRST_INDEX;
+ static final int ARRAY_ITEMS_COUNT = setvalues001a.ARRAY_ITEMS_COUNT;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new setvalues001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debugee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debugee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debugee for TypeID of tested class
+ log.display("Getting ReferenceTypeID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for arrayID value from static field
+ log.display("Getting arrayID value from static field: "
+ + ARRAY_FIELD_NAME);
+ long arrayID = queryObjectID(classID,
+ ARRAY_FIELD_NAME, JDWP.Tag.ARRAY);
+ log.display(" got arrayID: " + arrayID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(arrayID);
+
+ // check confirmation from debuggee that values have been set correctly
+ log.display("\n>>> Checking that the values have been set correctly \n");
+ checkValuesChanged();
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ e.printStackTrace(out);
+ success = false;
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception:\n" + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received form debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for objectID value of static class field.
+ */
+ long queryObjectID(long classID, String fieldName, byte tag) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != tag) {
+ throw new Failure("Wrong objectID tag received from field \"" + fieldName
+ + "\": " + value.getTag() + " (expected: " + tag + ")");
+ }
+
+ // extract threadID from the value
+ long objectID = ((Long)value.getValue()).longValue();
+ return objectID;
+ }
+
+ /**
+ * Perform testing JDWP command for specified objectID.
+ */
+ void testCommand(long arrayID) {
+ // create command packet
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+
+ // add out data to the command packet
+ log.display(" arrayID: " + arrayID);
+ command.addObjectID(arrayID);
+ log.display(" firstIndex: " + ARRAY_FIRST_INDEX);
+ command.addInt(ARRAY_FIRST_INDEX);
+ log.display(" values: " + ARRAY_ITEMS_COUNT);
+ command.addInt(ARRAY_ITEMS_COUNT);
+ // add new int values for array components
+ for (int i = ARRAY_FIRST_INDEX; i < ARRAY_FIRST_INDEX + ARRAY_ITEMS_COUNT; i++) {
+ int intValue = i * 100 + 1;
+ JDWP.UntaggedValue value = new JDWP.UntaggedValue(new Integer(intValue));
+ log.display(" untagged_value: " + value);
+ command.addUntaggedValue(value, JDWP.Tag.INT);
+ }
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet: " + e.getMessage());
+ success = false;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // no reply data to extract
+
+ // check for extra data in reply packet
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + "0x" + reply.toHexString(reply.currentDataPosition(), 4));
+ success = false;
+ }
+ }
+
+ /**
+ * Check confirmation from debuggee that values are changed correctly.
+ */
+ void checkValuesChanged() {
+ // send debugee signal RUN
+ log.display("Sending signal to debugee: " + RUN);
+ pipe.println(RUN);
+
+ // wait for DONE signal from debugee
+ log.display("Waiting for signal from debugee: " + DONE);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+
+ // check received signal
+ if (signal == null) {
+ throw new TestBug("<null> signal received from debugee: " + signal
+ + " (expected: " + DONE + ")");
+ } else if (signal.equals(DONE)) {
+ log.display("All array values have been correctly set into debuggee VM");
+ } else if (signal.equals(ERROR)) {
+ log.complain("Not all array values have been correctly set into debuggee VM");
+ success = false;
+ } else {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + DONE + ")");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/SetValues/setvalues001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ArrayReference/SetValues/setvalues001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ArrayReference
+ * command: SetValues
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * the new set values of array components are equal to the
+ * expected ones.
+ * Test consists of two compoments:
+ * debugger: setvalues001
+ * debuggee: setvalues001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization messages.
+ * Next, debugger obtains from debuggee classID for the tested class and
+ * arrayID as the value of the class static field. Checked array in
+ * debuggee is filled with the initial integer values.
+ * Then, debugger creates command packet for SetValues command with the
+ * found arrayID, start index and number of components as arguments,
+ * and new integer values, writes packet to the transport channel
+ * and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and ensures there is no data in the packet. Also test send signal
+ * <RUN> to debuggee to check new array values. If new values are set
+ * correctly debuggee replies with signal DONE.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ArrayReference.SetValues.setvalues001
+ * nsk.jdwp.ArrayReference.SetValues.setvalues001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ArrayReference.SetValues.setvalues001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayReference/SetValues/setvalues001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ArrayReference.SetValues;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class setvalues001a {
+
+ // name of the static field with the tested array object
+ public static final String ARRAY_FIELD_NAME = "array";
+
+ // length, first index and number of array components to get
+ public static final int ARRAY_LENGTH = 16;
+ public static final int ARRAY_FIRST_INDEX = 4;
+ public static final int ARRAY_ITEMS_COUNT = 10;
+
+ private static ArgumentHandler argumentHandler = null;
+ private static Log log = null;
+
+ public static void main(String args[]) {
+ setvalues001a _setvalues001a = new setvalues001a();
+ System.exit(setvalues001.JCK_STATUS_BASE + _setvalues001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // meke communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // ensure tested class loaded
+ log.display("Creating and initializing tested array");
+ TestedClass.initArrayValues();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + setvalues001.READY);
+ pipe.println(setvalues001.READY);
+
+ // wait for signal RUN from debugeer
+ log.display("Waiting for signal from debugger: " + setvalues001.RUN);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+ // check received signal
+ if (signal == null || !signal.equals(setvalues001.RUN)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + setvalues001.RUN + ")");
+ log.display("Debugee FAILED");
+ return setvalues001.FAILED;
+ }
+
+ // check assigned values
+ log.display("Checking new array values");
+ if (TestedClass.checkArrayValues()) {
+ log.display("Sending signal to debugger: " + setvalues001.DONE);
+ pipe.println(setvalues001.DONE);
+ } else {
+ log.display("Sending signal to debugger: " + setvalues001.ERROR);
+ pipe.println(setvalues001.ERROR);
+ }
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + setvalues001.QUIT);
+ signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (! signal.equals(setvalues001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + setvalues001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return setvalues001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return setvalues001.PASSED;
+ }
+
+ // tested class with own static fields values
+ public static class TestedClass {
+
+ // static field with tested array
+ public static int array[] = null;
+
+ public static void initArrayValues() {
+ array = new int[ARRAY_LENGTH];
+ for (int i = 0; i < ARRAY_LENGTH; i++) {
+ array[i] = i * 10;
+ }
+ }
+
+ public static boolean checkArrayValues() {
+ if (array == null) {
+ log.complain("Checked array == null after setting values: " + array);
+ return false;
+ }
+
+ boolean success = true;
+ if (array.length != ARRAY_LENGTH) {
+ log.complain("Unexpected array length after setting values: "
+ + array.length + " (expected: " + ARRAY_LENGTH + ")");
+ success = false;
+ }
+
+ for (int i = 0; i < array.length; i++) {
+ int initial = i * 10;
+ int changed = i * 100 + 1;
+ if (i < ARRAY_FIRST_INDEX || i >= ARRAY_FIRST_INDEX + ARRAY_ITEMS_COUNT) {
+ log.display(" " + i + " (not changed): " + initial + " -> " + array[i]);
+ if (array[i] != initial) {
+ log.complain("Changed value of " + i + " component which is out of changed region: "
+ + array[i] + "(initial: " + initial + ")");
+ success = false;
+ }
+ } else {
+ log.display(" " + i + " (changed): " + initial + " -> " + array[i]);
+ if (array[i] != changed) {
+ if (array[i] == initial) {
+ log.complain("Value of " + i + " component not changed: "
+ + array[i] + "(expected: " + changed + ")");
+ success = false;
+ } else {
+ log.complain("Value of " + i + " component changed incorrectly: "
+ + array[i] + "(expected: " + changed + ")");
+ success = false;
+ }
+ }
+ }
+ }
+
+ return success;
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayType/NewInstance/newinstance001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ArrayType.NewInstance;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ArrayType.NewInstance.
+ *
+ * See newinstance001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class newinstance001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ArrayType.NewInstance";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "newinstance001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ArrayType.NewInstance";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ArrayType.NewInstance;
+
+ // tested array type signature constant
+ static final String TESTED_ARRAY_SIGNATURE = "[I";
+
+ // tested array type size constant
+ static final int TESTED_ARRAY_SIZE = 100;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new newinstance001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debugee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debugee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debugee for TypeID of tested class
+ log.display("Getting arrayTypeID by signature:\n"
+ + " " + TESTED_ARRAY_SIGNATURE);
+ long typeID = debugee.getReferenceTypeID(TESTED_ARRAY_SIGNATURE);
+ log.display(" got TypeID: " + typeID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(typeID);
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Perform testing JDWP command for specified TypeID.
+ */
+ void testCommand(long typeID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" arrayTypeID: " + typeID);
+ command.addReferenceTypeID(typeID);
+ log.display(" length: " + TESTED_ARRAY_SIZE);
+ command.addInt(TESTED_ARRAY_SIZE);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract and check number of nested classes
+ JDWP.Value newArray = null;
+ try {
+ newArray = reply.getValue();
+ log.display(" newArray: " + newArray);
+
+ byte tag = newArray.getTag();
+ if (tag != JDWP.Tag.ARRAY) {
+ log.complain("Unexpected tag of new array value in the reply packet:"
+ + tag + " (expected: " + JDWP.Tag.ARRAY + ")");
+ success = false;
+ }
+
+ long objectID = 0;
+ try {
+ objectID = ((Long)newArray.getValue()).longValue();
+ } catch (ClassCastException e) {
+ throw new TestBug("Caught ClassCastException vhile extracting objectID from tagged value: "
+ + newArray);
+ }
+
+ if (objectID == 0) {
+ log.complain("Null objectID returned for new array value in the reply packet");
+ success = false;
+ }
+
+ } catch (BoundException e) {
+ log.complain("Unable to extract newArray value from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.offsetString());
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayType/NewInstance/newinstance001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ArrayType/NewInstance/newinstance001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ArrayType
+ * command: NewInstance
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: newinstance001
+ * debuggee: newinstance001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains arrayTypeIDs for the tested class from debugee.
+ * Then, debugger creates command packet for ArrayType.NewInstance command
+ * with the found arrayTypeID as an argument, writes packet to the transport
+ * channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts tagged objectID value of the new created array. Also test
+ * checks that the tag of the extracted value is ARRAY_ID and objectID is
+ * not null.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ArrayType.NewInstance.newinstance001
+ * nsk.jdwp.ArrayType.NewInstance.newinstance001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ArrayType.NewInstance.newinstance001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ArrayType/NewInstance/newinstance001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ArrayType.NewInstance;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class newinstance001a {
+
+ public static void main(String args[]) {
+ newinstance001a _newinstance001a = new newinstance001a();
+ System.exit(newinstance001.JCK_STATUS_BASE + _newinstance001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // ensure tested array type is loaded
+ log.display("Creating array of integer");
+ int foo[] = new int[10];
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + newinstance001.READY);
+ pipe.println(newinstance001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + newinstance001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (! signal.equals(newinstance001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + newinstance001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return newinstance001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return newinstance001.PASSED;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassLoaderReference/VisibleClasses/visibclasses001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ClassLoaderReference.VisibleClasses;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ClassLoaderReference.VisibleClasses.
+ *
+ * See visibclasses001.README for description of test execution.
+ *
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class visibclasses001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ClassLoaderReference.VisibleClasses";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "visibclasses001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ClassLoaderReference.VisibleClasses";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ClassLoaderReference.VisibleClasses;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new visibclasses001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debugee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debugee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debugee for TypeID of tested class
+ log.display("Getting ReferenceTypeID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debugee for TypeIDs of classes been nested
+ log.display("Getting classLoaderID for tested classes");
+ long classLoaderID = queryClassLoaderID(classID);
+ log.display(" got classLoaderID: " + classLoaderID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(classLoaderID, classID);
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debugee for classLoaderID for specified classID.
+ */
+ long queryClassLoaderID(long classID) {
+ CommandPacket command =
+ new CommandPacket(JDWP.Command.ReferenceType.ClassLoader);
+ command.addReferenceTypeID(classID);
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+
+ try {
+ reply.resetPosition();
+
+ long classLoaderID = reply.getObjectID();
+ return classLoaderID;
+ } catch (BoundException e) {
+ throw new Failure("Unable to parse reply packet for ReferenceType.ClassLoader:\n\t"
+ + e);
+ }
+ }
+
+ /**
+ * Perform testing JDWP command for specified classLoaderID.
+ */
+ void testCommand(long classLoaderID, long expectedClassID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ log.display(" classLoaderID: " + classLoaderID);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addObjectID(classLoaderID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract and check number of nested classes
+ int classes = 0;
+ try {
+ classes = reply.getInt();
+ log.display(" classes: " + classes);
+
+ } catch (BoundException e) {
+ log.complain("Unable to extract number of nested classes from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ }
+
+ if (classes < 0) {
+ log.complain("Negative number of classes in the reply packet:" + classes);
+ success = false;
+ } else if (classes == 0) {
+ log.complain("Zero number of classes in the reply packet:" + classes);
+ success = false;
+ }
+
+ boolean found = false;
+ // extract and check TypeID for each received class
+ for (int i = 0; i < classes; i++ ) {
+ log.display(" class #" + i);
+
+ // extract TypeTag byte
+ byte refTypeTag = (byte)0;
+ String refTypeTagName = null;
+ try {
+ refTypeTag = reply.getByte();
+ String tag;
+ switch (refTypeTag) {
+ case JDWP.TypeTag.CLASS:
+ refTypeTagName = "CLASS";
+ break;
+ case JDWP.TypeTag.INTERFACE:
+ refTypeTagName = "INTERFACE";
+ break;
+ case JDWP.TypeTag.ARRAY:
+ refTypeTagName = "ARRAY";
+ break;
+ default:
+ refTypeTagName = "UNKNOWN";
+ break;
+ }
+ log.display(" refTypeTag: " + refTypeTag + "=" + refTypeTagName);
+ } catch (BoundException e) {
+ log.complain("Unable to extract refTypetag of " + i
+ + " class from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ break;
+ }
+
+ // extract and check TypeID
+ long typeID = 0;
+ try {
+ typeID = reply.getReferenceTypeID();
+ log.display(" typeID: " + typeID);
+
+ } catch (BoundException e) {
+ log.complain("Unable to extract TypeID of " + i
+ + " nested class from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ break;
+ }
+
+ if (typeID == expectedClassID) {
+ log.display("Found expected classID: " + expectedClassID);
+ found = true;
+ if (refTypeTag != JDWP.TypeTag.CLASS) {
+ log.complain("unexpected refTypeTag returned for checked class: "
+ + refTypeTag + "=" + refTypeTagName
+ + " (expected: " + JDWP.TypeTag.CLASS + "=CLASS)");
+ success = false;
+ }
+ }
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.offsetString());
+ success = false;
+ }
+
+ if (!found) {
+ log.complain("Expected classID not found in the list of visible classes: " + expectedClassID);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassLoaderReference/VisibleClasses/visibclasses001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ClassLoaderReference/VisibleClasses/visibclasses001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ClassLoaderReference
+ * command: VisibleClasses
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * list of classes returned for classObjectID contains at least
+ * one expected classID.
+ * Test consists of two compoments:
+ * debugger: visibclasses001
+ * debuggee: visibclasses001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains classID for the tested class and its
+ * classLoaderID from debugee.
+ * Then, debugger creates command packet for VisibleClasses command
+ * with the found classObjectID as an argument, writes packet to the
+ * transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts list of typeIDs of the visible classes. Also test checks
+ * that this list includes expected classID of the original class.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ClassLoaderReference.VisibleClasses.visibclasses001
+ * nsk.jdwp.ClassLoaderReference.VisibleClasses.visibclasses001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ClassLoaderReference.VisibleClasses.visibclasses001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassLoaderReference/VisibleClasses/visibclasses001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ClassLoaderReference.VisibleClasses;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class visibclasses001a {
+
+ public static void main(String args[]) {
+ visibclasses001a _visibclasses001a = new visibclasses001a();
+ System.exit(visibclasses001.JCK_STATUS_BASE + _visibclasses001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // ensure tested class loaded
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + visibclasses001.READY);
+ pipe.println(visibclasses001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + visibclasses001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (! signal.equals(visibclasses001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + visibclasses001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return visibclasses001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return visibclasses001.PASSED;
+ }
+
+ // tested class with nested classes
+ public static class TestedClass {
+ int foo = 0;
+ public TestedClass() {
+ foo = 100;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassObjectReference/ReflectedType/reflectype001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ClassObjectReference.ReflectedType;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class reflectype001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.ClassObjectReference.ReflectedType";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "reflectype001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "ClassObjectReference.ReflectedType";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ClassObjectReference.ReflectedType;
+
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new reflectype001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ try {
+
+ // get referenceTypeID for debugee class
+
+ long originalTypeID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+
+ // get classObjectID for originalTypeID
+
+ long classObjectID = 0;
+ {
+ log.display("Getting classObjectID for referenceTypeID: " + originalTypeID);
+
+ CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.ClassObject);
+ command.addReferenceTypeID(originalTypeID);
+
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+
+ classObjectID = reply.getObjectID();
+ log.display("Found classObjectID: " + classObjectID);
+
+ }
+
+ // begin test of JDWP command
+
+ log.display("Create command " + JDWP_COMMAND_NAME
+ + " with classObjectID: " + classObjectID);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addObjectID(classObjectID);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ byte refTypeTag = reply.getByte();
+ log.display(" refTypeTag: " + classObjectID);
+
+ long typeID = reply.getReferenceTypeID();
+ log.display(" typeID: " + typeID);
+
+ if (refTypeTag != JDWP.TypeTag.CLASS) {
+ log.complain("No JDWP.TypeTag.CLASS tag returned for class object: " + refTypeTag);
+ success = false;
+ }
+
+ if (typeID != originalTypeID) {
+ log.complain("Returned typeID does not equal to original referenceTypeID: " + originalTypeID);
+ success = false;
+ }
+
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ success = false;
+ } else {
+ log.display("Reply packet parsed successfully");
+ }
+
+ // end test of JDWP command
+
+ } catch (Exception e) {
+ log.complain("Caught exception while testing JDWP command: " + e);
+ success = false;
+ } finally {
+
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception while connecting to debugee: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Caught unexpected exception while starting the test: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassObjectReference/ReflectedType/reflectype001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ClassObjectReference/ReflectedType/reflectype001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ClassObjectReference
+ * command: RefelectedType
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test check if
+ * received referenceTypeID for class object is equal to
+ * the original one.
+ * Test consists of two compoments:
+ * debugger: reflectype001
+ * debuggee: reflectype001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with execution commands.
+ * Next, debugger obtains referenceTypeID for debuggee class and then
+ * classObjectID, which will be used to test JDWP command.
+ * Then, debugger creates command packet for RefelectedType command with the
+ * found classObjectID as an argument, writes packet to the transport
+ * channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts referenceTypeID. Debugger tests also that obtained
+ * referenceTypeID has the proper tag and is equal to the original one.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ * COMMENTS
+ * Fixed misprint in package name according to test bug:
+ * 4782469 TEST_RFE: incorrect package name in some JPDA tests
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ClassObjectReference.ReflectedType.reflectype001
+ * nsk.jdwp.ClassObjectReference.ReflectedType.reflectype001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ClassObjectReference.ReflectedType.reflectype001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassObjectReference/ReflectedType/reflectype001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ClassObjectReference.ReflectedType;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class reflectype001a {
+
+ public static void main(String args[]) {
+ reflectype001a _reflectype001a = new reflectype001a();
+ System.exit(reflectype001.JCK_STATUS_BASE + _reflectype001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return reflectype001.PASSED;
+ }
+
+ static public class TestedClass {
+ int foo = 0;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/InvokeMethod/invokemeth001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,411 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ClassType.InvokeMethod;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ClassType.InvokeMethod.
+ *
+ * See invokemeth001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class invokemeth001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names
+ static final String PACKAGE_NAME = "nsk.jdwp.ClassType.InvokeMethod";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "invokemeth001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command
+ static final String JDWP_COMMAND_NAME = "ClassType.InvokeMethod";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ClassType.InvokeMethod;
+
+ // tested class name and signature
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedObjectClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // field and method names
+ static final String RESULT_FIELD_NAME = "result";
+ static final String TESTED_METHOD_NAME = "testedMethod";
+ static final String BREAKPOINT_METHOD_NAME = "run";
+ static final int BREAKPOINT_LINE_NUMBER = invokemeth001a.BREAKPOINT_LINE_NUMBER;
+
+ // data for invoked method
+ static final int ARGUMENTS_COUNT = 1;
+ static final int INITIAL_VALUE = invokemeth001a.INITIAL_VALUE;
+ static final int ARGUMENT_VALUE = invokemeth001a.FINAL_VALUE;
+ static final int RETURN_VALUE = INITIAL_VALUE;
+ static final int INVOKE_OPTIONS = 0;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // data obtained from debuggee
+ long classID = 0;
+ long threadID = 0;
+ long methodID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new invokemeth001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime(); // minutes
+ timeout = waitTime * 60 * 1000; // milliseconds
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee VM");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debuggee launched");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for VM_INIT event
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // prepare debuggee for testing and obtain required data
+ log.display("\n>>> Getting prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP command
+ log.display("\n>> Testing JDWP command \n");
+ testCommand();
+
+ // check command results
+ if (success) {
+ log.display("\n>>> Checking result of tested command \n");
+ checkResult();
+ }
+
+ // finish debuggee
+ log.display("\n>> Finishing debuggee \n");
+
+ // resume debuggee after testing command
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for VM_DEATH event
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ log.display(" ... VM_DEATH event received");
+ dead = true;
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ log.display("\n>>> Finishing test \n");
+
+ // disconnect debugee and wait for its exit
+ if (debugee != null) {
+ quitDebugee();
+ }
+ }
+
+ // check result
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+ out.println("TEST PASSED");
+ return PASSED;
+ }
+
+ /**
+ * Get debuggee prepared for testing and obtain required data.
+ */
+ void prepareForTest() {
+ // wait for tested class loaded on debuggee startup and obtain its classID
+ log.display("Waiting for class loaded:\n\t" + TESTED_CLASS_NAME);
+ classID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... class loaded with classID: " + classID);
+ log.display("");
+
+ // query debuggee for tested methodID
+ log.display("Getting tested methodID by name: " + TESTED_METHOD_NAME);
+ methodID = debugee.getMethodID(classID, TESTED_METHOD_NAME, true);
+ log.display(" ... got methodID: " + methodID);
+ log.display("");
+
+ // set breakpoint and wait for debugee reached it
+ log.display("Waiting for breakpoint reached at: "
+ + BREAKPOINT_METHOD_NAME + ":" + BREAKPOINT_LINE_NUMBER);
+ threadID = debugee.waitForBreakpointReached(classID,
+ BREAKPOINT_METHOD_NAME,
+ BREAKPOINT_LINE_NUMBER,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... breakpoint reached with threadID: " + threadID);
+ log.display("Tested thread is suspended by breakpoint event");
+ }
+
+ /**
+ * Perform testing JDWP command.
+ */
+ void testCommand() {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" classID: " + classID);
+ command.addReferenceTypeID(classID);
+ log.display(" threadID: " + threadID);
+ command.addObjectID(threadID);
+ log.display(" methodID: " + methodID);
+ command.addMethodID(methodID);
+ log.display(" arguments: " + ARGUMENTS_COUNT);
+ command.addInt(ARGUMENTS_COUNT);
+ for (int i = 0; i < ARGUMENTS_COUNT; i++) {
+ JDWP.Value value = new JDWP.Value(JDWP.Tag.INT, new Integer(ARGUMENT_VALUE));
+ log.display(" arg: " + value);
+ command.addValue(value);
+ }
+ log.display(" options: " + INVOKE_OPTIONS);
+ command.addInt(INVOKE_OPTIONS);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet for tested command:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Wrong header of reply packet for tested command:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet data:");
+ reply.resetPosition();
+
+ // extract return value
+ JDWP.Value returnValue = null;
+ try {
+ returnValue = reply.getValue();
+ log.display(" returnValue: " + returnValue);
+ } catch (BoundException e) {
+ log.complain("Unable to extract returnValues from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // extract exception tag
+ JDWP.Value exception = null;
+ try {
+ exception = reply.getValue();
+ log.display(" exception: " + exception);
+ } catch (BoundException e) {
+ log.complain("Unable to extract exception from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... packed data parsed");
+
+ // check that return value is an integer
+ if (returnValue.getTag() != JDWP.Tag.INT) {
+ log.complain("Unexpected tag of returnValue returned: " + returnValue.getTag()
+ + " (expected: " + JDWP.Tag.INT + ")");
+ success = false;
+ }
+
+ // check that return value is as expected
+ int intValue = ((Integer)returnValue.getValue()).intValue();
+ if (intValue != RETURN_VALUE) {
+ log.complain("Unexpected value of returnValue returned: " + intValue
+ + " (expected: " + RETURN_VALUE + ")");
+ success = false;
+ }
+
+ // check that exception value is an object
+ if (exception.getTag() != JDWP.Tag.OBJECT) {
+ log.complain("Unexpected tag of exception returned: " + exception.getTag()
+ + " (expected: " + JDWP.Tag.OBJECT + ")");
+ success = false;
+ }
+
+ // check that exception object is null
+ long exceptionID = ((Long)exception.getValue()).longValue();
+ if (exceptionID != 0) {
+ log.complain("Non-null exception object returned: " + exceptionID
+ + " (expected: " + 0 + ")");
+ success = false;
+ }
+ }
+
+ /**
+ * Check result of the tested JDWP command.
+ */
+ void checkResult() {
+ // query debuggee for result value from a static field
+ log.display("Getting result value from static field: " + RESULT_FIELD_NAME);
+ JDWP.Value value = debugee.getStaticFieldValue(classID, RESULT_FIELD_NAME, JDWP.Tag.INT);
+ int result = ((Integer)value.getValue()).intValue();
+ log.display(" ... got result: " + result);
+
+ // check if the result value is changed as expected
+ if (result != ARGUMENT_VALUE) {
+ log.complain("Method has not been really invoked: \n\t"
+ + "variable not changed by the method: " + result
+ + " (expected: " + ARGUMENT_VALUE + ")");
+ success = false;
+ } else {
+ log.display("Method has been really invoked: \n\t"
+ + " variable changed by the method: " + result
+ + " (expected: " + ARGUMENT_VALUE + ")");
+ }
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/InvokeMethod/invokemeth001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ClassType/InvokeMethod/invokemeth001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ClassType
+ * command: InvokeMethod
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * the tested static method is really invoked into debuggee.
+ * Test consists of two compoments:
+ * debugger: invokemeth001
+ * debuggee: invokemeth001a
+ * First, debugger uses nsk.share.* support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded, requests methodID
+ * for tested method, sets breakpoint and wait for breakpoint reached.
+ * When breakpoint event received the tested thread into debuggee
+ * is suspended by this event.
+ * Then, debugger creates command packet for ClassType.InvokeMethod
+ * command with the found classID, methodID, threadID, and also adds
+ * one integer argument for the method invocation. Then debugger writes
+ * packet to the transport channel and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts method's result value and exception objectID. Test checks
+ * if result value is an expected integer and exception objectID is null.
+ * Also test gets value of static field, wich should be modified by
+ * the invoked method, to verify if this method was really invoked
+ * into debuggee.
+ * Finally, debugger disconnects debuggee, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ClassType.InvokeMethod.invokemeth001
+ * nsk.jdwp.ClassType.InvokeMethod.invokemeth001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ClassType.InvokeMethod.invokemeth001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/InvokeMethod/invokemeth001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.ClassType.InvokeMethod;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class invokemeth001a {
+
+ // name of the tested thread
+ public static final String THREAD_NAME = "testedThread";
+
+ // line nunber for breakpoint
+ public static final int BREAKPOINT_LINE_NUMBER = 86;
+
+ // initial and final value of variable changed by the method invoked from debugger
+ public static final int INITIAL_VALUE = 10;
+ public static final int FINAL_VALUE = 1234;
+
+ // scaffold objects
+ private static volatile ArgumentHandler argumentHandler = null;
+ private static volatile Log log = null;
+
+ public static void main(String args[]) {
+ invokemeth001a _invokemeth001a = new invokemeth001a();
+ System.exit(invokemeth001.JCK_STATUS_BASE + _invokemeth001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // create tested of tested class
+ log.display("Creating object of tested class");
+ TestedObjectClass foo = new TestedObjectClass();
+ log.display(" ... object created");
+
+ // run method with breakpoint
+ TestedObjectClass.run();
+
+ log.display("Debugee PASSED");
+ return invokemeth001.PASSED;
+ }
+
+ // tested object class
+ public static class TestedObjectClass {
+ // result of invoking tested mathod
+ public static volatile int result = INITIAL_VALUE;
+
+ // suspend current thread on breakpoint
+ public static void run() {
+ log.display("Tested thread: started");
+
+ log.display("Breakpoint line reached");
+ // next line is for breakpoint
+ int foo = 0; // BREAKPOINT_LINE_NUMBER
+ log.display("Breakpoint line passed");
+
+ log.display("Tested thread: finished");
+ }
+
+ // tested method for invocation from debugger
+ public static int testedMethod(int arg) {
+ log.display("Tested method invoked with argument:" + arg);
+ int old = result;
+ result = arg;
+ log.display("Tested method returned with result:" + old);
+ return old;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/NewInstance/newinst001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,442 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ClassType.NewInstance;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ClassType.NewInstance.
+ *
+ * See newinst001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class newinst001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names
+ static final String PACKAGE_NAME = "nsk.jdwp.ClassType.NewInstance";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "newinst001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command
+ static final String JDWP_COMMAND_NAME = "ClassType.NewInstance";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ClassType.NewInstance;
+
+ // tested class name and signature
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedObjectClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // field and method names
+ static final String RESULT_FIELD_NAME = "result";
+ static final String TESTED_CONSTRUCTOR_NAME = "<init>";
+ static final String BREAKPOINT_METHOD_NAME = "run";
+ static final int BREAKPOINT_LINE_NUMBER = newinst001a.BREAKPOINT_LINE_NUMBER;
+
+ // data for invoked method
+ static final int ARGUMENTS_COUNT = 1;
+ static final int INITIAL_VALUE = newinst001a.INITIAL_VALUE;
+ static final int ARGUMENT_VALUE = newinst001a.FINAL_VALUE;
+ static final int RETURN_VALUE = INITIAL_VALUE;
+ static final int INVOKE_OPTIONS = 0;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+ boolean dead = false;
+
+ // data obtained from debuggee
+ long classID = 0;
+ long threadID = 0;
+ long methodID = 0;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new newinst001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee VM");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debuggee launched");
+
+ // set timeout for debuggee responces
+ int waitTime = argumentHandler.getWaitTime(); // minutes
+ long timeout = waitTime * 60 * 1000; // milliseconds
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for VM_INIT event
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // run the test
+ runTest();
+
+ // wait for VM_DEATH event
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ log.display(" ... VM_DEATH event received");
+ dead = true;
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ log.display("\n>>> Finishing test \n");
+
+ // disconnect debugee and wait for its exit
+ if (debugee != null) {
+ quitDebugee();
+ }
+ }
+
+ // check result
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+ out.println("TEST PASSED");
+ return PASSED;
+ }
+
+ /**
+ * Obtain required data and test JDWP command.
+ */
+ void runTest() {
+ log.display("\n>>> Obtaining required data \n");
+
+ // wait for tested class loaded on debuggee startup and obtain its classID
+ log.display("Waiting for class loaded:\n\t" + TESTED_CLASS_NAME);
+ classID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... got classID: " + classID);
+ log.display("");
+
+ // query debuggee for tested methodID
+ log.display("Getting tested methodID by constructor name: " + TESTED_CONSTRUCTOR_NAME);
+ methodID = debugee.getMethodID(classID, TESTED_CONSTRUCTOR_NAME, true);
+ log.display(" ... got methodID: " + methodID);
+ log.display("");
+
+ // set breakpoint and wait for debugee reached it
+ log.display("Waiting for breakpoint reached at: "
+ + BREAKPOINT_METHOD_NAME + ":" + BREAKPOINT_LINE_NUMBER);
+ threadID = debugee.waitForBreakpointReached(classID,
+ BREAKPOINT_METHOD_NAME,
+ BREAKPOINT_LINE_NUMBER,
+ JDWP.SuspendPolicy.EVENT_THREAD);
+ log.display(" ... breakpoint reached with threadID: " + threadID);
+
+ // test JDWP command
+ log.display("\n>> Testing JDWP command \n");
+ testCommand();
+
+ // check command results
+ if (success) {
+ log.display("\n>>> Checking command results \n");
+ checkResult();
+ }
+
+ // resume debuggee after the command
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+ }
+
+ /**
+ * Perform testing JDWP command.
+ */
+ void testCommand() {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" classID: " + classID);
+ command.addReferenceTypeID(classID);
+ log.display(" threadID: " + threadID);
+ command.addObjectID(threadID);
+ log.display(" methodID: " + methodID);
+ command.addMethodID(methodID);
+ log.display(" arguments: " + ARGUMENTS_COUNT);
+ command.addInt(ARGUMENTS_COUNT);
+ for (int i = 0; i < ARGUMENTS_COUNT; i++) {
+ JDWP.Value value = new JDWP.Value(JDWP.Tag.INT, new Integer(ARGUMENT_VALUE));
+ log.display(" arg: " + value);
+ command.addValue(value);
+ }
+ log.display(" options: " + INVOKE_OPTIONS);
+ command.addInt(INVOKE_OPTIONS);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // receive reply packet from debugee
+ ReplyPacket reply = new ReplyPacket();
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet for tested command:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Wrong header of reply packet for tested command:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet data:");
+ reply.resetPosition();
+
+ // extract return value
+ JDWP.Value newObject = null;
+ try {
+ newObject = reply.getValue();
+ log.display(" newObject: " + newObject);
+ } catch (BoundException e) {
+ log.complain("Unable to extract returnValues from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // extract exception tag
+ JDWP.Value exception = null;
+ try {
+ exception = reply.getValue();
+ log.display(" exception: " + exception);
+ } catch (BoundException e) {
+ log.complain("Unable to extract exception from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... packed data parsed");
+
+ // check that return value is an integer
+ if (newObject.getTag() != JDWP.Tag.OBJECT) {
+ log.complain("Unexpected tag of returnValue returned: " + newObject.getTag()
+ + " (expected: " + JDWP.Tag.OBJECT + ")");
+ success = false;
+ }
+
+ // check that return value is as expected
+ long newObjectID = ((Long)newObject.getValue()).longValue();
+ if (newObjectID == 0) {
+ log.complain("Unexpected null objectID for newObject value returned: "
+ + newObjectID + " (expected: not " + 0 + ")");
+ success = false;
+ }
+
+ // check that exception value is an object
+ if (exception.getTag() != JDWP.Tag.OBJECT) {
+ log.complain("Unexpected tag of exception returned: " + exception.getTag()
+ + " (expected: " + JDWP.Tag.OBJECT + ")");
+ success = false;
+ }
+
+ // check that exception object is null
+ long exceptionID = ((Long)exception.getValue()).longValue();
+ if (exceptionID != 0) {
+ log.complain("Not null objectID for exception value returned: " + exceptionID
+ + " (expected: " + 0 + ")");
+ success = false;
+ }
+ }
+
+ /**
+ * Check result of the tested JDWP command.
+ */
+ void checkResult() {
+ // query debuggee for result value from a static field
+ log.display("Getting result value from static field: " + RESULT_FIELD_NAME);
+ int result = queryInt(classID, RESULT_FIELD_NAME, JDWP.Tag.INT);
+ log.display(" ... got result: " + result);
+
+ // check if the result value is changed as expected
+ if (result != ARGUMENT_VALUE) {
+ log.complain("Method has not been really invoked: \n\t"
+ + "variable not changed by the method: " + result
+ + " (expected: " + ARGUMENT_VALUE + ")");
+ success = false;
+ } else {
+ log.display("Method has been really invoked: \n\t"
+ + " variable changed by the method: " + result
+ + " (expected: " + ARGUMENT_VALUE + ")");
+ }
+ }
+
+ /**
+ * Query debuggee for value of static field of the class.
+ */
+ JDWP.Value queryFieldValue(long classID, String fieldName, byte tag) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != tag) {
+ log.complain("unexpedted value tag returned from debuggee: " + value.getTag()
+ + " (expected: " + tag + ")");
+ throw new Failure("Error occured while getting value from static field: "
+ + fieldName);
+ }
+
+ return value;
+ }
+
+ /**
+ * Query debuggee for objectID value of static field of the class.
+ */
+ long queryObjectID(long classID, String fieldName, byte tag) {
+ JDWP.Value value = queryFieldValue(classID, fieldName, tag);
+ long objectID = ((Long)value.getValue()).longValue();
+ return objectID;
+ }
+
+ /**
+ * Query debuggee for int value of static field of the class.
+ */
+ int queryInt(long classID, String fieldName, byte tag) {
+ JDWP.Value value = queryFieldValue(classID, fieldName, tag);
+ int intValue = ((Integer)value.getValue()).intValue();
+ return intValue;
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debuggee if not dead
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally dispose debuggee:\n\t" + e.getMessage());
+ }
+ }
+
+ // wait for debugee exits
+ log.display("Waiting for debuggee exits");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee finished with exit code: " + code);
+
+ // analize debuggee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/NewInstance/newinst001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ClassType/NewInstance/newinst001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ClassType
+ * command: NewInstance
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * the tested constructor is really invoked into debuggee.
+ * Test consists of two compoments:
+ * debugger: newinst001
+ * debuggee: newinst001a
+ * First, debugger uses nsk.share.* support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded, requests methodID
+ * for tested constructtor, sets breakpoint and wait for breakpoint reached.
+ * When breakpoint event is received the tested thread into debuggee
+ * is suspended by this event.
+ * Then, debugger creates command packet for classType.NewInstance
+ * command with the found classID, methodID, threadID, and also adds one
+ * integer argument for the constructor invocation. Then debugger writes
+ * packet to the transport channel and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts tegged objectID's of new created object and exception.
+ * Test checks if objectID is not null and exception objectID is null.
+ * Also test gets value of static field, wich should be modified by
+ * the invoked constructor, to verify if this constructor was really
+ * invoked into debuggee.
+ * Finally, debugger disconnects debuggee, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ClassType.NewInstance.newinst001
+ * nsk.jdwp.ClassType.NewInstance.newinst001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ClassType.NewInstance.newinst001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/NewInstance/newinst001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.ClassType.NewInstance;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class newinst001a {
+
+ // name of the tested thread
+ public static final String THREAD_NAME = "testedThread";
+
+ // line nunber for breakpoint
+ public static final int BREAKPOINT_LINE_NUMBER = 88;
+
+ // initial and final value of variable changed by the method invoked from debugger
+ public static final int INITIAL_VALUE = 10;
+ public static final int FINAL_VALUE = 1234;
+
+ // scaffold objects
+ private static volatile ArgumentHandler argumentHandler = null;
+ private static volatile Log log = null;
+
+ public static void main(String args[]) {
+ newinst001a _newinst001a = new newinst001a();
+ System.exit(newinst001.JCK_STATUS_BASE + _newinst001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // create tested of tested class
+ log.display("Accessing to tested class");
+ TestedObjectClass.foo = 100;
+ log.display(" ... class loaded");
+
+ // invoke method with breakpoint
+ TestedObjectClass.run();
+
+ log.display("Debugee PASSED");
+ return newinst001.PASSED;
+ }
+
+ // tested object class
+ public static class TestedObjectClass {
+ public static int foo = 0;
+
+ // result of invoking tested mathod
+ public static volatile int result = INITIAL_VALUE;
+
+ // suspend current thread on on breakpoint
+ public static void run() {
+ log.display("Tested thread: started");
+
+ log.display("Breakpoint line reached");
+ // next line is for breakpoint
+ int foo = 0; // BREAKPOINT_LINE_NUMBER
+ log.display("Breakpoint line passed");
+
+ log.display("Tested thread: finished");
+ }
+
+ // tested constructor for invokation from debugger
+ public TestedObjectClass(int arg) {
+ log.display("Tested constructor invoked with argument:" + arg);
+ if (arg != FINAL_VALUE) {
+ log.complain("Unexpected value of constructor argument: " + arg
+ + " (expected: " + FINAL_VALUE + ")");
+ }
+ result = arg;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/SetValues/setvalues001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ClassType.SetValues;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ClassType.SetValues.
+ *
+ * See setvalues001.README for description of test execution.
+ *
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class setvalues001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String RUN = "run";
+ static final String DONE = "done";
+ static final String ERROR = "error";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ClassType.SetValues";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "setvalues001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ClassType.SetValues";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ClassType.SetValues;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // target values class name and signature constants
+ static final String TARGET_VALUES_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TargetValuesClass";
+ static final String TARGET_VALUES_CLASS_SIGNATURE = "L" + TARGET_VALUES_CLASS_NAME.replace('.', '/') + ";";
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new setvalues001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debugee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debugee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debugee for classID for the class with target values
+ log.display("Getting classID for class with target values by signature:\n"
+ + " " + TARGET_VALUES_CLASS_SIGNATURE);
+ long targetValuesClassID =
+ debugee.getReferenceTypeID(TARGET_VALUES_CLASS_SIGNATURE);
+ log.display(" got classID: " + targetValuesClassID);
+
+ // query debugee for fieldIDs of the class static fields
+ log.display("Getting fieldIDs for static fields of the class");
+ long targetValuesFieldIDs[] = queryClassFieldIDs(targetValuesClassID);
+ log.display(" got fields: " + targetValuesFieldIDs.length);
+ int count = targetValuesFieldIDs.length;
+
+ // query debugee for values of the fields
+ log.display("Getting values of the static fields");
+ JDWP.Value targetValues[] =
+ queryClassFieldValues(targetValuesClassID, targetValuesFieldIDs);
+ log.display(" got values: " + targetValues.length);
+ if (targetValues.length != count) {
+ throw new Failure("Unexpected number of static fields values received: "
+ + targetValues.length + "(expected: " + count + ")");
+ }
+
+ // query debugee for classID of the tested class
+ log.display("Getting tested classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long testedClassID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + testedClassID);
+
+ // query debugee for fieldIDs of tested class static fields
+ log.display("Getting fieldIDs for static fields of the tested class");
+ long testedFieldIDs[] = queryClassFieldIDs(testedClassID);
+ log.display(" got fields: " + testedFieldIDs.length);
+ if (testedFieldIDs.length != count) {
+ throw new Failure("Unexpected number of static fields of tested class received: "
+ + testedFieldIDs.length + "(expected: " + count + ")");
+ }
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(testedClassID, testedFieldIDs, targetValues);
+
+ // check confirmation from debuggee that values have been set properly
+ log.display("\n>>> Checking that the values have been set properly \n");
+ checkValuesChanged();
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ e.printStackTrace(out);
+ success = false;
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception:\n" + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received form debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debugee for fieldID's of the class static fields.
+ */
+ long[] queryClassFieldIDs(long classID) {
+ // compose ReferenceType.Fields command packet
+ CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.Fields);
+ command.addReferenceTypeID(classID);
+ command.setLength();
+
+ // send the command and receive reply
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+
+ // extract fieldIDs from the reply packet
+ try {
+ reply.resetPosition();
+
+ int declared = reply.getInt();
+ long[] fieldIDs = new long[declared];
+
+ for (int i = 0; i < declared; i++ ) {
+ long fieldID = reply.getFieldID();
+ String name = reply.getString();
+ String signature = reply.getString();
+ int modBits = reply.getInt();
+
+ fieldIDs[i] = fieldID;
+ }
+ return fieldIDs;
+ } catch (BoundException e) {
+ log.complain("Unable to parse reply packet for ReferenceType.Fields command:\n\t"
+ + e);
+ log.complain("Received reply packet:\n"
+ + reply);
+ throw new Failure("Error occured while getting static fieldIDs for classID: " + classID);
+ }
+ }
+
+ /**
+ * Query debugee for values of the class static fields.
+ */
+ JDWP.Value[] queryClassFieldValues(long classID, long fieldIDs[]) {
+ // compose ReferenceType.Fields command packet
+ int count = fieldIDs.length;
+ CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.GetValues);
+ command.addReferenceTypeID(classID);
+ command.addInt(count);
+ for (int i = 0; i < count; i++) {
+ command.addFieldID(fieldIDs[i]);
+ }
+ command.setLength();
+
+ // send the command and receive reply
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+
+ // extract values from the reply packet
+ try {
+ reply.resetPosition();
+
+ int valuesCount = reply.getInt();
+ JDWP.Value values[] = new JDWP.Value[valuesCount];
+ for (int i = 0; i < valuesCount; i++ ) {
+ JDWP.Value value = reply.getValue();
+ values[i] = value;
+ }
+ return values;
+ } catch (BoundException e) {
+ log.complain("Unable to parse reply packet for ReferenceType.GetValues command:\n\t"
+ + e);
+ log.complain("Received reply packet:\n"
+ + reply);
+ throw new Failure("Error occured while getting static fields values for classID: " + classID);
+ }
+ }
+
+ /**
+ * Perform testing JDWP command for specified classID.
+ */
+ void testCommand(long classID, long fieldIDs[], JDWP.Value values[]) {
+ int count = fieldIDs.length;
+
+ // create command packet
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+
+ // add out data to the command packet
+ log.display(" classID: " + classID);
+ command.addReferenceTypeID(classID);
+ log.display(" values: " + count);
+ command.addInt(count);
+ for (int i = 0; i < count; i++) {
+ log.display(" field #" + i +":");
+ log.display(" fieldID: " + fieldIDs[i]);
+ command.addFieldID(fieldIDs[i]);
+
+ JDWP.Value value = values[i];
+ JDWP.UntaggedValue untaggedValue =
+ new JDWP.UntaggedValue(value.getValue());
+ log.display(" untagged_value: " + untaggedValue.getValue());
+ command.addUntaggedValue(untaggedValue, value.getTag());
+ }
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet: " + e.getMessage());
+ success = false;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // no data to extract
+
+ // check for extra data in reply packet
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + "0x" + reply.toHexString(reply.currentDataPosition(), 4));
+ success = false;
+ }
+ }
+
+ /**
+ * Check confiramtion from debuggee that values are changed.
+ */
+ void checkValuesChanged() {
+ // send debugee signal RUN
+ log.display("Sending signal to debugee: " + RUN);
+ pipe.println(RUN);
+
+ // wait for DONE signal from debugee
+ log.display("Waiting for signal from debugee: " + DONE);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+
+ // check received signal
+ if (signal == null) {
+ throw new TestBug("<null> signal received from debugee: " + signal
+ + " (expected: " + DONE + ")");
+ } else if (signal.equals(DONE)) {
+ log.display("All static fields values have been correctly set into debuggee VM");
+ } else if (signal.equals(ERROR)) {
+ log.complain("Not all static fields values have been correctly set into debuggee VM");
+ success = false;
+ } else {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + DONE + ")");
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/SetValues/setvalues001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ClassType/SetValues/setvalues001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ClassType
+ * command: SetValues
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * the values are correctly set to debuggee class fields.
+ * Test consists of two compoments:
+ * debugger: setvalues001
+ * debuggee: setvalues001a
+ * To set values to the static fields of the tested class
+ * and check that they are set correctly, test defines
+ * following classes into debuggee VM:
+ * OriginalValuesClass - with original values of static fields
+ * TargetValuesClass - with target values of static fields
+ * TestedClass - tested class with static fields to set values to
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization messages.
+ * Next, debugger obtains classIDs for the tested class and class with
+ * the target values from debugee, it obtains also fieldIDs for thess
+ * classese and target values of the fields.
+ * Then, debugger creates command packet for SetValues command with the
+ * found referenceTypeID and list of fieldIDs as arguments, writes packet
+ * to the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and and checks that there is no data in the reply packet.
+ * Then debugger sends signal RUN to debuggee to ask it to verify
+ * new fields values of tested class. Debuggee compares compares
+ * these values with original and terget values and sends ERROR signal
+ * to debugger if the values was not set correctly.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ClassType.SetValues.setvalues001
+ * nsk.jdwp.ClassType.SetValues.setvalues001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ClassType.SetValues.setvalues001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/SetValues/setvalues001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ClassType.SetValues;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part of the test.
+ */
+public class setvalues001a {
+
+ static ArgumentHandler argumentHandler = null;
+ static Log log = null;
+
+ public static void main(String args[]) {
+ setvalues001a _setvalues001a = new setvalues001a();
+ System.exit(setvalues001.JCK_STATUS_BASE + _setvalues001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ // make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // ensure tested class loaded
+ log.display("Creating object of all required classes");
+ OriginalValuesClass original = new OriginalValuesClass();
+ TargetValuesClass target = new TargetValuesClass();
+ TestedClass tested = new TestedClass();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + setvalues001.READY);
+ pipe.println(setvalues001.READY);
+
+ // wait for signal RUN from debugeer
+ log.display("Waiting for signal from debugger: " + setvalues001.RUN);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+ // check received signal
+ if (signal == null || !signal.equals(setvalues001.RUN)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + setvalues001.RUN + ")");
+ log.display("Debugee FAILED");
+ return setvalues001.FAILED;
+ }
+
+ // check assigned values
+ if (checkValues()) {
+ log.display("Sending signal to debugger: " + setvalues001.DONE);
+ pipe.println(setvalues001.DONE);
+ } else {
+ log.display("Sending signal to debugger: " + setvalues001.ERROR);
+ pipe.println(setvalues001.ERROR);
+ }
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + setvalues001.QUIT);
+ signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+ // check received signal
+ if (! signal.equals(setvalues001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + setvalues001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return setvalues001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return setvalues001.PASSED;
+ }
+
+ // check values of static fields for both classes
+ static boolean checkValues() {
+ int different = 0;
+ log.display("Checking that values have been set correctly:");
+
+ // check value of the field
+ if (TestedClass.booleanValue != TargetValuesClass.booleanValue) {
+ different++;
+ log.complain(" booleanValue = " + TestedClass.booleanValue + "\n"
+ + " setting: " + OriginalValuesClass.booleanValue
+ + " -> " + TargetValuesClass.booleanValue);
+ if (TestedClass.booleanValue == OriginalValuesClass.booleanValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" booleanValue: " + OriginalValuesClass.booleanValue
+ + " -> " + TargetValuesClass.booleanValue);
+ }
+
+ // check value of the field
+ if (TestedClass.byteValue != TargetValuesClass.byteValue) {
+ different++;
+ log.complain(" byteValue = " + TestedClass.byteValue + "\n"
+ + " setting: " + OriginalValuesClass.byteValue
+ + " -> " + TargetValuesClass.byteValue);
+ if (TestedClass.byteValue == OriginalValuesClass.byteValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" byteValue: " + OriginalValuesClass.byteValue
+ + " -> " + TargetValuesClass.byteValue);
+ }
+
+ // check value of the field
+ if (TestedClass.charValue != TargetValuesClass.charValue) {
+ different++;
+ log.complain(" charValue = " + TestedClass.charValue + "\n"
+ + " setting: " + OriginalValuesClass.charValue
+ + " -> " + TargetValuesClass.charValue);
+ if (TestedClass.charValue == OriginalValuesClass.charValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" charValue: " + OriginalValuesClass.charValue
+ + " -> " + TargetValuesClass.charValue);
+ }
+
+ // check value of the field
+ if (TestedClass.intValue != TargetValuesClass.intValue) {
+ different++;
+ log.complain(" intValue = " + TestedClass.intValue + "\n"
+ + " setting: " + OriginalValuesClass.intValue
+ + " -> " + TargetValuesClass.intValue);
+ if (TestedClass.intValue == OriginalValuesClass.intValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" intValue: " + OriginalValuesClass.intValue
+ + " -> " + TargetValuesClass.intValue);
+ }
+
+ // check value of the field
+ if (TestedClass.shortValue != TargetValuesClass.shortValue) {
+ different++;
+ log.complain(" shortValue = " + TestedClass.shortValue + "\n"
+ + " setting: " + OriginalValuesClass.shortValue
+ + " -> " + TargetValuesClass.shortValue);
+ if (TestedClass.shortValue == OriginalValuesClass.shortValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" shortValue: " + OriginalValuesClass.shortValue
+ + " -> " + TargetValuesClass.shortValue);
+ }
+ // check value of the field
+ if (TestedClass.longValue != TargetValuesClass.longValue) {
+ different++;
+ log.complain(" longValue = " + TestedClass.longValue + "\n"
+ + " setting: " + OriginalValuesClass.longValue
+ + " -> " + TargetValuesClass.longValue);
+ if (TestedClass.longValue == OriginalValuesClass.longValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" longValue: " + OriginalValuesClass.longValue
+ + " -> " + TargetValuesClass.longValue);
+ }
+ // check value of the field
+ if (TestedClass.floatValue != TargetValuesClass.floatValue) {
+ different++;
+ log.complain(" floatValue = " + TestedClass.floatValue + "\n"
+ + " setting: " + OriginalValuesClass.floatValue
+ + " -> " + TargetValuesClass.floatValue);
+ if (TestedClass.floatValue == OriginalValuesClass.floatValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" floatValue: " + OriginalValuesClass.floatValue
+ + " -> " + TargetValuesClass.floatValue);
+ }
+ // check value of the field
+ if (TestedClass.doubleValue != TargetValuesClass.doubleValue) {
+ different++;
+ log.complain(" doubleValue = " + TestedClass.doubleValue + "\n"
+ + " setting: " + OriginalValuesClass.doubleValue
+ + " -> " + TargetValuesClass.doubleValue);
+ if (TestedClass.doubleValue == OriginalValuesClass.doubleValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" doubleValue: " + OriginalValuesClass.doubleValue
+ + " -> " + TargetValuesClass.doubleValue);
+ }
+
+ // check value of the field
+ if (TestedClass.stringValue != TargetValuesClass.stringValue) {
+ different++;
+ log.complain(" stringValue = " + TestedClass.stringValue + "\n"
+ + " setting: " + OriginalValuesClass.stringValue
+ + " -> " + TargetValuesClass.stringValue);
+ if (TestedClass.stringValue == OriginalValuesClass.stringValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" stringValue: " + OriginalValuesClass.stringValue
+ + " -> " + TargetValuesClass.stringValue);
+ }
+
+ // check value of the field
+ if (TestedClass.objectValue != TargetValuesClass.objectValue) {
+ different++;
+ log.complain(" objectValue = " + TestedClass.objectValue + "\n"
+ + " setting: " + OriginalValuesClass.objectValue
+ + " -> " + TargetValuesClass.objectValue);
+ if (TestedClass.objectValue == OriginalValuesClass.objectValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" objectValue: " + OriginalValuesClass.objectValue
+ + " -> " + TargetValuesClass.objectValue);
+ }
+
+/*
+ // check value of the field
+ if (TestedClass.Value != TargetValuesClass.Value) {
+ different++;
+ log.complain(" Value = " + TestedClass.Value + "\n"
+ + " setting: " + OriginalValuesClass.Value
+ + " -> " + TargetValuesClass.Value);
+ if (TestedClass.Value == OriginalValuesClass.Value) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" Value: " + OriginalValuesClass.Value
+ + " -> " + TargetValuesClass.Value);
+ }
+*/
+
+ // check taht no any changed value differs from target
+ if (different > 0) {
+ log.complain("Values of " + different + " fields have not been set correctly");
+ return false;
+ }
+
+ log.display("Values of all fields have been set correctly");
+ return true;
+ }
+
+ // class with the original values of static fields
+ public static class OriginalValuesClass {
+ static final boolean booleanValue = true;
+ static final byte byteValue = (byte)0x01;
+ static final char charValue = 'Z';
+ static final int intValue = 100;
+ static final short shortValue = (short)10;
+ static final long longValue = (long)1000000;
+ static final float floatValue = (float)3.14;
+ static final double doubleValue = (double)2.8e-12;
+ static final String stringValue = "text";
+ static final Object objectValue = new OriginalValuesClass();
+ }
+
+ // class with the original values of static fields
+ public static class TargetValuesClass {
+ static final boolean booleanValue = false;
+ static final byte byteValue = (byte)0x0F;
+ static final char charValue = 'A';
+ static final int intValue = 999;
+ static final short shortValue = (short)88;
+ static final long longValue = (long)11111111;
+ static final float floatValue = (float)7.19;
+ static final double doubleValue = (double)4.6e24;
+ static final String stringValue = "new text";
+ static final Object objectValue = new TargetValuesClass();
+ }
+
+ // tested class with own static fields values
+ public static class TestedClass {
+ private static boolean booleanValue = OriginalValuesClass.booleanValue;
+ private static byte byteValue = OriginalValuesClass.byteValue;
+ protected static char charValue = OriginalValuesClass.charValue;
+ protected static int intValue = OriginalValuesClass.intValue;
+ public static short shortValue = OriginalValuesClass.shortValue;
+ public static long longValue = OriginalValuesClass.longValue;
+ static float floatValue = OriginalValuesClass.floatValue;
+ static double doubleValue = OriginalValuesClass.doubleValue;
+ static String stringValue = OriginalValuesClass.stringValue;
+ static Object objectValue = OriginalValuesClass.objectValue;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/Superclass/superclass001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ClassType.Superclass;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ClassType.Superclass.
+ *
+ * See superclass001.README for description of test execution.
+ *
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class superclass001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ClassType.Superclass";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "superclass001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ClassType.Superclass";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ClassType.Superclass;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // tested superclass name and signature constants
+ static final String TESTED_SUPERCLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "Superclass";
+ static final String TESTED_SUPERCLASS_SIGNATURE = "L" + TESTED_SUPERCLASS_NAME.replace('.', '/') + ";";
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new superclass001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debugee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debugee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debugee for classID of tested class
+ log.display("Getting classID of tested class by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debugee for classID of tested superclass
+ log.display("Getting classID of tested superclass by signature:\n"
+ + " " + TESTED_SUPERCLASS_SIGNATURE);
+ long superclassID = debugee.getReferenceTypeID(TESTED_SUPERCLASS_SIGNATURE);
+ log.display(" got classID: " + superclassID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(classID, superclassID);
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception:\n" + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received form debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Perform testing JDWP command for specified classID's.
+ */
+ void testCommand(long classID, long superclassID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ log.display(" ClassID: " + classID);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addReferenceTypeID(classID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet: " + e.getMessage());
+ success = false;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract and check superclass ID
+ try {
+ long superclass = reply.getReferenceTypeID();
+ log.display(" superclass: " + superclass);
+
+ if (superclass != superclassID) {
+ log.complain("Unexpected classID for superclass in the reply packet:" + superclass
+ + " (expected: " + superclassID + ")");
+ success = false;
+ }
+ } catch (BoundException e) {
+ log.complain("Unable to extract superclass ID from reply packet:\n" + e.getMessage());
+ success = false;
+ }
+
+ // check for extra data in reply packet
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/Superclass/superclass001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ClassType/Superclass/superclass001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ClassType
+ * command: Superclass
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test check that the
+ * returned classID for a superclass is equal to the expected one.
+ * Test consists of two compoments:
+ * debugger: superclass001
+ * debuggee: superclass001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger prepares for testing JDWP command and obtains
+ * classID's for the tested class and its superclass.
+ * Then, debugger creates command packet for Superclass command with the
+ * found classID as an argument, writes packet to the transport channel,
+ * and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts classID of a superclass. Also test checks that extracted
+ * classID for a superclass is equal to the expected one.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ClassType.Superclass.superclass001
+ * nsk.jdwp.ClassType.Superclass.superclass001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ClassType.Superclass.superclass001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ClassType/Superclass/superclass001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ClassType.Superclass;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class superclass001a {
+
+ public static void main(String args[]) {
+ superclass001a _superclass001a = new superclass001a();
+ System.exit(superclass001.JCK_STATUS_BASE + _superclass001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // meke communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // ensure tested class loaded
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + superclass001.READY);
+ pipe.println(superclass001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + superclass001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (! signal.equals(superclass001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + superclass001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return superclass001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return superclass001.PASSED;
+ }
+
+ // indirect superclass for tested class
+ public static class IndirectSuperclass {
+ int foo = 0;
+ public IndirectSuperclass() {
+ foo = 100;
+ }
+ }
+
+ // direct superclass for tested class
+ public static class Superclass extends IndirectSuperclass {
+ public Superclass() {
+ super();
+ }
+ }
+
+ // tested class
+ public static class TestedClass extends Superclass {
+ public TestedClass() {
+ super();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/BREAKPOINT/breakpoint001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,653 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.BREAKPOINT;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP event: BREAKPOINT.
+ *
+ * See breakpoint001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP event is tested in the method waitForTestedEvent().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class breakpoint001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Event.BREAKPOINT";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "breakpoint001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP event constants
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.BREAKPOINT;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+
+ // name and signature of the tested class
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+ static final String TESTED_THREAD_NAME = "TestedThread";
+
+ // name of field and method of tested class
+ static final String THREAD_FIELD_NAME = "thread";
+ static final String TESTED_METHOD_NAME = "run";
+ static final int BREAKPOINT_LINE = breakpoint001a.BREAKPOINT_LINE;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // obtained data
+ long testedClassID = 0;
+ long testedThreadID = 0;
+ long testedMethodID = 0;
+ JDWP.Location testedLocation = null;
+ int eventRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new breakpoint001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // get debuggee prepared for testing
+ log.display("\n>>> Getting prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP event
+ log.display("\n>>> Testing JDWP event \n");
+
+ // request tested event
+ log.display("Making request for BREAKPOINT event at: "
+ + TESTED_METHOD_NAME + ":" + BREAKPOINT_LINE);
+ requestTestedEvent();
+ log.display(" ... got requestID: " + eventRequestID);
+ log.display("");
+
+ // resume debuggee
+ log.display("Resumindg debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+ log.display("");
+
+ // wait for tested BREAKPOINT event
+ log.display("Waiting for BREAKPOINT event received");
+ waitForTestedEvent();
+ log.display(" ... event received");
+ log.display("");
+
+ // check if event is for expected thread
+ if (success) {
+ log.display("Checking thread of BREAKPOINT event");
+ checkThread();
+ log.display("");
+ }
+
+
+ // clear tested request for BREAKPOINT event
+ log.display("Clearing request for tested event");
+ clearTestedRequest();
+ log.display(" ... request removed");
+
+ // finish debuggee after testing
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Get debuggee prepared for testing and obtain required data.
+ */
+ void prepareForTest() {
+ // wait for tested class loaded
+ log.display("Waiting for tested class loaded");
+ testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... got classID: " + testedClassID);
+ log.display("");
+
+ // get methodID for tested method
+ log.display("Getting tested methodID by name: " + TESTED_METHOD_NAME);
+ testedMethodID = debugee.getMethodID(testedClassID, TESTED_METHOD_NAME, true);
+ log.display(" ... got methodID: " + testedMethodID);
+
+ // get codeIndex for breakpoint line
+ log.display("Getting codeIndex for breakpoint line: " + BREAKPOINT_LINE);
+ long codeIndex = debugee.getCodeIndex(testedClassID, testedMethodID, BREAKPOINT_LINE);
+ log.display(" ... got index: " + codeIndex);
+
+ // create location for breakpoint
+ log.display("Creating location for breakpoint request");
+ testedLocation = new JDWP.Location(JDWP.TypeTag.CLASS, testedClassID,
+ testedMethodID, codeIndex);
+ log.display(" ... got location: " + testedLocation);
+ }
+
+ /**
+ * Make request for tested BREAKPOINT event.
+ */
+ void requestTestedEvent() {
+ Failure failure = new Failure("Error occured while makind request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Set");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set);
+ log.display(" eventKind: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" eventPolicy: " + TESTED_EVENT_SUSPEND_POLICY);
+ command.addByte(TESTED_EVENT_SUSPEND_POLICY);
+ log.display(" modifiers: " + 1);
+ command.addInt(1);
+ log.display(" modKind: " + JDWP.EventModifierKind.LOCATION_ONLY);
+ command.addByte(JDWP.EventModifierKind.LOCATION_ONLY);
+ log.display(" location: " + testedLocation);
+ command.addLocation(testedLocation);
+ command.setLength();
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ // receive reply packet from debugee
+ ReplyPacket reply = new ReplyPacket();
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract requestID
+ int requestID = 0;
+ try {
+ requestID = reply.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract requestID from request reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // check requestID
+ if (requestID == 0) {
+ log.complain("Unexpected null requestID returned: " + requestID);
+ success = false;
+ throw failure;
+ }
+
+ eventRequestID = requestID;
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Clear request for tested BREAKPOINT event.
+ */
+ void clearTestedRequest() {
+ Failure failure = new Failure("Error occured while clearing request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Clear");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear);
+ log.display(" event: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" requestID: " + eventRequestID);
+ command.addInt(eventRequestID);
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ log.display(" no data");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Wait for tested BREAKPOINT event.
+ */
+ void waitForTestedEvent() {
+
+ EventPacket eventPacket = null;
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for event packet");
+ eventPacket = debugee.getEventPacket(timeout);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.complain("Unable to read tested event packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check suspendPolicy value
+ if (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY) {
+ log.complain("Unexpected SuspendPolicy in tested event packet: " +
+ suspendPolicy + " (expected: " + TESTED_EVENT_SUSPEND_POLICY + ")");
+ success = false;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ long eventThreadID = 0;
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check eventKind
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ log.complain("Unexpected VM_DEATH event received: " +
+ eventKind + " (expected: " + JDWP.EventKind.BREAKPOINT + ")");
+ dead = true;
+ success = false;
+ return;
+ } else if (eventKind != JDWP.EventKind.BREAKPOINT) {
+ log.complain("Unexpected eventKind of event " + i + " in tested event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.BREAKPOINT + ")");
+ success = false;
+ return;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != eventRequestID) {
+ log.complain("Unexpected requestID of event " + i + " in tested event packet: " +
+ requestID + " (expected: " + eventRequestID + ")");
+ success = false;
+ }
+
+ // get threadID
+ long threadID = 0;
+ try {
+ threadID = eventPacket.getObjectID();
+ log.display(" threadID: " + threadID);
+ } catch (BoundException e) {
+ log.complain("Unable to get threadID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // save threadID for further checking
+ testedThreadID = threadID;
+
+ // get location
+ JDWP.Location location = null;
+ try {
+ location = eventPacket.getLocation();
+ log.display(" location: " + location);
+ } catch (BoundException e) {
+ log.complain("Unable to get location of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check location
+ if (location.getTag() != testedLocation.getTag()) {
+ log.complain("Unexpected class tag of location of event " + i
+ + " in tested event packet: " + location.getTag()
+ + " (expected: " + testedLocation.getTag() + ")");
+ success = false;
+ }
+ if (location.getClassID() != testedLocation.getClassID()) {
+ log.complain("Unexpected classID of location of event " + i
+ + " in tested event packet: " + location.getClassID()
+ + " (expected: " + testedLocation.getClassID() + ")");
+ success = false;
+ }
+ if (location.getMethodID() != testedLocation.getMethodID()) {
+ log.complain("Unexpected methodID of location of event " + i
+ + " in tested event packet: " + location.getMethodID()
+ + " (expected: " + testedLocation.getMethodID() + ")");
+ success = false;
+ }
+ if (location.getIndex() != testedLocation.getIndex()) {
+ log.complain("Unexpected codeIndex of location of event " + i
+ + " in tested event packet: " + location.getIndex()
+ + " (expected: " + testedLocation.getIndex() + ")");
+ success = false;
+ }
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event packet parsed");
+ }
+
+ /**
+ * Check if threadID received by BREAKPOINT event is as expected one.
+ */
+ void checkThread() {
+ // get thread value from static field of tested class
+ log.display("Getting thread value from static field: " + THREAD_FIELD_NAME);
+ JDWP.Value value = debugee.getStaticFieldValue(testedClassID, THREAD_FIELD_NAME,
+ JDWP.Tag.THREAD);
+ long threadID = ((Long)value.getValue()).longValue();
+ log.display(" ... got threadID: " + testedThreadID);
+
+ // check threadID
+ if (threadID != testedThreadID) {
+ log.complain("Unexpected threadID of BREAKPOINT event received: " +
+ testedThreadID + " (expected: " + threadID + ")");
+ success = false;
+ } else {
+ log.display("Received threadID is as expected");
+ }
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/BREAKPOINT/breakpoint001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Event/BREAKPOINT/breakpoint001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Event
+ * command: Composite
+ * command set: EventRequest
+ * command: Set, Clear
+ * event kind: BREAKPOINT
+ * Test checks that
+ * 1) debuggee successfully creates BREAKPOINT event request
+ * for particular location
+ * 2) expected BREAKPOINT event is received when the thread
+ * reaches breakpoint and has correct attributes
+ * 3) debuggee successfully removes event request
+ * Test consists of two compoments:
+ * debugger: breakpoint001
+ * debuggee: breakpoint001a
+ * First, debugger uses nsk.share support classes to launch debuggee,
+ * and obtains Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded and makes BREAKPOINT
+ * event request for location into method run() of the tested thread,
+ * When event is received debugger checks if the received event
+ * is for this location and has correct attributes. Then debugger
+ * removes event request.
+ * Finally, debugger disconnects debuggee, waits for it exited
+ * and exits too with proper exit code.
+ * COMMENTS
+ * Test was fixed due to test bug:
+ * 4797978 TEST_BUG: potential race condition in a number of JDWP tests
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Event.BREAKPOINT.breakpoint001
+ * nsk.jdwp.Event.BREAKPOINT.breakpoint001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Event.BREAKPOINT.breakpoint001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/BREAKPOINT/breakpoint001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.Event.BREAKPOINT;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class breakpoint001a {
+
+ static final int BREAKPOINT_LINE = 91;
+
+ static ArgumentHandler argumentHandler = null;
+ static Log log = null;
+
+ public static void main(String args[]) {
+ breakpoint001a _breakpoint001a = new breakpoint001a();
+ System.exit(breakpoint001.JCK_STATUS_BASE + _breakpoint001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // create tested thread
+ log.display("Creating tested thread");
+ TestedClass.thread = new TestedClass(breakpoint001.TESTED_THREAD_NAME);
+ log.display(" ... thread created");
+
+ // start tested thread
+ log.display("Starting tested thread");
+ TestedClass.thread.start();
+ log.display(" ... thread started");
+
+ // wait for thread finished
+ try {
+ log.display("Waiting for tested thread finished");
+ TestedClass.thread.join();
+ log.display(" ... thread finished");
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for tested thread finished");
+ return breakpoint001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return breakpoint001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass extends Thread {
+ public static volatile TestedClass thread = null;
+
+ public TestedClass(String name) {
+ super(name);
+ }
+
+ public void run() {
+ log.display("Tested thread: started");
+ log.display("Breakpoint line reached");
+ // next line is for breakpoint
+ int foo = 0; // BREAKPOINT_LINE
+ log.display("Breakpoint line passed");
+ log.display("Tested thread: finished");
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_PREPARE/clsprepare001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,607 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.CLASS_PREPARE;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP event: CLASS_PREPARE.
+ *
+ * See clsprepare001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP event is tested in the method waitForTestedEvent().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class clsprepare001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Event.CLASS_PREPARE";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "clsprepare001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP event constants
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.CLASS_PREPARE;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+
+ // name and signature of the tested class
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // obtained data
+ int eventRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new clsprepare001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // make request for CLASS_PREPARE event
+ log.display("\n>>> Making request for tested event \n");
+
+ log.display("Making request for CLASS_PREPARE event for class:\n\t"
+ + TESTED_CLASS_NAME);
+ requestTestedEvent();
+ log.display(" ... got requestID: " + eventRequestID);
+
+ // resume debuggee
+ log.display("Resumindg debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for tested CLASS_PREPARE event
+ log.display("\n>>> Testing JDWP event \n");
+ waitForTestedEvent();
+
+ // clear tested request for CLASS_PREPARE event
+ log.display("\n>>> Clearing request for tested event \n");
+ clearTestedRequest();
+
+ // finish debuggee after testing
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Make request for tested CLASS_PREPARE event.
+ */
+ void requestTestedEvent() {
+ Failure failure = new Failure("Error occured while makind request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Set");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set);
+ log.display(" eventKind: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" eventPolicy: " + TESTED_EVENT_SUSPEND_POLICY);
+ command.addByte(TESTED_EVENT_SUSPEND_POLICY);
+ log.display(" modifiers: " + 1);
+ command.addInt(1);
+ log.display(" modKind: " + JDWP.EventModifierKind.CLASS_MATCH);
+ command.addByte(JDWP.EventModifierKind.CLASS_MATCH);
+ log.display(" classPattern: " + TESTED_CLASS_NAME);
+ command.addString(TESTED_CLASS_NAME);
+ command.setLength();
+ log.display(" ... command packet composed");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract requestID
+ int requestID = 0;
+ try {
+ requestID = reply.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract requestID from request reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // check requestID
+ if (requestID == 0) {
+ log.complain("Unexpected null requestID returned: " + requestID);
+ success = false;
+ throw failure;
+ }
+
+ eventRequestID = requestID;
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Clear request for tested CLASS_PREPARE event.
+ */
+ void clearTestedRequest() {
+ Failure failure = new Failure("Error occured while clearing request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Clear");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear);
+ log.display(" event: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" requestID: " + eventRequestID);
+ command.addInt(eventRequestID);
+ log.display(" ... command packet composed");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ log.display(" no data");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Wait for tested CLASS_PREPARE event.
+ */
+ void waitForTestedEvent() {
+
+ EventPacket eventPacket = null;
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for event packet (for " + timeout + "ms timeout)");
+ eventPacket = debugee.getEventPacket(timeout);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.complain("Unable to read tested event packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check suspendPolicy value
+ if (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY) {
+ log.complain("Unexpected SuspendPolicy in tested event packet: " +
+ suspendPolicy + " (expected: " + TESTED_EVENT_SUSPEND_POLICY + ")");
+ success = false;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check eventKind
+ if (eventKind != JDWP.EventKind.CLASS_PREPARE) {
+ log.complain("Unexpected eventKind of event " + i + " in tested event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.CLASS_PREPARE + ")");
+ success = false;
+ return;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != eventRequestID) {
+ log.complain("Unexpected requestID of event " + i + " in tested event packet: " +
+ requestID + " (expected: " + eventRequestID + ")");
+ success = false;
+ }
+
+ // get threadID
+ long threadID = 0;
+ try {
+ threadID = eventPacket.getObjectID();
+ log.display(" threadID: " + threadID);
+ } catch (BoundException e) {
+ log.complain("Unable to get threadID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check threadID
+ if (threadID == 0) {
+ log.complain("Unexpected null threadID of event " + i + " in tested event packet: " +
+ threadID);
+ success = false;
+ }
+
+ // get refTypeTag
+ byte refTypeTag = 0;
+ try {
+ refTypeTag = eventPacket.getByte();
+ log.display(" refTypeTag: " + refTypeTag);
+ } catch (BoundException e) {
+ log.complain("Unable to get refTypeTag of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check refTypeGag
+ if (refTypeTag != JDWP.TypeTag.CLASS) {
+ log.complain("Unexpected refTypeTag of event " + i + " in tested event packet: " +
+ refTypeTag + " (expected: " + JDWP.TypeTag.CLASS + ")");
+ success = false;
+ }
+
+ // get referenceTypeID
+ long referenceTypeID = 0;
+ try {
+ referenceTypeID = eventPacket.getReferenceTypeID();
+ log.display(" referenceTypeID: " + referenceTypeID);
+ } catch (BoundException e) {
+ log.complain("Unable to get referenceTypeID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check referenceTypeID
+ if (referenceTypeID == 0) {
+ log.complain("Unexpected null referenceTypeID of event " + i + " in tested event packet: " +
+ referenceTypeID);
+ success = false;
+ }
+
+ // get signature
+ String signature = null;
+ try {
+ signature = eventPacket.getString();
+ log.display(" signature: " + signature);
+ } catch (BoundException e) {
+ log.complain("Unable to get class signature of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check signature
+ if (!signature.equals(TESTED_CLASS_SIGNATURE)) {
+ log.complain("Unexpected class signature of event " + i + " in tested event packet: " +
+ signature + " (expected: " + TESTED_CLASS_SIGNATURE + ")");
+ success = false;
+ }
+
+ // get status
+ int status = 0;
+ try {
+ status = eventPacket.getInt();
+ log.display(" status: " + status);
+ } catch (BoundException e) {
+ log.complain("Unable to get class status of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check status
+ if ((status & JDWP.ClassStatus.ERROR) != 0) {
+ log.complain("Unexpected class status of event " + i + " in tested event packet: " +
+ status + " (expected: w/o bit " + JDWP.ClassStatus.ERROR + ")");
+ success = false;
+ }
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event packet parsed");
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_PREPARE/clsprepare001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Event/CLASS_PREPARE/clsprepare001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Event
+ * command: Composite
+ * command set: EventRequest
+ * command: Set, Clear
+ * event kind: CLASS_PREPARE
+ * Test checks that
+ * 1) debuggee successfully creates CLASS_PREPARE event request
+ * for tested class name
+ * 2) expected CLASS_PREPARE event is received when this class
+ * is loaded at the debuggee's startup.
+ * 3) debuggee successfully removes event request
+ * Test consists of two compoments:
+ * debugger: thrstart001
+ * debuggee: thrstart001a
+ * First, debugger uses nsk.share support classes to launch debuggee,
+ * and obtains Transport object, that represents JDWP transport channel.
+ * Next, debugger makes CLASS_PREPARE event request for tested class
+ * and resumes debuggee to permit it to load classes.
+ * When expected CLASS_PREPARE event is received debugger checks
+ * if this event is for tested class and has correct attributes.
+ * Then debugger removes event request.
+ * Finally, debugger disconnects debuggee, waits for it exited
+ * and exits too with proper exit code.
+ * COMMENTS
+ * Test was fixed due to test bug:
+ * 4797978 TEST_BUG: potential race condition in a number of JDWP tests
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Event.CLASS_PREPARE.clsprepare001
+ * nsk.jdwp.Event.CLASS_PREPARE.clsprepare001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Event.CLASS_PREPARE.clsprepare001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_PREPARE/clsprepare001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.CLASS_PREPARE;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class clsprepare001a {
+
+ public static void main(String args[]) {
+ clsprepare001a _clsprepare001a = new clsprepare001a();
+ System.exit(clsprepare001.JCK_STATUS_BASE + _clsprepare001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // ensure tested class is loaded
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+ log.display(" ... object created");
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return clsprepare001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass {
+ int foo = 0;
+
+ public TestedClass() {
+ foo = 1000;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_UNLOAD/clsunload001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,540 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.CLASS_UNLOAD;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP event: CLASS_UNLOAD.
+ *
+ * See clsunload001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP event is tested in the method waitForTestedEvent().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class clsunload001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Event.CLASS_UNLOAD";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "clsunload001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP event constants
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.CLASS_UNLOAD;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+
+ // name and signature of the tested class
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // obtained data
+ int eventRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new clsunload001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // make request for CLASS_UNLOAD event
+ log.display("\n>>> Making request for tested event \n");
+
+ log.display("Making request for CLASS_UNLOAD event for class:\n\t"
+ + TESTED_CLASS_NAME);
+ requestTestedEvent();
+ log.display(" ... got requestID: " + eventRequestID);
+
+ log.display("Resumindg debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for tested CLASS_UNLOAD event
+ log.display("\n>>> Testing JDWP event \n");
+ waitForTestedEvent();
+
+ if (!dead) {
+ // clear tested request for CLASS_UNLOAD event
+ log.display("\n>>> Clearing request for tested event \n");
+ clearTestedRequest();
+
+ // finish debuggee after testing
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Make request for tested CLASS_UNLOAD event.
+ */
+ void requestTestedEvent() {
+ Failure failure = new Failure("Error occured while makind request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Set");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set);
+ log.display(" eventKind: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" eventPolicy: " + TESTED_EVENT_SUSPEND_POLICY);
+ command.addByte(TESTED_EVENT_SUSPEND_POLICY);
+ log.display(" modifiers: " + 1);
+ command.addInt(1);
+ log.display(" modKind: " + JDWP.EventModifierKind.CLASS_MATCH);
+ command.addByte(JDWP.EventModifierKind.CLASS_MATCH);
+ log.display(" classPattern: " + TESTED_CLASS_NAME);
+ command.addString(TESTED_CLASS_NAME);
+ command.setLength();
+ log.display(" ... command packet composed");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract requestID
+ int requestID = 0;
+ try {
+ requestID = reply.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract requestID from request reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // check requestID
+ if (requestID == 0) {
+ log.complain("Unexpected null requestID returned: " + requestID);
+ success = false;
+ throw failure;
+ }
+
+ eventRequestID = requestID;
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Clear request for tested CLASS_UNLOAD event.
+ */
+ void clearTestedRequest() {
+ Failure failure = new Failure("Error occured while clearing request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Clear");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear);
+ log.display(" event: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" requestID: " + eventRequestID);
+ command.addInt(eventRequestID);
+ log.display(" ... command packet composed");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ log.display(" no data");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Wait for tested CLASS_UNLOAD event.
+ */
+ void waitForTestedEvent() {
+
+ EventPacket eventPacket = null;
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for event packet (for " + timeout + "ms timeout)");
+ eventPacket = debugee.getEventPacket(timeout);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.complain("Unable to read tested event packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check if VM_DEATH event
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ log.display("Got VM_DEATH event while waiting for tested event");
+ dead = true;
+ log.println("No CLASS_UNLOAD event occured at all so treat test as PASSED");
+ return;
+ }
+
+ // check eventKind
+ if (eventKind != JDWP.EventKind.CLASS_UNLOAD) {
+ log.complain("Unexpected eventKind of event " + i + " in tested event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.CLASS_UNLOAD + ")");
+ success = false;
+ return;
+ }
+
+ // check suspendPolicy value
+ if (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY) {
+ log.complain("Unexpected SuspendPolicy in tested event packet: " +
+ suspendPolicy + " (expected: " + TESTED_EVENT_SUSPEND_POLICY + ")");
+ success = false;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != eventRequestID) {
+ log.complain("Unexpected requestID of event " + i + " in tested event packet: " +
+ requestID + " (expected: " + eventRequestID + ")");
+ success = false;
+ }
+
+ // get signature
+ String signature = null;
+ try {
+ signature = eventPacket.getString();
+ log.display(" signature: " + signature);
+ } catch (BoundException e) {
+ log.complain("Unable to get class signature of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check signature
+ if (!signature.equals(TESTED_CLASS_SIGNATURE)) {
+ log.complain("Unexpected class signature of event " + i + " in tested event packet: " +
+ signature + " (expected: " + TESTED_CLASS_SIGNATURE + ")");
+ success = false;
+ }
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event packet parsed");
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_UNLOAD/clsunload001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Event/CLASS_UNLOAD/clsunload001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Event
+ * command: Composite
+ * command set: EventRequest
+ * command: Set, Clear
+ * event kind: CLASS_UNLOAD
+ * Test checks that
+ * 1) debuggee successfully creates CLASS_UNLOAD event request
+ * for particular class name
+ * 2) expected CLASS_UNLOAD event is received if this class is
+ * unloaded at debuggee's exit
+ * 3) debuggee successfully removes event request
+ * Test consists of two compoments:
+ * debugger: clsunload001
+ * debuggee: clsunload001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Next, debugger makes request for CLASS_UNLOAD event for tested class,
+ * and resumes debuggee to permit it to exit.
+ * If expected CLASS_UNLOAD event is received debugger checks that
+ * this event if for tested class and has correct attributes.
+ * If no CLASS_UNLOAD event occures, tests pass anyway.
+ * Finally, debugger disconnects debuggee, waits for it exited
+ * and exits too with proper exit code.
+ * COMMENTS
+ * Test was fixed due to test bug:
+ * 4797978 TEST_BUG: potential race condition in a number of JDWP tests
+ * Test was fixed due to test bug:
+ * 4864576 TEST_BUG: copy/paste error in JDWP test clsunload001
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Event.CLASS_UNLOAD.clsunload001
+ * nsk.jdwp.Event.CLASS_UNLOAD.clsunload001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Event.CLASS_UNLOAD.clsunload001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/CLASS_UNLOAD/clsunload001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.CLASS_UNLOAD;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class clsunload001a {
+
+ public static void main(String args[]) {
+ clsunload001a _clsunload001a = new clsunload001a();
+ System.exit(clsunload001.JCK_STATUS_BASE + _clsunload001a.runIt(args, System.err));
+// _clsunload001a.runIt(args, System.err);
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // ensure tested class is loaded
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+ log.display(" ... object created");
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return clsunload001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass {
+ int foo = 0;
+
+ public TestedClass() {
+ foo = 1000;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/Composite/composite001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.Composite;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: Event.Composite.
+ *
+ * See composite001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class composite001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Event.Composite";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "composite001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "Event.Composite";
+ static final int JDWP_COMMAND_ID = JDWP.Command.Event.Composite;
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.VM_START;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new composite001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // test JDWP command
+ log.display("\n>>> Testing JDWP event \n");
+ testCommand();
+
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Test JDWP command.
+ */
+ void testCommand() {
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" suspendPolicy: " + TESTED_EVENT_SUSPEND_POLICY);
+ command.addByte(TESTED_EVENT_SUSPEND_POLICY);
+ log.display(" events: " + 1);
+ command.addInt(1);
+ log.display(" eventKind: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" requestID: " + 0);
+ command.addInt(0);
+ log.display(" threadID: " + 0);
+ command.addObjectID(0);
+ command.setLength();
+ log.display(" ... command packet created");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ log.display("Checking header of reply packet:");
+
+ // extract and check length field
+ int length = reply.getLength();
+ log.display(" length: " + length);
+ if (length != reply.length()) {
+ log.complain("Unexpected value of length field in header of reply packet: "
+ + length + "(actual: " + reply.length() + ")");
+ success = false;
+ }
+
+ // extract and check id field
+ int id = reply.getPacketID();
+ log.display(" id: " + id);
+ if (id != command.getPacketID()) {
+ log.complain("Unexpected value of id field in header of reply packet: "
+ + id + "(expected: " + command.getPacketID() + ")");
+ success = false;
+ }
+
+ // extract and check flags field
+ byte flags = reply.getFlags();
+ log.display(" flags: " + flags);
+ if (flags != JDWP.Flag.REPLY_PACKET) {
+ log.complain("Unexpected value of flags field in header of reply packet: "
+ + flags + "(expected: " + JDWP.Flag.REPLY_PACKET + ")");
+ success = false;
+ }
+
+ // extract and check error field (should be not null!)
+ int error = reply.getErrorCode();
+ log.display(" error: " + error);
+ if (error == JDWP.Error.NONE) {
+ log.complain("Unexpected null value of error field in header of reply packet: "
+ + error + "(expected: not " + JDWP.Error.NONE + ")");
+ success = false;
+ }
+
+ log.display(" ... packet header is parsed");
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet data:");
+ reply.resetPosition();
+
+ // no out data
+ log.display(" no out data");
+
+ log.display(" ... packet data is parsed");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee if not dead
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/Composite/composite001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Event/Composite/composite001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Event
+ * command: Composite
+ * Test checks that debugee replies with some error code when command
+ * Event.Composite with correct event is sent to debugee, because
+ * only debuggee is permited to send such a command to debugger.
+ * Test consists of two compoments:
+ * debugger: composite001
+ * debuggee: composite001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Next, debugger creates command packet for Event.Composite command
+ * with VM_START event and sends it to debuggee. Then debugger reads
+ * reply packet and checks if an error code is in the packet header.
+ * Finally, debugger disconnects debuggee, waits for it exited
+ * and exits too with proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Event.Composite.composite001
+ * nsk.jdwp.Event.Composite.composite001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Event.Composite.composite001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/Composite/composite001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.Composite;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class composite001a {
+
+ public static void main(String args[]) {
+ composite001a _composite001a = new composite001a();
+ System.exit(composite001.JCK_STATUS_BASE + _composite001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return composite001.PASSED;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/EXCEPTION/exception001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,747 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.EXCEPTION;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP event: EXCEPTION.
+ *
+ * See exception001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP event is tested in the method waitForTestedEvent().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class exception001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Event.EXCEPTION";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "exception001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP event constants
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.EXCEPTION;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+
+ // name and signature of the tested class
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedThreadClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+ static final String TESTED_THREAD_NAME = "TestedThread";
+
+ // name of field and method of tested class
+ static final String EXCEPTION_FIELD_NAME = "exception";
+ static final String BREAKPOINT_METHOD_NAME = "run";
+ static final String THROW_METHOD_NAME = "methodForThrow";
+ static final String CATCH_METHOD_NAME = "methodForCatch";
+ static final int BREAKPOINT_LINE = exception001a.BREAKPOINT_LINE;
+ static final int EXCEPTION_THROW_LINE = exception001a.EXCEPTION_THROW_LINE;
+ static final int EXCEPTION_CATCH_LINE = exception001a.EXCEPTION_CATCH_LINE;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // obtained data
+ long testedClassID = 0;
+ long testedThreadID = 0;
+ long catchMethodID = 0;
+ long throwMethodID = 0;
+ JDWP.Location throwLocation = null;
+ JDWP.Location catchLocation = null;
+ long exceptionObjectID = 0;
+ int eventRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new exception001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // prepare debuggee
+ log.display("\n>>> Getting prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP event
+ log.display("\n>>> Testing JDWP event \n");
+ log.display("Making request for EXCEPTION event for class:\n\t"
+ + TESTED_CLASS_NAME);
+ requestTestedEvent();
+ log.display(" ... got requestID: " + eventRequestID);
+ log.display("");
+
+ // resume debuggee
+ log.display("Resumindg debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+ log.display("");
+
+ // wait for tested EXCEPTION event
+ log.display("Waiting for EXCEPTION event received");
+ waitForTestedEvent();
+ log.display(" ... event received");
+ log.display("");
+
+ // clear tested request for EXCEPTION event
+ log.display("Clearing request for tested event");
+ clearTestedRequest();
+ log.display(" ... request removed");
+
+ // finish debuggee after testing
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Get debuggee prepared for testing and obtain required data.
+ */
+ void prepareForTest() {
+ // wait for tested class loaded
+ log.display("Waiting for tested class loaded");
+ testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... got classID: " + testedClassID);
+ log.display("");
+
+ // get methodID for the exception throw method
+ log.display("Getting methodID for exception throw method: " + THROW_METHOD_NAME);
+ throwMethodID = debugee.getMethodID(testedClassID, THROW_METHOD_NAME, true);
+ log.display(" ... got methodID: " + throwMethodID);
+
+ // get codeIndex for exception throw line
+ log.display("Getting codeIndex for exception throw line: " + EXCEPTION_THROW_LINE);
+ long codeIndex = debugee.getCodeIndex(testedClassID, throwMethodID, EXCEPTION_THROW_LINE);
+ log.display(" ... got index: " + codeIndex);
+
+ // create location for exception throw line
+ log.display("Creating location for exception throw");
+ throwLocation = new JDWP.Location(JDWP.TypeTag.CLASS, testedClassID,
+ throwMethodID, codeIndex);
+ log.display(" ... got location: " + throwLocation);
+
+ // get methodID for the exception catch method
+ log.display("Getting methodID for exception catch method: " + CATCH_METHOD_NAME);
+ catchMethodID = debugee.getMethodID(testedClassID, CATCH_METHOD_NAME, true);
+ log.display(" ... got methodID: " + catchMethodID);
+
+ // get codeIndex for exception catch line
+ log.display("Getting codeIndex for exception catch line: " + EXCEPTION_CATCH_LINE);
+ codeIndex = debugee.getCodeIndex(testedClassID, catchMethodID, EXCEPTION_CATCH_LINE);
+ log.display(" ... got index: " + codeIndex);
+
+ // create location for exception catch line
+ log.display("Creating location for exception catch");
+ catchLocation = new JDWP.Location(JDWP.TypeTag.CLASS, testedClassID,
+ catchMethodID, codeIndex);
+ log.display(" ... got location: " + catchLocation);
+ log.display("");
+
+ // wait for breakpoint reached
+ log.display("Waiting for breakpoint reached at: "
+ + BREAKPOINT_METHOD_NAME + ":" + BREAKPOINT_LINE);
+ testedThreadID = debugee.waitForBreakpointReached(testedClassID,
+ BREAKPOINT_METHOD_NAME,
+ BREAKPOINT_LINE,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... breakpoint reached with threadID: " + testedThreadID);
+
+ // get excepion objectID value for static field
+ log.display("Getting exception objectID from static field: " + EXCEPTION_FIELD_NAME);
+ JDWP.Value value = debugee.getStaticFieldValue(testedClassID, EXCEPTION_FIELD_NAME, JDWP.Tag.OBJECT);
+ exceptionObjectID = ((Long)value.getValue()).longValue();
+ log.display(" ... got exception objectID: " + exceptionObjectID);
+ log.display("");
+ }
+
+ /**
+ * Make request for tested EXCEPTION event.
+ */
+ void requestTestedEvent() {
+ Failure failure = new Failure("Error occured while makind request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Set");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set);
+ log.display(" eventKind: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" eventPolicy: " + TESTED_EVENT_SUSPEND_POLICY);
+ command.addByte(TESTED_EVENT_SUSPEND_POLICY);
+ log.display(" modifiers: " + 1);
+ command.addInt(1);
+ log.display(" modKind: " + JDWP.EventModifierKind.CLASS_ONLY + " (CLASS_ONLY)");
+ command.addByte(JDWP.EventModifierKind.CLASS_ONLY);
+ log.display(" classID: " + testedClassID);
+ command.addReferenceTypeID(testedClassID);
+ command.setLength();
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ // receive reply packet from debugee
+ ReplyPacket reply = new ReplyPacket();
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract requestID
+ int requestID = 0;
+ try {
+ requestID = reply.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract requestID from request reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // check requestID
+ if (requestID == 0) {
+ log.complain("Unexpected null requestID returned: " + requestID);
+ success = false;
+ throw failure;
+ }
+
+ eventRequestID = requestID;
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Clear request for tested EXCEPTION event.
+ */
+ void clearTestedRequest() {
+ Failure failure = new Failure("Error occured while clearing request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Clear");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear);
+ log.display(" event: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" requestID: " + eventRequestID);
+ command.addInt(eventRequestID);
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ log.display(" no data");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Wait for tested EXCEPTION event.
+ */
+ void waitForTestedEvent() {
+
+ // receive reply packet from debugee
+ EventPacket eventPacket = null;
+ try {
+ log.display("Waiting for event packet");
+ eventPacket = debugee.getEventPacket(timeout);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.complain("Unable to read tested event packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check suspendPolicy value
+ if (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY) {
+ log.complain("Unexpected SuspendPolicy in tested event packet: " +
+ suspendPolicy + " (expected: " + TESTED_EVENT_SUSPEND_POLICY + ")");
+ success = false;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ long eventThreadID = 0;
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check eventKind
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ log.complain("Unexpected VM_DEATH event received: " +
+ eventKind + " (expected: " + JDWP.EventKind.EXCEPTION + ")");
+ dead = true;
+ success = false;
+ return;
+ } else if (eventKind != JDWP.EventKind.EXCEPTION) {
+ log.complain("Unexpected eventKind of event " + i + " in tested event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.EXCEPTION + ")");
+ success = false;
+ return;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != eventRequestID) {
+ log.complain("Unexpected requestID of event " + i + " in tested event packet: " +
+ requestID + " (expected: " + eventRequestID + ")");
+ success = false;
+ }
+
+ // get threadID
+ long threadID = 0;
+ try {
+ threadID = eventPacket.getObjectID();
+ log.display(" threadID: " + threadID);
+ } catch (BoundException e) {
+ log.complain("Unable to get threadID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check threadID
+ if (threadID != testedThreadID) {
+ log.complain("Unexpected threadID of event " + i + " in tested event packet: " +
+ threadID + " (expected: " + testedThreadID + ")");
+ success = false;
+ }
+
+ // get throw location
+ JDWP.Location location = null;
+ try {
+ location = eventPacket.getLocation();
+ log.display(" throw_location: " + location);
+ } catch (BoundException e) {
+ log.complain("Unable to get throw location of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check location
+ checkLocation(location, throwLocation, i, EXCEPTION_THROW_LINE, "throw");
+
+ // get exception tag
+ byte tag = 0;
+ try {
+ tag = eventPacket.getByte();
+ log.display(" exception_tag: " + tag);
+ } catch (BoundException e) {
+ log.complain("Unable to get exception tag of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check tag
+ if (tag != JDWP.Tag.OBJECT) {
+ log.complain("Unexpected exception tag of event " + i + " in tested event packet: " +
+ tag + " (expected: " + JDWP.Tag.OBJECT + ")");
+ success = false;
+ }
+
+ // get exception objectID
+ long objectID = 0;
+ try {
+ objectID = eventPacket.getObjectID();
+ log.display(" exception_objectID: " + objectID);
+ } catch (BoundException e) {
+ log.complain("Unable to get exception objectID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check threadID
+ if (objectID != exceptionObjectID) {
+ log.complain("Unexpected exception objectID of event " + i + " in tested event packet: " +
+ objectID + " (expected: " + exceptionObjectID + ")");
+ success = false;
+ }
+
+ // get catch location
+ location = null;
+ try {
+ location = eventPacket.getLocation();
+ log.display(" catch_location: " + location);
+ } catch (BoundException e) {
+ log.complain("Unable to get catch location of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check location
+ checkLocation(location, catchLocation, i, EXCEPTION_CATCH_LINE, "catch");
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event packet parsed");
+ }
+
+ /**
+ * Check if given location is equal to the expected one.
+ */
+ void checkLocation(JDWP.Location location, JDWP.Location expectedLocation,
+ int eventNumber, int expectedLine, String kind) {
+ if (location.getTag() != expectedLocation.getTag()) {
+ log.complain("Unexpected class tag of " + kind + " location of event "
+ + eventNumber + " in tested event packet: " + location.getTag()
+ + " (expected: " + expectedLocation.getTag() + ")");
+ success = false;
+ }
+ if (location.getClassID() != expectedLocation.getClassID()) {
+ log.complain("Unexpected classID of " + kind + " location of event "
+ + eventNumber + " in tested event packet: " + location.getClassID()
+ + " (expected: " + expectedLocation.getClassID() + ")");
+ success = false;
+ }
+ if (location.getMethodID() != expectedLocation.getMethodID()) {
+ log.complain("Unexpected methodID of " + kind + " location of event "
+ + eventNumber + " in tested event packet: " + location.getMethodID()
+ + " (expected: " + expectedLocation.getMethodID() + ")");
+ success = false;
+ }
+ if (location.getIndex() != expectedLocation.getIndex()) {
+/*
+ log.complain("Unexpected codeIndex of " + kind + " location of event " + i
+ + " in tested event packet: " + location.getIndex()
+ + " (expected: " + expectedLocation.getIndex() + ")");
+ success = false;
+*/
+ try {
+ // find approximate line number for location
+ int lineNumber = debugee.getLineNumber(location, true);
+ if (lineNumber != expectedLine) {
+ log.complain("Unexpected line number of " + kind + " location of event "
+ + eventNumber + " in tested event packet: " + lineNumber
+ + " (expected: " + expectedLine + ")");
+ success = false;
+ } else {
+ log.display("Unexpected codeIndex of " + kind + " location: " + location.getIndex()
+ + " (expected: " + expectedLocation.getIndex() + ")");
+ log.display("Though line number of catch location is as expected: "
+ + expectedLine);
+ }
+ } catch (Failure e) {
+ log.complain("Unable to get line number for " + kind + " location of event "
+ + eventNumber + " in tested event packet:\n\t" + e.getMessage());
+ success = false;
+ }
+ }
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/EXCEPTION/exception001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Event/EXCEPTION/exception001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Event
+ * command: Composite
+ * command set: EventRequest
+ * command: Set, Clear
+ * event kind: EXCEPTION
+ * Test checks that
+ * 1) debuggee successfully creates EXCEPTION event request
+ * occured for particular classID
+ * 2) expected EXCEPTION event is received when the exception
+ * is thrown into debuggee
+ * 3) debuggee successfully removes event request
+ * Test consists of two compoments:
+ * debugger: exception001
+ * debuggee: exception001a
+ * First, debugger uses nsk.share support classes to launch debuggee,
+ * and obtains Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded and obtains expected
+ * locations for throw and catch clauses of the tested exception.
+ * Then debugger waits for a breakpoint for tested thread is reached,
+ * end makes request for EXCEPTION event for found classID.
+ * When event is received debugger checks if the received event is for
+ * expected request, thread, and has correct locations of throw and
+ * catch clauses. Then debugger removes event request.
+ * Finally, debugger disconnects debuggee, waits for it exited
+ * and exits too with proper exit code.
+ * COMMENTS
+ * The test was fixed due to the following bug:
+ * 4740123 Wrong exception catch location in ExceptionEvent
+ * Test was fixed due to test bug:
+ * 4797978 TEST_BUG: potential race condition in a number of JDWP tests
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Event.EXCEPTION.exception001
+ * nsk.jdwp.Event.EXCEPTION.exception001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Event.EXCEPTION.exception001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/EXCEPTION/exception001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.Event.EXCEPTION;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class exception001a {
+
+ static final int BREAKPOINT_LINE = 102;
+ static final int EXCEPTION_THROW_LINE = 114;
+ static final int EXCEPTION_CATCH_LINE = 121; // line number was changed due to 4740123
+
+ static ArgumentHandler argumentHandler = null;
+ static Log log = null;
+
+ public static void main(String args[]) {
+ exception001a _exception001a = new exception001a();
+ System.exit(exception001.JCK_STATUS_BASE + _exception001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // create tested thread
+ log.display("Creating tested thread");
+ TestedThreadClass thread = new TestedThreadClass(exception001.TESTED_THREAD_NAME);
+ log.display(" ... thread created");
+
+ // create tested exception
+ log.display("Creating tested exception object");
+ TestedThreadClass.exception = new TestedExceptionClass("tested exception");
+ log.display(" ... exception object created");
+
+ // start tested thread
+ log.display("Starting tested thread");
+ thread.start();
+ log.display(" ... thread started");
+
+ // wait for thread finished
+ try {
+ log.display("Waiting for tested thread finished");
+ thread.join();
+ log.display(" ... thread finished");
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for tested thread finished");
+ return exception001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return exception001.PASSED;
+ }
+
+ // tested class
+ public static class TestedThreadClass extends Thread {
+
+ // static field with tested exception object
+ public static volatile TestedExceptionClass exception = null;
+
+ public TestedThreadClass(String name) {
+ super(name);
+ }
+
+ // reach breakpoint before testing exception
+ public void run() {
+ log.display("Tested thread: started");
+
+ log.display("Breakpoint line reached");
+ // next line is for breakpoint
+ int foo = 0; // BREAKPOINT_LINE
+ log.display("Breakpoint line passed");
+
+ methodForCatch();
+
+ log.display("Tested thread: finished");
+ }
+
+ // throw tested exception
+ public void methodForThrow() throws TestedExceptionClass {
+ log.display("Throwing tested exception:\n\t" + exception);
+ // next line is location of exception throw
+ throw exception; // EXCEPTION_THROW_LINE
+ }
+
+ // catch tested exception
+ public void methodForCatch() {
+ try {
+ methodForThrow();
+ } catch (TestedExceptionClass e) { // EXCEPTION_CATCH_LINE
+ // due to evaluation of 4740123: "the first instruction at the target
+ // of the exception is code to assign to the formal parameter"
+ log.display("Caught tested exception:\n\t" + e);
+ }
+ }
+
+ }
+
+ // tested exception class
+ public static class TestedExceptionClass extends Exception {
+ public TestedExceptionClass(String message) {
+ super(message);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_ACCESS/fldaccess001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,804 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.FIELD_ACCESS;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP event: FIELD_ACCESS.
+ *
+ * See fldaccess001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP event is tested in the method waitForTestedEvent().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class fldaccess001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // VM capability constatnts
+ static final int VM_CAPABILITY_NUMBER = JDWP.Capability.CAN_WATCH_FIELD_ACCESS;
+ static final String VM_CAPABILITY_NAME = "canWatchFieldAccess";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Event.FIELD_ACCESS";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "fldaccess001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP event constants
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.FIELD_ACCESS;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+
+ // name and signature of the tested class
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedObjectClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+ static final String TESTED_THREAD_NAME = "TestedThread";
+
+ // name of field and method of tested class
+ static final String OBJECT_FIELD_NAME = "object";
+ static final String VALUE_FIELD_NAME = "value";
+ static final String TESTED_METHOD_NAME = "methodForAccess";
+ static final String BREAKPOINT_METHOD_NAME = "run";
+ static final int BREAKPOINT_LINE = fldaccess001a.BREAKPOINT_LINE;
+ static final int FIELD_ACCESS_LINE = fldaccess001a.FIELD_ACCESS_LINE;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // obtained data
+ long testedClassID = 0;
+ long testedThreadID = 0;
+ long testedMethodID = 0;
+ long testedFieldID = 0;
+ long testedObjectID = 0;
+ JDWP.Location testedLocation = null;
+ int eventRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new fldaccess001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // check for VM capability
+ log.display("\n>>> Checking VM capability \n");
+ log.display("Getting VM capability: " + VM_CAPABILITY_NAME);
+ boolean capable = debugee.getCapability(VM_CAPABILITY_NUMBER, VM_CAPABILITY_NAME);
+ log.display(" ... got VM capability: " + capable);
+
+ // exit as PASSED if this capability is not supported
+ if (!capable) {
+ out.println("TEST PASSED: unsupported VM capability: "
+ + VM_CAPABILITY_NAME);
+ return PASSED;
+ }
+
+ // prepare debuggee
+ log.display("\n>>> Getting prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP event
+ log.display("\n>>> Testing JDWP event \n");
+ log.display("Making request for FIELD_ACCESS event for field: "
+ + VALUE_FIELD_NAME);
+ requestTestedEvent();
+ log.display(" ... got requestID: " + eventRequestID);
+ log.display("");
+
+ // resume debuggee
+ log.display("Resumindg debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+ log.display("");
+
+ // wait for tested FIELD_ACCESS event
+ log.display("Waiting for FIELD_ACCESS event received");
+ waitForTestedEvent();
+ log.display(" ... event received");
+ log.display("");
+
+ // clear tested request for FIELD_ACCESS event
+ log.display("Clearing request for tested event");
+ clearTestedRequest();
+ log.display(" ... request removed");
+
+ // finish debuggee after testing
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Get debuggee prepared for testing and obtain required data.
+ */
+ void prepareForTest() {
+ // wait for tested class loaded
+ log.display("Waiting for tested class loaded:\n\t" + TESTED_CLASS_NAME);
+ testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... class loaded with classID: " + testedClassID);
+ log.display("");
+
+ // get fieldID for the tested field
+ log.display("Getting tested fieldID for field name: " + VALUE_FIELD_NAME);
+ testedFieldID = debugee.getClassFieldID(testedClassID, VALUE_FIELD_NAME, true);
+ log.display(" ... got fieldID: " + testedFieldID);
+
+ // get methodID for the tested method
+ log.display("Getting tested methodID for method name: " + TESTED_METHOD_NAME);
+ testedMethodID = debugee.getMethodID(testedClassID, TESTED_METHOD_NAME, true);
+ log.display(" ... got methodID: " + testedMethodID);
+
+ // get codeIndex for field access line
+ log.display("Getting codeIndex for field acccess line: " + FIELD_ACCESS_LINE);
+ long codeIndex = debugee.getCodeIndex(testedClassID, testedMethodID, FIELD_ACCESS_LINE);
+ log.display(" ... got index: " + codeIndex);
+
+ // create location for method entry line
+ log.display("Creating location for field access line");
+ testedLocation = new JDWP.Location(JDWP.TypeTag.CLASS, testedClassID,
+ testedMethodID, codeIndex);
+ log.display(" ... got location: " + testedLocation);
+ log.display("");
+
+ // wait for breakpoint reached
+ log.display("Waiting for breakpoint reached at: "
+ + BREAKPOINT_METHOD_NAME + ":" + BREAKPOINT_LINE);
+ testedThreadID = debugee.waitForBreakpointReached(testedClassID,
+ BREAKPOINT_METHOD_NAME,
+ BREAKPOINT_LINE,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... breakpoint reached with threadID: " + testedThreadID);
+ log.display("");
+
+ // get objectID of the tested object from static field
+ log.display("Getting tested objectID from static field: " + OBJECT_FIELD_NAME);
+ JDWP.Value value = debugee.getStaticFieldValue(testedClassID, OBJECT_FIELD_NAME, JDWP.Tag.OBJECT);
+ testedObjectID = ((Long)value.getValue()).longValue();
+ log.display(" ... got objectID: " + testedObjectID);
+ }
+
+ /**
+ * Make request for tested FIELD_ACCESS event.
+ */
+ void requestTestedEvent() {
+ Failure failure = new Failure("Error occured while makind request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Set");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set);
+ log.display(" eventKind: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" eventPolicy: " + TESTED_EVENT_SUSPEND_POLICY);
+ command.addByte(TESTED_EVENT_SUSPEND_POLICY);
+ log.display(" modifiers: " + 1);
+ command.addInt(1);
+ log.display(" modKind: " + JDWP.EventModifierKind.FIELD_ONLY + " (FIELD_ONLY)");
+ command.addByte(JDWP.EventModifierKind.FIELD_ONLY);
+ log.display(" classID: " + testedClassID);
+ command.addReferenceTypeID(testedClassID);
+ log.display(" fieldID: " + testedFieldID);
+ command.addFieldID(testedFieldID);
+/*
+ log.display(" modifiers: " + 1);
+ command.addInt(1);
+ log.display(" modKind: " + JDWP.EventModifierKind.CLASS_ONLY + " (CLASS_ONLY)");
+ command.addByte(JDWP.EventModifierKind.CLASS_ONLY);
+ log.display(" classID: " + testedClassID);
+ command.addReferenceTypeID(testedClassID);
+*/
+ command.setLength();
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ // receive reply packet from debugee
+ ReplyPacket reply = new ReplyPacket();
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract requestID
+ int requestID = 0;
+ try {
+ requestID = reply.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract requestID from request reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // check requestID
+ if (requestID == 0) {
+ log.complain("Unexpected null requestID returned: " + requestID);
+ success = false;
+ throw failure;
+ }
+
+ eventRequestID = requestID;
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Clear request for tested FIELD_ACCESS event.
+ */
+ void clearTestedRequest() {
+ Failure failure = new Failure("Error occured while clearing request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Clear");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear);
+ log.display(" event: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" requestID: " + eventRequestID);
+ command.addInt(eventRequestID);
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ log.display(" no data");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Wait for tested FIELD_ACCESS event.
+ */
+ void waitForTestedEvent() {
+
+ EventPacket eventPacket = null;
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for event packet");
+ eventPacket = debugee.getEventPacket(timeout);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.complain("Unable to read tested event packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check suspendPolicy value
+ if (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY) {
+ log.complain("Unexpected SuspendPolicy in tested event packet: " +
+ suspendPolicy + " (expected: " + TESTED_EVENT_SUSPEND_POLICY + ")");
+ success = false;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ long eventThreadID = 0;
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check eventKind
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ log.complain("Unexpected VM_DEATH event received: " +
+ eventKind + " (expected: " + JDWP.EventKind.FIELD_ACCESS + ")");
+ dead = true;
+ success = false;
+ return;
+ } else if (eventKind != JDWP.EventKind.FIELD_ACCESS) {
+ log.complain("Unexpected eventKind of event " + i + " in tested event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.FIELD_ACCESS + ")");
+ success = false;
+ return;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != eventRequestID) {
+ log.complain("Unexpected requestID of event " + i + " in tested event packet: " +
+ requestID + " (expected: " + eventRequestID + ")");
+ success = false;
+ }
+
+ // get threadID
+ long threadID = 0;
+ try {
+ threadID = eventPacket.getObjectID();
+ log.display(" threadID: " + threadID);
+ } catch (BoundException e) {
+ log.complain("Unable to get threadID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check threadID
+ if (threadID != testedThreadID) {
+ log.complain("Unexpected threadID of event " + i + " in tested event packet: " +
+ threadID + " (expected: " + testedThreadID + ")");
+ success = false;
+ }
+
+ // get location
+ JDWP.Location location = null;
+ try {
+ location = eventPacket.getLocation();
+ log.display(" location: " + location);
+ } catch (BoundException e) {
+ log.complain("Unable to get location of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check location
+ checkLocation(location, testedLocation, i, FIELD_ACCESS_LINE);
+
+ // get type tag
+ byte refTypeTag = 0;
+ try {
+ refTypeTag = eventPacket.getByte();
+ log.display(" refTypeTag: " + refTypeTag);
+ } catch (BoundException e) {
+ log.complain("Unable to get reftypetag of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check type tag
+ if (refTypeTag != JDWP.TypeTag.CLASS) {
+ log.complain("Unexpected refTypeTag of event " + i + " in tested event packet: " +
+ refTypeTag + " (expected: " + JDWP.TypeTag.CLASS + ")");
+ success = false;
+ }
+
+ // get typeID
+ long typeID = 0;
+ try {
+ typeID = eventPacket.getReferenceTypeID();
+ log.display(" typeID: " + typeID);
+ } catch (BoundException e) {
+ log.complain("Unable to get typeID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check typeID
+ if (typeID != testedClassID) {
+ log.complain("Unexpected typeID of event " + i + " in tested event packet: " +
+ typeID + " (expected: " + testedClassID + ")");
+ success = false;
+ }
+
+ // get fieldID
+ long fieldID = 0;
+ try {
+ fieldID = eventPacket.getFieldID();
+ log.display(" fieldID: " + fieldID);
+ } catch (BoundException e) {
+ log.complain("Unable to get fieldID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check fieldID
+ if (fieldID != testedFieldID) {
+ log.complain("Unexpected fieldID of event " + i + " in tested event packet: " +
+ fieldID + " (expected: " + testedFieldID + ")");
+ success = false;
+ }
+
+ // get object tag
+ byte objectTag = 0;
+ try {
+ objectTag = eventPacket.getByte();
+ log.display(" objectTag: " + objectTag);
+ } catch (BoundException e) {
+ log.complain("Unable to get object tag of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check object tag
+ if (objectTag != JDWP.Tag.OBJECT) {
+ log.complain("Unexpected object tag of event " + i + " in tested event packet: " +
+ objectTag + " (expected: " + JDWP.Tag.OBJECT + ")");
+ success = false;
+ }
+
+ // get objectID
+ long objectID = 0;
+ try {
+ objectID = eventPacket.getObjectID();
+ log.display(" objectID: " + objectID);
+ } catch (BoundException e) {
+ log.complain("Unable to get objectID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check objectID
+ if (objectID != 0) {
+ log.complain("Unexpected objectID of event " + i + " in tested event packet: " +
+ objectID + " (expected: " + 0 + ")");
+ success = false;
+ }
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event packet parsed");
+ }
+
+ /**
+ * Check if given location is equal to the expected one.
+ */
+ void checkLocation(JDWP.Location location, JDWP.Location expectedLocation,
+ int eventNumber, int expectedLine) {
+ if (location.getTag() != expectedLocation.getTag()) {
+ log.complain("Unexpected class tag of location of event "
+ + eventNumber + " in tested event packet: " + location.getTag()
+ + " (expected: " + expectedLocation.getTag() + ")");
+ success = false;
+ }
+ if (location.getClassID() != expectedLocation.getClassID()) {
+ log.complain("Unexpected classID of location of event "
+ + eventNumber + " in tested event packet: " + location.getClassID()
+ + " (expected: " + expectedLocation.getClassID() + ")");
+ success = false;
+ }
+ if (location.getMethodID() != expectedLocation.getMethodID()) {
+ log.complain("Unexpected methodID of location of event "
+ + eventNumber + " in tested event packet: " + location.getMethodID()
+ + " (expected: " + expectedLocation.getMethodID() + ")");
+ success = false;
+ }
+ if (location.getIndex() != expectedLocation.getIndex()) {
+/*
+ log.complain("Unexpected codeIndex of location of event " + i
+ + " in tested event packet: " + location.getIndex()
+ + " (expected: " + expectedLocation.getIndex() + ")");
+ success = false;
+*/
+ try {
+ // find approximate line number for location
+ int lineNumber = debugee.getLineNumber(location, true);
+ if (lineNumber != expectedLine) {
+ log.complain("Unexpected line number of location of event "
+ + eventNumber + " in tested event packet: " + lineNumber
+ + " (expected: " + expectedLine + ")");
+ success = false;
+ } else {
+ log.display("Unexpected codeIndex of location: " + location.getIndex()
+ + " (expected: " + expectedLocation.getIndex() + ")");
+ log.display("Though line number of catch location is as expected: "
+ + expectedLine);
+ }
+ } catch (Failure e) {
+ log.complain("Unable to get line number for location of event "
+ + eventNumber + " in tested event packet:\n\t" + e.getMessage());
+ success = false;
+ }
+ }
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_ACCESS/fldaccess001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Event/FIELD_ACCESS/fldaccess001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Event
+ * command: Composite
+ * command set: EventRequest
+ * command: Set, Clear
+ * event kind: FIELD_ACCESS
+ * Test checks that
+ * 1) debuggee successfully creates FIELD_ACCESS event request
+ * for particular static filed
+ * 2) expected FIELD_ACCESS event is received when the thread
+ * accesses tested field into debuggee
+ * 3) debuggee successfully removes event request
+ * Test consists of two compoments:
+ * debugger: fldaccess001
+ * debuggee: fldaccess001a
+ * First, debugger uses nsk.share support classes to launch debuggee,
+ * and obtains Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded and obtains fieldID
+ * for tested static field and expected location of FIELD_ACCESS event.
+ * Then debugger waits for breakpoint is reached by a thread in
+ * debuggee makes request for FIELD_ACCESS event for known classID and
+ * fieldID.
+ * When event is received debugger checks if the received event is for
+ * expected request, class, thread, field and location, and has correct
+ * attributes. Then debugger removes event request.
+ * Finally, debugger disconnects debuggee, waits for it exited
+ * and exits too with proper exit code.
+ * COMMENTS
+ * Test was fixed due to test bug:
+ * 4797978 TEST_BUG: potential race condition in a number of JDWP tests
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Event.FIELD_ACCESS.fldaccess001
+ * nsk.jdwp.Event.FIELD_ACCESS.fldaccess001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Event.FIELD_ACCESS.fldaccess001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_ACCESS/fldaccess001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.Event.FIELD_ACCESS;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class fldaccess001a {
+
+ static final int BREAKPOINT_LINE = 114;
+ static final int FIELD_ACCESS_LINE = 125;
+
+ static ArgumentHandler argumentHandler = null;
+ static Log log = null;
+
+ public static void main(String args[]) {
+ fldaccess001a _fldaccess001a = new fldaccess001a();
+ System.exit(fldaccess001.JCK_STATUS_BASE + _fldaccess001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // create tested thread and object
+ log.display("Creating object of the tested class");
+ TestedObjectClass.object = new TestedObjectClass();
+ log.display(" ... object created");
+
+ log.display("Creating tested thread");
+ TestedThreadClass thread = new TestedThreadClass(fldaccess001.TESTED_THREAD_NAME);
+ log.display(" ... thread created");
+
+ // start tested thread
+ log.display("Starting tested thread");
+ thread.start();
+ log.display(" ... thread started");
+
+ // wait for thread finished
+ try {
+ log.display("Waiting for tested thread finished");
+ thread.join();
+ log.display(" ... thread finished");
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for tested thread finished");
+ return fldaccess001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return fldaccess001.PASSED;
+ }
+
+ // tested thread class
+ public static class TestedThreadClass extends Thread {
+
+ public TestedThreadClass(String name) {
+ super(name);
+ }
+
+ public void run() {
+ log.display("Tested thread: started");
+
+ // invoke method of tested object class
+ TestedObjectClass.run();
+
+ log.display("Tested thread: finished");
+ }
+ }
+
+ // tested object class
+ public static class TestedObjectClass {
+
+ // static field with object been accessed
+ public static volatile TestedObjectClass object = null;
+
+ // static field been accessed
+ public static int value = 0;
+
+ // reach breakpoint and then touch field
+ public static void run() {
+ log.display("Breakpoint line reached");
+ // next line is location of BREAKPOINT event
+ int foo = 0; // BREAKPOINT_LINE
+ log.display("Breakpoint line passed");
+
+ // invoke method which accesses the field
+ methodForAccess();
+ }
+
+ // access the tested field
+ public static void methodForAccess() {
+ log.display("Before tested field accessed");
+ // next line is location of FIELD_ACCESS event
+ int foo = value; // FIELD_ACCESS_LINE
+ log.display("After tested field accessed");
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_MODIFICATION/fldmodification001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,825 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.FIELD_MODIFICATION;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP event: FIELD_MODIFICATION.
+ *
+ * See fldmodification001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP event is tested in the method waitForTestedEvent().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class fldmodification001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // VM capability constatnts
+ static final int VM_CAPABILITY_NUMBER = JDWP.Capability.CAN_WATCH_FIELD_MODIFICATION;
+ static final String VM_CAPABILITY_NAME = "canWatchFieldModification";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Event.FIELD_MODIFICATION";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "fldmodification001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP event constants
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.FIELD_MODIFICATION;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+
+ // name and signature of the tested class
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedObjectClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+ static final String TESTED_THREAD_NAME = "TestedThread";
+
+ // name of field and method of tested class
+ static final String OBJECT_FIELD_NAME = "object";
+ static final String VALUE_FIELD_NAME = "value";
+ static final String TESTED_METHOD_NAME = "methodForAccess";
+ static final String BREAKPOINT_METHOD_NAME = "run";
+ static final int BREAKPOINT_LINE = fldmodification001a.BREAKPOINT_LINE;
+ static final int FIELD_MODIFICATION_LINE = fldmodification001a.FIELD_MODIFICATION_LINE;
+ static final int FIELD_MODIFICATION_VALUE = 6574;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // obtained data
+ long testedClassID = 0;
+ long testedThreadID = 0;
+ long testedMethodID = 0;
+ long testedFieldID = 0;
+ long testedObjectID = 0;
+ JDWP.Location testedLocation = null;
+ int eventRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new fldmodification001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // check for VM capability
+ log.display("\n>>> Checking VM capability \n");
+ log.display("Getting VM capability: " + VM_CAPABILITY_NAME);
+ boolean capable = debugee.getCapability(VM_CAPABILITY_NUMBER, VM_CAPABILITY_NAME);
+ log.display(" ... got VM capability: " + capable);
+
+ // exit as PASSED if this capability is not supported
+ if (!capable) {
+ out.println("TEST PASSED: unsupported VM capability: "
+ + VM_CAPABILITY_NAME);
+ return PASSED;
+ }
+
+ // prepare debuggee
+ log.display("\n>>> Getting prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP event
+ log.display("\n>>> Testing JDWP event \n");
+ log.display("Making request for FIELD_MODIFICATION event for field: "
+ + VALUE_FIELD_NAME);
+ requestTestedEvent();
+ log.display(" ... got requestID: " + eventRequestID);
+ log.display("");
+
+ // resume debuggee
+ log.display("Resumindg debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+ log.display("");
+
+ // wait for tested FIELD_MODIFICATION event
+ log.display("Waiting for FIELD_MODIFICATION event received");
+ waitForTestedEvent();
+ log.display(" ... event received");
+ log.display("");
+
+ // clear tested request for FIELD_MODIFICATION event
+ log.display("Clearing request for tested event");
+ clearTestedRequest();
+ log.display(" ... request removed");
+
+ // finish debuggee after testing
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Get debuggee prepared for testing and obtain required data.
+ */
+ void prepareForTest() {
+ // wait for tested class loaded
+ log.display("Waiting for tested class loaded:\n\t" + TESTED_CLASS_NAME);
+ testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... class loaded with classID: " + testedClassID);
+ log.display("");
+
+ // get fieldID for the tested field
+ log.display("Getting tested fieldID for field name: " + VALUE_FIELD_NAME);
+ testedFieldID = debugee.getClassFieldID(testedClassID, VALUE_FIELD_NAME, true);
+ log.display(" ... got fieldID: " + testedFieldID);
+
+ // get methodID for the tested method
+ log.display("Getting tested methodID for method name: " + TESTED_METHOD_NAME);
+ testedMethodID = debugee.getMethodID(testedClassID, TESTED_METHOD_NAME, true);
+ log.display(" ... got methodID: " + testedMethodID);
+
+ // get codeIndex for field access line
+ log.display("Getting codeIndex for field modification line: " + FIELD_MODIFICATION_LINE);
+ long codeIndex = debugee.getCodeIndex(testedClassID, testedMethodID, FIELD_MODIFICATION_LINE);
+ log.display(" ... got index: " + codeIndex);
+
+ // create location for method entry line
+ log.display("Creating location for field modofication line");
+ testedLocation = new JDWP.Location(JDWP.TypeTag.CLASS, testedClassID,
+ testedMethodID, codeIndex);
+ log.display(" ... got location: " + testedLocation);
+ log.display("");
+
+ // wait for breakpoint reached
+ log.display("Waiting for breakpoint reached at: "
+ + BREAKPOINT_METHOD_NAME + ":" + BREAKPOINT_LINE);
+ testedThreadID = debugee.waitForBreakpointReached(testedClassID,
+ BREAKPOINT_METHOD_NAME,
+ BREAKPOINT_LINE,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... breakpoint reached with threadID: " + testedThreadID);
+ log.display("");
+
+ // get objectID of the tested object from static field
+ log.display("Getting tested objectID from static field: " + OBJECT_FIELD_NAME);
+ JDWP.Value value = debugee.getStaticFieldValue(testedClassID, OBJECT_FIELD_NAME, JDWP.Tag.OBJECT);
+ testedObjectID = ((Long)value.getValue()).longValue();
+ log.display(" ... got objectID: " + testedObjectID);
+ }
+
+ /**
+ * Make request for tested FIELD_MODIFICATION event.
+ */
+ void requestTestedEvent() {
+ Failure failure = new Failure("Error occured while makind request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Set");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set);
+ log.display(" eventKind: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" eventPolicy: " + TESTED_EVENT_SUSPEND_POLICY);
+ command.addByte(TESTED_EVENT_SUSPEND_POLICY);
+ log.display(" modifiers: " + 1);
+ command.addInt(1);
+ log.display(" modKind: " + JDWP.EventModifierKind.FIELD_ONLY + " (FIELD_ONLY)");
+ command.addByte(JDWP.EventModifierKind.FIELD_ONLY);
+ log.display(" classID: " + testedClassID);
+ command.addReferenceTypeID(testedClassID);
+ log.display(" fieldID: " + testedFieldID);
+ command.addFieldID(testedFieldID);
+ command.setLength();
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ // receive reply packet from debugee
+ ReplyPacket reply = new ReplyPacket();
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract requestID
+ int requestID = 0;
+ try {
+ requestID = reply.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract requestID from request reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // check requestID
+ if (requestID == 0) {
+ log.complain("Unexpected null requestID returned: " + requestID);
+ success = false;
+ throw failure;
+ }
+
+ eventRequestID = requestID;
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Clear request for tested FIELD_MODIFICATION event.
+ */
+ void clearTestedRequest() {
+ Failure failure = new Failure("Error occured while clearing request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Clear");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear);
+ log.display(" event: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" requestID: " + eventRequestID);
+ command.addInt(eventRequestID);
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ log.display(" no data");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Wait for tested FIELD_MODIFICATION event.
+ */
+ void waitForTestedEvent() {
+
+ EventPacket eventPacket = null;
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for event packet");
+ eventPacket = debugee.getEventPacket(timeout);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.complain("Unable to read tested event packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check suspendPolicy value
+ if (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY) {
+ log.complain("Unexpected SuspendPolicy in tested event packet: " +
+ suspendPolicy + " (expected: " + TESTED_EVENT_SUSPEND_POLICY + ")");
+ success = false;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ long eventThreadID = 0;
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check eventKind
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ log.complain("Unexpected VM_DEATH event received: " +
+ eventKind + " (expected: " + JDWP.EventKind.FIELD_MODIFICATION + ")");
+ dead = true;
+ success = false;
+ return;
+ } else if (eventKind != JDWP.EventKind.FIELD_MODIFICATION) {
+ log.complain("Unexpected eventKind of event " + i + " in tested event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.FIELD_MODIFICATION + ")");
+ success = false;
+ return;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != eventRequestID) {
+ log.complain("Unexpected requestID of event " + i + " in tested event packet: " +
+ requestID + " (expected: " + eventRequestID + ")");
+ success = false;
+ }
+
+ // get threadID
+ long threadID = 0;
+ try {
+ threadID = eventPacket.getObjectID();
+ log.display(" threadID: " + threadID);
+ } catch (BoundException e) {
+ log.complain("Unable to get threadID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check threadID
+ if (threadID != testedThreadID) {
+ log.complain("Unexpected threadID of event " + i + " in tested event packet: " +
+ threadID + " (expected: " + testedThreadID + ")");
+ success = false;
+ }
+
+ // get location
+ JDWP.Location location = null;
+ try {
+ location = eventPacket.getLocation();
+ log.display(" location: " + location);
+ } catch (BoundException e) {
+ log.complain("Unable to get location of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check location
+ checkLocation(location, testedLocation, i, FIELD_MODIFICATION_LINE);
+
+ // get type tag
+ byte refTypeTag = 0;
+ try {
+ refTypeTag = eventPacket.getByte();
+ log.display(" refTypeTag: " + refTypeTag);
+ } catch (BoundException e) {
+ log.complain("Unable to get reftypetag of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check type tag
+ if (refTypeTag != JDWP.TypeTag.CLASS) {
+ log.complain("Unexpected refTypeTag of event " + i + " in tested event packet: " +
+ refTypeTag + " (expected: " + JDWP.TypeTag.CLASS + ")");
+ success = false;
+ }
+
+ // get typeID
+ long typeID = 0;
+ try {
+ typeID = eventPacket.getReferenceTypeID();
+ log.display(" typeID: " + typeID);
+ } catch (BoundException e) {
+ log.complain("Unable to get typeID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check typeID
+ if (typeID != testedClassID) {
+ log.complain("Unexpected typeID of event " + i + " in tested event packet: " +
+ typeID + " (expected: " + testedClassID + ")");
+ success = false;
+ }
+
+ // get fieldID
+ long fieldID = 0;
+ try {
+ fieldID = eventPacket.getFieldID();
+ log.display(" fieldID: " + fieldID);
+ } catch (BoundException e) {
+ log.complain("Unable to get fieldID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check fieldID
+ if (fieldID != testedFieldID) {
+ log.complain("Unexpected fieldID of event " + i + " in tested event packet: " +
+ fieldID + " (expected: " + testedFieldID + ")");
+ success = false;
+ }
+
+ // get object tag
+ byte objectTag = 0;
+ try {
+ objectTag = eventPacket.getByte();
+ log.display(" objectTag: " + objectTag);
+ } catch (BoundException e) {
+ log.complain("Unable to get object tag of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check object tag
+ if (objectTag != JDWP.Tag.OBJECT) {
+ log.complain("Unexpected object tag of event " + i + " in tested event packet: " +
+ objectTag + " (expected: " + JDWP.Tag.OBJECT + ")");
+ success = false;
+ }
+
+ // get objectID
+ long objectID = 0;
+ try {
+ objectID = eventPacket.getObjectID();
+ log.display(" objectID: " + objectID);
+ } catch (BoundException e) {
+ log.complain("Unable to get objectID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check objectID
+ if (objectID != 0) {
+ log.complain("Unexpected objectID of event " + i + " in tested event packet: " +
+ objectID + " (expected: " + 0 + ")");
+ success = false;
+ }
+
+ // get valueToBe
+ JDWP.Value valueToBe = null;
+ try {
+ valueToBe = eventPacket.getValue();
+ log.display(" valueToBe: " + valueToBe);
+ } catch (BoundException e) {
+ log.complain("Unable to get valueToBe of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check value tag
+ byte valueTag = valueToBe.getTag();
+ if (valueTag != JDWP.Tag.INT) {
+ log.complain("Unexpected valueToBe tag of event " + i + " in tested event packet: " +
+ valueTag + " (expected: " + JDWP.Tag.INT + ")");
+ success = false;
+ }
+
+ // check integer value
+ int intValue = ((Integer)valueToBe.getValue()).intValue();
+ if (intValue != FIELD_MODIFICATION_VALUE) {
+ log.complain("Unexpected valueToBe of event " + i + " in tested event packet: " +
+ intValue + " (expected: " + FIELD_MODIFICATION_VALUE + ")");
+ success = false;
+ }
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event packet parsed");
+ }
+
+ /**
+ * Check if given location is equal to the expected one.
+ */
+ void checkLocation(JDWP.Location location, JDWP.Location expectedLocation,
+ int eventNumber, int expectedLine) {
+ if (location.getTag() != expectedLocation.getTag()) {
+ log.complain("Unexpected class tag of location of event "
+ + eventNumber + " in tested event packet: " + location.getTag()
+ + " (expected: " + expectedLocation.getTag() + ")");
+ success = false;
+ }
+ if (location.getClassID() != expectedLocation.getClassID()) {
+ log.complain("Unexpected classID of location of event "
+ + eventNumber + " in tested event packet: " + location.getClassID()
+ + " (expected: " + expectedLocation.getClassID() + ")");
+ success = false;
+ }
+ if (location.getMethodID() != expectedLocation.getMethodID()) {
+ log.complain("Unexpected methodID of location of event "
+ + eventNumber + " in tested event packet: " + location.getMethodID()
+ + " (expected: " + expectedLocation.getMethodID() + ")");
+ success = false;
+ }
+ if (location.getIndex() != expectedLocation.getIndex()) {
+/*
+ log.complain("Unexpected codeIndex of location of event " + i
+ + " in tested event packet: " + location.getIndex()
+ + " (expected: " + expectedLocation.getIndex() + ")");
+ success = false;
+*/
+ try {
+ // find approximate line number for location
+ int lineNumber = debugee.getLineNumber(location, true);
+ if (lineNumber != expectedLine) {
+ log.complain("Unexpected line number of location of event "
+ + eventNumber + " in tested event packet: " + lineNumber
+ + " (expected: " + expectedLine + ")");
+ success = false;
+ } else {
+ log.display("Unexpected codeIndex of location: " + location.getIndex()
+ + " (expected: " + expectedLocation.getIndex() + ")");
+ log.display("Though line number of catch location is as expected: "
+ + expectedLine);
+ }
+ } catch (Failure e) {
+ log.complain("Unable to get line number for location of event "
+ + eventNumber + " in tested event packet:\n\t" + e.getMessage());
+ success = false;
+ }
+ }
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_MODIFICATION/fldmodification001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Event/FIELD_MODIFICATION/fldmodification001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Event
+ * command: Composite
+ * command set: EventRequest
+ * command: Set, Clear
+ * event kind: FIELD_MODIFICATION
+ * Test checks that
+ * 1) debuggee successfully creates FIELD_MODIFICATION event request
+ * for particular static filed
+ * 2) expected FIELD_MODIFICATION event is received when the thread
+ * modifies tested field into debuggee
+ * 3) debuggee successfully removes event request
+ * Test consists of two compoments:
+ * debugger: fldmodification001
+ * debuggee: fldmodification001a
+ * First, debugger uses nsk.share support classes to launch debuggee,
+ * and obtains Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded and obtains fieldID
+ * for tested static field and expected location of FIELD_MODIFICATION
+ * event. Then debugger waits for breakpoint is reached by a thread in
+ * debuggee makes request for FIELD_MODIFICATION event for known
+ * classID and fieldID.
+ * When event is received debugger checks if the received event is for
+ * expected request, class, thread, field and location, and has correct
+ * value to be assigned and ather attributes. Then debugger removes
+ * event request.
+ * Finally, debugger disconnects debuggee, waits for it exited
+ * and exits too with proper exit code.
+ * COMMENTS
+ * Test was fixed due to test bug:
+ * 4797978 TEST_BUG: potential race condition in a number of JDWP tests
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Event.FIELD_MODIFICATION.fldmodification001
+ * nsk.jdwp.Event.FIELD_MODIFICATION.fldmodification001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Event.FIELD_MODIFICATION.fldmodification001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/FIELD_MODIFICATION/fldmodification001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.Event.FIELD_MODIFICATION;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class fldmodification001a {
+
+ static final int BREAKPOINT_LINE = 114;
+ static final int FIELD_MODIFICATION_LINE = 126;
+
+ static ArgumentHandler argumentHandler = null;
+ static Log log = null;
+
+ public static void main(String args[]) {
+ fldmodification001a _fldmodification001a = new fldmodification001a();
+ System.exit(fldmodification001.JCK_STATUS_BASE + _fldmodification001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // create tested thread and object
+ log.display("Creating object of the tested class");
+ TestedObjectClass.object = new TestedObjectClass();
+ log.display(" ... object created");
+
+ log.display("Creating tested thread");
+ TestedThreadClass thread = new TestedThreadClass(fldmodification001.TESTED_THREAD_NAME);
+ log.display(" ... thread created");
+
+ // start tested thread
+ log.display("Starting tested thread");
+ thread.start();
+ log.display(" ... thread started");
+
+ // wait for thread finished
+ try {
+ log.display("Waiting for tested thread finished");
+ thread.join();
+ log.display(" ... thread finished");
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for tested thread finished");
+ return fldmodification001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return fldmodification001.PASSED;
+ }
+
+ // tested thread class
+ public static class TestedThreadClass extends Thread {
+
+ public TestedThreadClass(String name) {
+ super(name);
+ }
+
+ public void run() {
+ log.display("Tested thread: started");
+
+ // invoke method of tested object class
+ TestedObjectClass.run();
+
+ log.display("Tested thread: finished");
+ }
+ }
+
+ // tested object class
+ public static class TestedObjectClass {
+
+ // static field with object been accessed
+ public static volatile TestedObjectClass object = null;
+
+ // static field been accessed
+ public static int value = 0;
+
+ // reach breakpoint and then touch field
+ public static void run() {
+ log.display("Breakpoint line reached");
+ // next line is location of BREAKPOINT event
+ int foo = 0; // BREAKPOINT_LINE
+ log.display("Breakpoint line passed");
+
+ // invoke method which accesses the field
+ methodForAccess();
+ }
+
+ // access the tested field
+ public static void methodForAccess() {
+ log.display("Assigning to tested field new value: "
+ + fldmodification001.FIELD_MODIFICATION_VALUE);
+ // next line is location of FIELD_MODIFICATION event
+ value = fldmodification001.FIELD_MODIFICATION_VALUE; // FIELD_MODIFICATION_LINE
+ log.display("Tested field modified");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_ENTRY/methentry001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,640 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.METHOD_ENTRY;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP event: METHOD_ENTRY.
+ *
+ * See methentry001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP event is tested in the method waitForTestedEvent().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class methentry001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Event.METHOD_ENTRY";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "methentry001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP event constants
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.METHOD_ENTRY;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+
+ // name and signature of the tested class
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+ static final String TESTED_THREAD_NAME = "TestedThread";
+
+ // name of field and method of tested class
+ static final String THREAD_FIELD_NAME = "thread";
+ static final String TESTED_METHOD_NAME = "testedMethod";
+ static final String BREAKPOINT_METHOD_NAME = "run";
+ static final int BREAKPOINT_LINE = methentry001a.BREAKPOINT_LINE;
+ static final int METHOD_ENTRY_LINE = methentry001a.METHOD_ENTRY_LINE;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // obtained data
+ long testedClassID = 0;
+ long testedThreadID = 0;
+ long testedMethodID = 0;
+ JDWP.Location testedLocation = null;
+ int eventRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new methentry001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // prepare debuggee
+ log.display("\n>>> Getting prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP event
+ log.display("\n>>> Testing JDWP event \n");
+ log.display("Making request for METHOD_ENTRY event for class:\n\t"
+ + TESTED_CLASS_NAME);
+ requestTestedEvent();
+ log.display(" ... got requestID: " + eventRequestID);
+ log.display("");
+
+ // resume debuggee
+ log.display("Resumindg debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+ log.display("");
+
+ // wait for tested METHOD_ENTRY event
+ log.display("Waiting for METHOD_ENTRY event received");
+ waitForTestedEvent();
+ log.display(" ... event received");
+ log.display("");
+
+ // clear tested request for METHOD_ENTRY event
+ log.display("Clearing request for tested event");
+ clearTestedRequest();
+ log.display(" ... request removed");
+
+ // finish debuggee after testing
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Get debuggee prepared for testing and obtain required data.
+ */
+ void prepareForTest() {
+ // wait for tested class loaded
+ log.display("Waiting for tested class loaded");
+ testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... got classID: " + testedClassID);
+ log.display("");
+
+ // get methodID for the tested method
+ log.display("Getting tested methodID for method name: " + TESTED_METHOD_NAME);
+ testedMethodID = debugee.getMethodID(testedClassID, TESTED_METHOD_NAME, true);
+ log.display(" ... got methodID: " + testedMethodID);
+
+ // get codeIndex for method entry line
+ log.display("Getting codeIndex for method entry line: " + METHOD_ENTRY_LINE);
+ long codeIndex = debugee.getCodeIndex(testedClassID, testedMethodID, METHOD_ENTRY_LINE);
+ log.display(" ... got index: " + codeIndex);
+
+ // create location for method entry line
+ log.display("Creating location for method entry");
+ testedLocation = new JDWP.Location(JDWP.TypeTag.CLASS, testedClassID,
+ testedMethodID, codeIndex);
+ log.display(" ... got location: " + testedLocation);
+ log.display("");
+
+ // wait for breakpoint reached
+ log.display("Waiting for breakpoint reached at: "
+ + BREAKPOINT_METHOD_NAME + ":" + BREAKPOINT_LINE);
+ testedThreadID = debugee.waitForBreakpointReached(testedClassID,
+ BREAKPOINT_METHOD_NAME,
+ BREAKPOINT_LINE,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... breakpoint reached with threadID: " + testedThreadID);
+ log.display("");
+ }
+
+ /**
+ * Make request for tested METHOD_ENTRY event.
+ */
+ void requestTestedEvent() {
+ Failure failure = new Failure("Error occured while makind request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Set");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set);
+ log.display(" eventKind: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" eventPolicy: " + TESTED_EVENT_SUSPEND_POLICY);
+ command.addByte(TESTED_EVENT_SUSPEND_POLICY);
+ log.display(" modifiers: " + 1);
+ command.addInt(1);
+ log.display(" modKind: " + JDWP.EventModifierKind.CLASS_ONLY);
+ command.addByte(JDWP.EventModifierKind.CLASS_ONLY);
+ log.display(" classID: " + testedClassID);
+ command.addReferenceTypeID(testedClassID);
+ command.setLength();
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract requestID
+ int requestID = 0;
+ try {
+ requestID = reply.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract requestID from request reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // check requestID
+ if (requestID == 0) {
+ log.complain("Unexpected null requestID returned: " + requestID);
+ success = false;
+ throw failure;
+ }
+
+ eventRequestID = requestID;
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Clear request for tested METHOD_ENTRY event.
+ */
+ void clearTestedRequest() {
+ Failure failure = new Failure("Error occured while clearing request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Clear");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear);
+ log.display(" event: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" requestID: " + eventRequestID);
+ command.addInt(eventRequestID);
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ log.display(" no data");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Wait for tested METHOD_ENTRY event.
+ */
+ void waitForTestedEvent() {
+
+ EventPacket eventPacket = null;
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for event packet");
+ eventPacket = debugee.getEventPacket(timeout);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.complain("Unable to read tested event packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check suspendPolicy value
+ if (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY) {
+ log.complain("Unexpected SuspendPolicy in tested event packet: " +
+ suspendPolicy + " (expected: " + TESTED_EVENT_SUSPEND_POLICY + ")");
+ success = false;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ long eventThreadID = 0;
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check eventKind
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ log.complain("Unexpected VM_DEATH event received: " +
+ eventKind + " (expected: " + JDWP.EventKind.METHOD_ENTRY + ")");
+ dead = true;
+ success = false;
+ return;
+ } else if (eventKind != JDWP.EventKind.METHOD_ENTRY) {
+ log.complain("Unexpected eventKind of event " + i + " in tested event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.METHOD_ENTRY + ")");
+ success = false;
+ return;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != eventRequestID) {
+ log.complain("Unexpected requestID of event " + i + " in tested event packet: " +
+ requestID + " (expected: " + eventRequestID + ")");
+ success = false;
+ }
+
+ // get threadID
+ long threadID = 0;
+ try {
+ threadID = eventPacket.getObjectID();
+ log.display(" threadID: " + threadID);
+ } catch (BoundException e) {
+ log.complain("Unable to get threadID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check threadID
+ if (threadID != testedThreadID) {
+ log.complain("Unexpected threadID of event " + i + " in tested event packet: " +
+ threadID + " (expected: " + testedThreadID + ")");
+ success = false;
+ }
+
+ // get location
+ JDWP.Location location = null;
+ try {
+ location = eventPacket.getLocation();
+ log.display(" location: " + location);
+ } catch (BoundException e) {
+ log.complain("Unable to get location of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check location
+ if (location.getTag() != testedLocation.getTag()) {
+ log.complain("Unexpected class tag of location of event " + i
+ + " in tested event packet: " + location.getTag()
+ + " (expected: " + testedLocation.getTag() + ")");
+ success = false;
+ }
+ if (location.getClassID() != testedLocation.getClassID()) {
+ log.complain("Unexpected classID of location of event " + i
+ + " in tested event packet: " + location.getClassID()
+ + " (expected: " + testedLocation.getClassID() + ")");
+ success = false;
+ }
+ if (location.getMethodID() != testedLocation.getMethodID()) {
+ log.complain("Unexpected methodID of location of event " + i
+ + " in tested event packet: " + location.getMethodID()
+ + " (expected: " + testedLocation.getMethodID() + ")");
+ success = false;
+ }
+ if (location.getIndex() != testedLocation.getIndex()) {
+ log.complain("Unexpected codeIndex of location of event " + i
+ + " in tested event packet: " + location.getIndex()
+ + " (expected: " + testedLocation.getIndex() + ")");
+ success = false;
+ }
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event packet parsed");
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_ENTRY/methentry001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Event/METHOD_ENTRY/methentry001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Event
+ * command: Composite
+ * command set: EventRequest
+ * command: Set, Clear
+ * event kind: METHOD_ENTRY
+ * Test checks that
+ * 1) debuggee successfully creates METHOD_ENTRY event request
+ * for particular classID
+ * 2) expected METHOD_ENTRY event is received when the thread
+ * entered tested method into debuggee
+ * 3) debuggee successfully removes event request
+ * Test consists of two compoments:
+ * debugger: methentry001
+ * debuggee: methentry001a
+ * First, debugger uses nsk.share support classes to launch debuggee,
+ * and obtains Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded and breakpoint reached.
+ * Then debugger gets methodID and entry location for tested method and
+ * makes request for METHOD_ENTRY event of methods of this class.
+ * When event is received debugger checks if the received event is for
+ * expected class, thread, method and location and has correct attributes.
+ * Then debugger removes event request.
+ * Finally, debugger disconnects debuggee, waits for it exited
+ * and exits too with proper exit code.
+ * COMMENTS
+ * Test was fixed due to test bug:
+ * 4797978 TEST_BUG: potential race condition in a number of JDWP tests
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Event.METHOD_ENTRY.methentry001
+ * nsk.jdwp.Event.METHOD_ENTRY.methentry001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Event.METHOD_ENTRY.methentry001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_ENTRY/methentry001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.Event.METHOD_ENTRY;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class methentry001a {
+
+ static final int BREAKPOINT_LINE = 91;
+ static final int METHOD_ENTRY_LINE = 103;
+
+ static ArgumentHandler argumentHandler = null;
+ static Log log = null;
+
+ public static void main(String args[]) {
+ methentry001a _methentry001a = new methentry001a();
+ System.exit(methentry001.JCK_STATUS_BASE + _methentry001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // create tested thread
+ log.display("Creating tested thread");
+ TestedClass thread = new TestedClass(methentry001.TESTED_THREAD_NAME);
+ log.display(" ... thread created");
+
+ // start tested thread
+ log.display("Starting tested thread");
+ thread.start();
+ log.display(" ... thread started");
+
+ // wait for thread finished
+ try {
+ log.display("Waiting for tested thread finished");
+ thread.join();
+ log.display(" ... thread finished");
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for tested thread finished");
+ return methentry001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return methentry001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass extends Thread {
+ public TestedClass(String name) {
+ super(name);
+ }
+
+ public void run() {
+ log.display("Tested thread: started");
+
+ log.display("Breakpoint line reached");
+ // next line is for breakpoint
+ int foo = 0; // BREAKPOINT_LINE
+ log.display("Breakpoint line passed");
+
+ log.display("Invoking tested method");
+ testedMethod();
+ log.display("Tested method invoked");
+
+ log.display("Tested thread: finished");
+ }
+
+ public static void testedMethod() {
+ // next line is for method entry location
+ log.display("Tested method entered"); // METHOD_ENTRY_LINE
+ log.display("Tested method exited");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_EXIT/methexit001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,640 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.METHOD_EXIT;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP event: METHOD_EXIT.
+ *
+ * See methexit001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP event is tested in the method waitForTestedEvent().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class methexit001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Event.METHOD_EXIT";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "methexit001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP event constants
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.METHOD_EXIT;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+
+ // name and signature of the tested class
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+ static final String TESTED_THREAD_NAME = "TestedThread";
+
+ // name of field and method of tested class
+ static final String THREAD_FIELD_NAME = "thread";
+ static final String TESTED_METHOD_NAME = "testedMethod";
+ static final String BREAKPOINT_METHOD_NAME = "run";
+ static final int BREAKPOINT_LINE = methexit001a.BREAKPOINT_LINE;
+ static final int METHOD_EXIT_LINE = methexit001a.METHOD_EXIT_LINE;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // obtained data
+ long testedClassID = 0;
+ long testedThreadID = 0;
+ long testedMethodID = 0;
+ JDWP.Location testedLocation = null;
+ int eventRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new methexit001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // prepare debuggee
+ log.display("\n>>> Getting prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP event
+ log.display("\n>>> Testing JDWP event \n");
+ log.display("Making request for METHOD_EXIT event for class:\n\t"
+ + TESTED_CLASS_NAME);
+ requestTestedEvent();
+ log.display(" ... got requestID: " + eventRequestID);
+ log.display("");
+
+ // resume debuggee
+ log.display("Resumindg debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+ log.display("");
+
+ // wait for tested METHOD_EXIT event
+ log.display("Waiting for METHOD_EXIT event received");
+ waitForTestedEvent();
+ log.display(" ... event received");
+ log.display("");
+
+ // clear tested request for METHOD_EXIT event
+ log.display("Clearing request for tested event");
+ clearTestedRequest();
+ log.display(" ... request removed");
+
+ // finish debuggee after testing
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Get debuggee prepared for testing and obtain required data.
+ */
+ void prepareForTest() {
+ // wait for tested class loaded
+ log.display("Waiting for tested class loaded");
+ testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... got classID: " + testedClassID);
+ log.display("");
+
+ // get methodID for the tested method
+ log.display("Getting tested methodID for method name: " + TESTED_METHOD_NAME);
+ testedMethodID = debugee.getMethodID(testedClassID, TESTED_METHOD_NAME, true);
+ log.display(" ... got methodID: " + testedMethodID);
+
+ // get codeIndex for method entry line
+ log.display("Getting codeIndex for method exit line: " + METHOD_EXIT_LINE);
+ long codeIndex = debugee.getCodeIndex(testedClassID, testedMethodID, METHOD_EXIT_LINE);
+ log.display(" ... got index: " + codeIndex);
+
+ // create location for method entry line
+ log.display("Creating location for method exit");
+ testedLocation = new JDWP.Location(JDWP.TypeTag.CLASS, testedClassID,
+ testedMethodID, codeIndex);
+ log.display(" ... got location: " + testedLocation);
+ log.display("");
+
+ // wait for breakpoint reached
+ log.display("Waiting for breakpoint reached at: "
+ + BREAKPOINT_METHOD_NAME + ":" + BREAKPOINT_LINE);
+ testedThreadID = debugee.waitForBreakpointReached(testedClassID,
+ BREAKPOINT_METHOD_NAME,
+ BREAKPOINT_LINE,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... breakpoint reached with threadID: " + testedThreadID);
+ log.display("");
+ }
+
+ /**
+ * Make request for tested METHOD_EXIT event.
+ */
+ void requestTestedEvent() {
+ Failure failure = new Failure("Error occured while makind request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Set");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set);
+ log.display(" eventKind: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" eventPolicy: " + TESTED_EVENT_SUSPEND_POLICY);
+ command.addByte(TESTED_EVENT_SUSPEND_POLICY);
+ log.display(" modifiers: " + 1);
+ command.addInt(1);
+ log.display(" modKind: " + JDWP.EventModifierKind.CLASS_ONLY);
+ command.addByte(JDWP.EventModifierKind.CLASS_ONLY);
+ log.display(" classID: " + testedClassID);
+ command.addReferenceTypeID(testedClassID);
+ command.setLength();
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract requestID
+ int requestID = 0;
+ try {
+ requestID = reply.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract requestID from request reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // check requestID
+ if (requestID == 0) {
+ log.complain("Unexpected null requestID returned: " + requestID);
+ success = false;
+ throw failure;
+ }
+
+ eventRequestID = requestID;
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Clear request for tested METHOD_EXIT event.
+ */
+ void clearTestedRequest() {
+ Failure failure = new Failure("Error occured while clearing request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Clear");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear);
+ log.display(" event: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" requestID: " + eventRequestID);
+ command.addInt(eventRequestID);
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ log.display(" no data");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Wait for tested METHOD_EXIT event.
+ */
+ void waitForTestedEvent() {
+
+ EventPacket eventPacket = null;
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for event packet");
+ eventPacket = debugee.getEventPacket(timeout);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.complain("Unable to read tested event packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check suspendPolicy value
+ if (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY) {
+ log.complain("Unexpected SuspendPolicy in tested event packet: " +
+ suspendPolicy + " (expected: " + TESTED_EVENT_SUSPEND_POLICY + ")");
+ success = false;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ long eventThreadID = 0;
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check eventKind
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ log.complain("Unexpected VM_DEATH event received: " +
+ eventKind + " (expected: " + JDWP.EventKind.METHOD_EXIT + ")");
+ dead = true;
+ success = false;
+ return;
+ } else if (eventKind != JDWP.EventKind.METHOD_EXIT) {
+ log.complain("Unexpected eventKind of event " + i + " in tested event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.METHOD_EXIT + ")");
+ success = false;
+ return;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != eventRequestID) {
+ log.complain("Unexpected requestID of event " + i + " in tested event packet: " +
+ requestID + " (expected: " + eventRequestID + ")");
+ success = false;
+ }
+
+ // get threadID
+ long threadID = 0;
+ try {
+ threadID = eventPacket.getObjectID();
+ log.display(" threadID: " + threadID);
+ } catch (BoundException e) {
+ log.complain("Unable to get threadID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check threadID
+ if (threadID != testedThreadID) {
+ log.complain("Unexpected threadID of event " + i + " in tested event packet: " +
+ threadID + " (expected: " + testedThreadID + ")");
+ success = false;
+ }
+
+ // get location
+ JDWP.Location location = null;
+ try {
+ location = eventPacket.getLocation();
+ log.display(" location: " + location);
+ } catch (BoundException e) {
+ log.complain("Unable to get location of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check location
+ if (location.getTag() != testedLocation.getTag()) {
+ log.complain("Unexpected class tag of location of event " + i
+ + " in tested event packet: " + location.getTag()
+ + " (expected: " + testedLocation.getTag() + ")");
+ success = false;
+ }
+ if (location.getClassID() != testedLocation.getClassID()) {
+ log.complain("Unexpected classID of location of event " + i
+ + " in tested event packet: " + location.getClassID()
+ + " (expected: " + testedLocation.getClassID() + ")");
+ success = false;
+ }
+ if (location.getMethodID() != testedLocation.getMethodID()) {
+ log.complain("Unexpected methodID of location of event " + i
+ + " in tested event packet: " + location.getMethodID()
+ + " (expected: " + testedLocation.getMethodID() + ")");
+ success = false;
+ }
+ if (location.getIndex() != testedLocation.getIndex()) {
+ log.complain("Unexpected codeIndex of location of event " + i
+ + " in tested event packet: " + location.getIndex()
+ + " (expected: " + testedLocation.getIndex() + ")");
+ success = false;
+ }
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event packet parsed");
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_EXIT/methexit001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Event/METHOD_EXIT/methexit001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Event
+ * command: Composite
+ * command set: EventRequest
+ * command: Set, Clear
+ * event kind: METHOD_EXIT
+ * Test checks that
+ * 1) debuggee successfully creates METHOD_EXIT event request
+ * for particular classID
+ * 2) expected METHOD_EXIT event is received when the thread
+ * exited tested method into debuggee
+ * 3) debuggee successfully removes event request
+ * Test consists of two compoments:
+ * debugger: methexit001
+ * debuggee: methexit001a
+ * First, debugger uses nsk.share support classes to launch debuggee,
+ * and obtains Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded and breakpoint reached.
+ * Then debugger gets methodID and method exit location for tested method
+ * and makes request for METHOD_EXIT event of methods of this class.
+ * When event is received debugger checks if the received event is for
+ * expected class, thread, method and location and has correct attributes.
+ * Then debugger removes event request.
+ * Finally, debugger disconnects debuggee, waits for it exited
+ * and exits too with proper exit code.
+ * COMMENTS
+ * Test was fixed due to test bug:
+ * 4797978 TEST_BUG: potential race condition in a number of JDWP tests
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Event.METHOD_EXIT.methexit001
+ * nsk.jdwp.Event.METHOD_EXIT.methexit001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Event.METHOD_EXIT.methexit001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/METHOD_EXIT/methexit001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.Event.METHOD_EXIT;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class methexit001a {
+
+ static final int BREAKPOINT_LINE = 91;
+ static final int METHOD_EXIT_LINE = 105;
+
+ static ArgumentHandler argumentHandler = null;
+ static Log log = null;
+
+ public static void main(String args[]) {
+ methexit001a _methexit001a = new methexit001a();
+ System.exit(methexit001.JCK_STATUS_BASE + _methexit001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // create tested thread
+ log.display("Creating tested thread");
+ TestedClass thread = new TestedClass(methexit001.TESTED_THREAD_NAME);
+ log.display(" ... thread created");
+
+ // start tested thread
+ log.display("Starting tested thread");
+ thread.start();
+ log.display(" ... thread started");
+
+ // wait for thread finished
+ try {
+ log.display("Waiting for tested thread finished");
+ thread.join();
+ log.display(" ... thread finished");
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for tested thread finished");
+ return methexit001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return methexit001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass extends Thread {
+ public TestedClass(String name) {
+ super(name);
+ }
+
+ public void run() {
+ log.display("Tested thread: started");
+
+ log.display("Breakpoint line reached");
+ // next line is for breakpoint
+ int foo = 0; // BREAKPOINT_LINE
+ log.display("Breakpoint line passed");
+
+ log.display("Invoking tested method");
+ testedMethod();
+ log.display("Tested method invoked");
+
+ log.display("Tested thread: finished");
+ }
+
+ public static void testedMethod() {
+ log.display("Tested method entered");
+ log.display("Tested method exited");
+ // next line is for method exit location
+ return; // METHOD_EXIT_LINE
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,645 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.SINGLE_STEP;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP event: SINGLE_STEP.
+ *
+ * See singlestep001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP event is tested in the method waitForTestedEvent().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class singlestep001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Event.SINGLE_STEP";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "singlestep001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP event constants
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.SINGLE_STEP;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+ static final int STEP_DEPTH = JDWP.StepDepth.OVER;
+ static final int STEP_SIZE = JDWP.StepSize.LINE;
+
+ // name and signature of the tested class
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+ static final String TESTED_THREAD_NAME = "TestedThread";
+
+ // name of field and method of tested class
+ static final String THREAD_FIELD_NAME = "thread";
+ static final String BREAKPOINT_METHOD_NAME = "run";
+ static final int BREAKPOINT_LINE = singlestep001a.BREAKPOINT_LINE;
+ static final int SINGLE_STEP_LINE = singlestep001a.SINGLE_STEP_LINE;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // obtained data
+ long testedClassID = 0;
+ long testedThreadID = 0;
+ long testedMethodID = 0;
+ JDWP.Location testedLocation = null;
+ int eventRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new singlestep001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // prepare debuggee
+ log.display("\n>>> Getting prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP event
+ log.display("\n>>> Testing JDWP event \n");
+ log.display("Making request for SINGLE_STEP event for class:\n\t"
+ + TESTED_CLASS_NAME);
+ requestTestedEvent();
+ log.display(" ... got requestID: " + eventRequestID);
+ log.display("");
+
+ // resume debuggee
+ log.display("Resumindg debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+ log.display("");
+
+ // wait for tested SINGLE_STEP event
+ log.display("Waiting for SINGLE_STEP event received");
+ waitForTestedEvent();
+ log.display(" ... event received");
+ log.display("");
+
+ // clear tested request for SINGLE_STEP event
+ log.display("Clearing request for tested event");
+ clearTestedRequest();
+ log.display(" ... request removed");
+
+ // finish debuggee after testing
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Get debuggee prepared for testing and obtain required data.
+ */
+ void prepareForTest() {
+ // wait for tested class loaded
+ log.display("Waiting for tested class loaded");
+ testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... got classID: " + testedClassID);
+ log.display("");
+
+ // get methodID for the tested method
+ log.display("Getting tested methodID for method name: " + BREAKPOINT_METHOD_NAME);
+ testedMethodID = debugee.getMethodID(testedClassID, BREAKPOINT_METHOD_NAME, true);
+ log.display(" ... got methodID: " + testedMethodID);
+
+ // get codeIndex for method entry line
+ log.display("Getting codeIndex for single step line: " + SINGLE_STEP_LINE);
+ long codeIndex = debugee.getCodeIndex(testedClassID, testedMethodID, SINGLE_STEP_LINE);
+ log.display(" ... got index: " + codeIndex);
+
+ // create location for method entry line
+ log.display("Creating location of single step event");
+ testedLocation = new JDWP.Location(JDWP.TypeTag.CLASS, testedClassID,
+ testedMethodID, codeIndex);
+ log.display(" ... got location: " + testedLocation);
+ log.display("");
+
+ // wait for breakpoint reached
+ log.display("Waiting for breakpoint reached at: "
+ + BREAKPOINT_METHOD_NAME + ":" + BREAKPOINT_LINE);
+ testedThreadID = debugee.waitForBreakpointReached(testedClassID,
+ BREAKPOINT_METHOD_NAME,
+ BREAKPOINT_LINE,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... breakpoint reached with threadID: " + testedThreadID);
+ log.display("");
+ }
+
+ /**
+ * Make request for tested SINGLE_STEP event.
+ */
+ void requestTestedEvent() {
+ Failure failure = new Failure("Error occured while makind request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Set");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set);
+ log.display(" eventKind: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" eventPolicy: " + TESTED_EVENT_SUSPEND_POLICY);
+ command.addByte(TESTED_EVENT_SUSPEND_POLICY);
+ log.display(" modifiers: " + 1);
+ command.addInt(1);
+ log.display(" modKind: " + JDWP.EventModifierKind.STEP + " (STEP)");
+ command.addByte(JDWP.EventModifierKind.STEP);
+ log.display(" threadID: " + testedThreadID);
+ command.addObjectID(testedThreadID);
+ log.display(" size: " + STEP_SIZE);
+ command.addInt(STEP_SIZE);
+ log.display(" depth: " + STEP_DEPTH);
+ command.addInt(STEP_DEPTH);
+ command.setLength();
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract requestID
+ int requestID = 0;
+ try {
+ requestID = reply.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract requestID from request reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // check requestID
+ if (requestID == 0) {
+ log.complain("Unexpected null requestID returned: " + requestID);
+ success = false;
+ throw failure;
+ }
+
+ eventRequestID = requestID;
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Clear request for tested SINGLE_STEP event.
+ */
+ void clearTestedRequest() {
+ Failure failure = new Failure("Error occured while clearing request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Clear");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear);
+ log.display(" event: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" requestID: " + eventRequestID);
+ command.addInt(eventRequestID);
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ log.display(" no data");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Wait for tested SINGLE_STEP event.
+ */
+ void waitForTestedEvent() {
+
+ EventPacket eventPacket = null;
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for event packet");
+ eventPacket = debugee.getEventPacket(timeout);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.complain("Unable to read tested event packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check suspendPolicy value
+ if (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY) {
+ log.complain("Unexpected SuspendPolicy in tested event packet: " +
+ suspendPolicy + " (expected: " + TESTED_EVENT_SUSPEND_POLICY + ")");
+ success = false;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ long eventThreadID = 0;
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check eventKind
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ log.complain("Unexpected VM_DEATH event received: " +
+ eventKind + " (expected: " + JDWP.EventKind.SINGLE_STEP + ")");
+ dead = true;
+ success = false;
+ return;
+ } else if (eventKind != JDWP.EventKind.SINGLE_STEP) {
+ log.complain("Unexpected eventKind of event " + i + " in tested event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.SINGLE_STEP + ")");
+ success = false;
+ return;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != eventRequestID) {
+ log.complain("Unexpected requestID of event " + i + " in tested event packet: " +
+ requestID + " (expected: " + eventRequestID + ")");
+ success = false;
+ }
+
+ // get threadID
+ long threadID = 0;
+ try {
+ threadID = eventPacket.getObjectID();
+ log.display(" threadID: " + threadID);
+ } catch (BoundException e) {
+ log.complain("Unable to get threadID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check threadID
+ if (threadID != testedThreadID) {
+ log.complain("Unexpected threadID of event " + i + " in tested event packet: " +
+ threadID + " (expected: " + testedThreadID + ")");
+ success = false;
+ }
+
+ // get location
+ JDWP.Location location = null;
+ try {
+ location = eventPacket.getLocation();
+ log.display(" location: " + location);
+ } catch (BoundException e) {
+ log.complain("Unable to get location of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check location
+ if (location.getTag() != testedLocation.getTag()) {
+ log.complain("Unexpected class tag of location of event " + i
+ + " in tested event packet: " + location.getTag()
+ + " (expected: " + testedLocation.getTag() + ")");
+ success = false;
+ }
+ if (location.getClassID() != testedLocation.getClassID()) {
+ log.complain("Unexpected classID of location of event " + i
+ + " in tested event packet: " + location.getClassID()
+ + " (expected: " + testedLocation.getClassID() + ")");
+ success = false;
+ }
+ if (location.getMethodID() != testedLocation.getMethodID()) {
+ log.complain("Unexpected methodID of location of event " + i
+ + " in tested event packet: " + location.getMethodID()
+ + " (expected: " + testedLocation.getMethodID() + ")");
+ success = false;
+ }
+ if (location.getIndex() != testedLocation.getIndex()) {
+ log.complain("Unexpected codeIndex of location of event " + i
+ + " in tested event packet: " + location.getIndex()
+ + " (expected: " + testedLocation.getIndex() + ")");
+ success = false;
+ }
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event packet parsed");
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Event/SINGLE_STEP/singlestep001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Event
+ * command: Composite
+ * command set: EventRequest
+ * command: Set, Clear
+ * event kind: SINGLE_STEP
+ * Test checks that
+ * 1) debuggee successfully creates SINGLE_STEP event request
+ * for particular threadID with attributes:
+ * depth=OVER, size=LINE
+ * 2) expected SINGLE_STEP event is received when the thread
+ * in debuggee steps to the next line after breakpoint
+ * 3) debuggee successfully removes event request
+ * Test consists of two compoments:
+ * debugger: singlestep001
+ * debuggee: singlestep001a
+ * First, debugger uses nsk.share support classes to launch debuggee,
+ * and obtains Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded and gets methodID
+ * and location for expected single step event after breakpoint.
+ * Then debugger waits for breakpoint reached with some thread
+ * and makes request for SINGLE_STEP event for this threadID.
+ * When event is received debugger checks if the received event is for
+ * expected request, thread, and location and has correct attributes.
+ * Then debugger removes event request.
+ * Finally, debugger disconnects debuggee, waits for it exited
+ * and exits too with proper exit code.
+ * COMMENTS
+ * Test was fixed due to test bug:
+ * 4797978 TEST_BUG: potential race condition in a number of JDWP tests
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Event.SINGLE_STEP.singlestep001
+ * nsk.jdwp.Event.SINGLE_STEP.singlestep001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Event.SINGLE_STEP.singlestep001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.Event.SINGLE_STEP;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class singlestep001a {
+
+ static final int BREAKPOINT_LINE = 91;
+ static final int SINGLE_STEP_LINE = 94;
+
+ static ArgumentHandler argumentHandler = null;
+ static Log log = null;
+
+ public static void main(String args[]) {
+ singlestep001a _singlestep001a = new singlestep001a();
+ System.exit(singlestep001.JCK_STATUS_BASE + _singlestep001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // create tested thread
+ log.display("Creating tested thread");
+ TestedClass thread = new TestedClass(singlestep001.TESTED_THREAD_NAME);
+ log.display(" ... thread created");
+
+ // start tested thread
+ log.display("Starting tested thread");
+ thread.start();
+ log.display(" ... thread started");
+
+ // wait for thread finished
+ try {
+ log.display("Waiting for tested thread finished");
+ thread.join();
+ log.display(" ... thread finished");
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for tested thread finished");
+ return singlestep001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return singlestep001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass extends Thread {
+ public TestedClass(String name) {
+ super(name);
+ }
+
+ public void run() {
+ log.display("Tested thread: started");
+
+ log.display("Breakpoint line reached");
+ // next line is for breakpoint
+ int foo = 0; // BREAKPOINT_LINE
+
+ // next line is for SINGLE_STEP event
+ foo = 10; // SINGLE_STEP_LINE
+
+ log.display("Tested thread: finished");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep002.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,652 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.SINGLE_STEP;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP event: SINGLE_STEP.
+ *
+ * See singlestep002.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP event is tested in the method waitForTestedEvent().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class singlestep002 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Event.SINGLE_STEP";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "singlestep002";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP event constants
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.SINGLE_STEP;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+ static final int STEP_DEPTH = JDWP.StepDepth.INTO;
+ static final int STEP_SIZE = JDWP.StepSize.LINE;
+
+ // name and signature of the tested class
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+ static final String TESTED_THREAD_NAME = "TestedThread";
+
+ // name of field and method of tested class
+ static final String THREAD_FIELD_NAME = "thread";
+ static final String BREAKPOINT_METHOD_NAME = "run";
+ static final String STEP_METHOD_NAME = "methodForStep";
+ static final int BREAKPOINT_LINE = singlestep002a.BREAKPOINT_LINE;
+ static final int SINGLE_STEP_LINE = singlestep002a.SINGLE_STEP_LINE;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // obtained data
+ long testedClassID = 0;
+ long testedThreadID = 0;
+ long testedMethodID = 0;
+ long stepMethodID = 0;
+ JDWP.Location testedLocation = null;
+ int eventRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new singlestep002().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // prepare debuggee
+ log.display("\n>>> Getting prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP event
+ log.display("\n>>> Testing JDWP event \n");
+ log.display("Making request for SINGLE_STEP event for class:\n\t"
+ + TESTED_CLASS_NAME);
+ requestTestedEvent();
+ log.display(" ... got requestID: " + eventRequestID);
+ log.display("");
+
+ // resume debuggee
+ log.display("Resumindg debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+ log.display("");
+
+ // wait for tested SINGLE_STEP event
+ log.display("Waiting for SINGLE_STEP event received");
+ waitForTestedEvent();
+ log.display(" ... event received");
+ log.display("");
+
+ // clear tested request for SINGLE_STEP event
+ log.display("Clearing request for tested event");
+ clearTestedRequest();
+ log.display(" ... request removed");
+
+ // finish debuggee after testing
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Get debuggee prepared for testing and obtain required data.
+ */
+ void prepareForTest() {
+ // wait for tested class loaded
+ log.display("Waiting for tested class loaded");
+ testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... got classID: " + testedClassID);
+ log.display("");
+
+ // get methodID for the tested method
+ log.display("Getting tested methodID for method name: " + BREAKPOINT_METHOD_NAME);
+ testedMethodID = debugee.getMethodID(testedClassID, BREAKPOINT_METHOD_NAME, true);
+ log.display(" ... got methodID: " + testedMethodID);
+
+ // get methodID for the method with STEP_EVENT
+ log.display("Getting methodID for STEP_EVENT method name: " + STEP_METHOD_NAME);
+ stepMethodID = debugee.getMethodID(testedClassID, STEP_METHOD_NAME, true);
+ log.display(" ... got methodID: " + stepMethodID);
+
+ // get codeIndex for method entry line
+ log.display("Getting codeIndex for single step line: " + SINGLE_STEP_LINE);
+ long codeIndex = debugee.getCodeIndex(testedClassID, stepMethodID, SINGLE_STEP_LINE);
+ log.display(" ... got index: " + codeIndex);
+
+ // create location for method entry line
+ log.display("Creating location of single step event");
+ testedLocation = new JDWP.Location(JDWP.TypeTag.CLASS, testedClassID,
+ stepMethodID, codeIndex);
+ log.display(" ... got location: " + testedLocation);
+ log.display("");
+
+ // wait for breakpoint reached
+ log.display("Waiting for breakpoint reached at: "
+ + BREAKPOINT_METHOD_NAME + ":" + BREAKPOINT_LINE);
+ testedThreadID = debugee.waitForBreakpointReached(testedClassID,
+ BREAKPOINT_METHOD_NAME,
+ BREAKPOINT_LINE,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... breakpoint reached with threadID: " + testedThreadID);
+ log.display("");
+ }
+
+ /**
+ * Make request for tested SINGLE_STEP event.
+ */
+ void requestTestedEvent() {
+ Failure failure = new Failure("Error occured while makind request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Set");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set);
+ log.display(" eventKind: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" eventPolicy: " + TESTED_EVENT_SUSPEND_POLICY);
+ command.addByte(TESTED_EVENT_SUSPEND_POLICY);
+ log.display(" modifiers: " + 1);
+ command.addInt(1);
+ log.display(" modKind: " + JDWP.EventModifierKind.STEP + " (STEP)");
+ command.addByte(JDWP.EventModifierKind.STEP);
+ log.display(" threadID: " + testedThreadID);
+ command.addObjectID(testedThreadID);
+ log.display(" size: " + STEP_SIZE);
+ command.addInt(STEP_SIZE);
+ log.display(" depth: " + STEP_DEPTH);
+ command.addInt(STEP_DEPTH);
+ command.setLength();
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract requestID
+ int requestID = 0;
+ try {
+ requestID = reply.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract requestID from request reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // check requestID
+ if (requestID == 0) {
+ log.complain("Unexpected null requestID returned: " + requestID);
+ success = false;
+ throw failure;
+ }
+
+ eventRequestID = requestID;
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Clear request for tested SINGLE_STEP event.
+ */
+ void clearTestedRequest() {
+ Failure failure = new Failure("Error occured while clearing request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Clear");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear);
+ log.display(" event: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" requestID: " + eventRequestID);
+ command.addInt(eventRequestID);
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ log.display(" no data");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Wait for tested SINGLE_STEP event.
+ */
+ void waitForTestedEvent() {
+
+ EventPacket eventPacket = null;
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for event packet");
+ eventPacket = debugee.getEventPacket(timeout);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.complain("Unable to read tested event packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check suspendPolicy value
+ if (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY) {
+ log.complain("Unexpected SuspendPolicy in tested event packet: " +
+ suspendPolicy + " (expected: " + TESTED_EVENT_SUSPEND_POLICY + ")");
+ success = false;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ long eventThreadID = 0;
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check eventKind
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ log.complain("Unexpected VM_DEATH event received: " +
+ eventKind + " (expected: " + JDWP.EventKind.SINGLE_STEP + ")");
+ dead = true;
+ success = false;
+ return;
+ } else if (eventKind != JDWP.EventKind.SINGLE_STEP) {
+ log.complain("Unexpected eventKind of event " + i + " in tested event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.SINGLE_STEP + ")");
+ success = false;
+ return;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != eventRequestID) {
+ log.complain("Unexpected requestID of event " + i + " in tested event packet: " +
+ requestID + " (expected: " + eventRequestID + ")");
+ success = false;
+ }
+
+ // get threadID
+ long threadID = 0;
+ try {
+ threadID = eventPacket.getObjectID();
+ log.display(" threadID: " + threadID);
+ } catch (BoundException e) {
+ log.complain("Unable to get threadID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check threadID
+ if (threadID != testedThreadID) {
+ log.complain("Unexpected threadID of event " + i + " in tested event packet: " +
+ threadID + " (expected: " + testedThreadID + ")");
+ success = false;
+ }
+
+ // get location
+ JDWP.Location location = null;
+ try {
+ location = eventPacket.getLocation();
+ log.display(" location: " + location);
+ } catch (BoundException e) {
+ log.complain("Unable to get location of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check location
+ if (location.getTag() != testedLocation.getTag()) {
+ log.complain("Unexpected class tag of location of event " + i
+ + " in tested event packet: " + location.getTag()
+ + " (expected: " + testedLocation.getTag() + ")");
+ success = false;
+ }
+ if (location.getClassID() != testedLocation.getClassID()) {
+ log.complain("Unexpected classID of location of event " + i
+ + " in tested event packet: " + location.getClassID()
+ + " (expected: " + testedLocation.getClassID() + ")");
+ success = false;
+ }
+ if (location.getMethodID() != testedLocation.getMethodID()) {
+ log.complain("Unexpected methodID of location of event " + i
+ + " in tested event packet: " + location.getMethodID()
+ + " (expected: " + testedLocation.getMethodID() + ")");
+ success = false;
+ }
+ if (location.getIndex() != testedLocation.getIndex()) {
+ log.complain("Unexpected codeIndex of location of event " + i
+ + " in tested event packet: " + location.getIndex()
+ + " (expected: " + testedLocation.getIndex() + ")");
+ success = false;
+ }
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event packet parsed");
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep002/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Event/SINGLE_STEP/singlestep002.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Event
+ * command: Composite
+ * command set: EventRequest
+ * command: Set, Clear
+ * event kind: SINGLE_STEP
+ * Test checks that
+ * 1) debuggee successfully creates SINGLE_STEP event request
+ * for particular threadID with attributes:
+ * depth=INTO, size=LINE
+ * 2) expected SINGLE_STEP event is received when the thread
+ * in debuggee steps to the next line after breakpoint
+ * 3) debuggee successfully removes event request
+ * Test consists of two compoments:
+ * debugger: singlestep002
+ * debuggee: singlestep002a
+ * First, debugger uses nsk.share support classes to launch debuggee,
+ * and obtains Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded and gets methodID
+ * and location for expected single step event into invoked method.
+ * Then debugger waits for breakpoint reached with some thread
+ * and makes request for SINGLE_STEP event for this threadID.
+ * When event is received debugger checks if the received event is for
+ * expected request, thread, and location and has correct attributes.
+ * Then debugger removes event request.
+ * Finally, debugger disconnects debuggee, waits for it exited
+ * and exits too with proper exit code.
+ * COMMENTS
+ * Test was fixed due to test bug:
+ * 4797978 TEST_BUG: potential race condition in a number of JDWP tests
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Event.SINGLE_STEP.singlestep002
+ * nsk.jdwp.Event.SINGLE_STEP.singlestep002a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Event.SINGLE_STEP.singlestep002
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep002a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.Event.SINGLE_STEP;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class singlestep002a {
+
+ static final int BREAKPOINT_LINE = 91;
+ static final int SINGLE_STEP_LINE = 101;
+
+ static ArgumentHandler argumentHandler = null;
+ static Log log = null;
+
+ public static void main(String args[]) {
+ singlestep002a _singlestep002a = new singlestep002a();
+ System.exit(singlestep002.JCK_STATUS_BASE + _singlestep002a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // create tested thread
+ log.display("Creating tested thread");
+ TestedClass thread = new TestedClass(singlestep002.TESTED_THREAD_NAME);
+ log.display(" ... thread created");
+
+ // start tested thread
+ log.display("Starting tested thread");
+ thread.start();
+ log.display(" ... thread started");
+
+ // wait for thread finished
+ try {
+ log.display("Waiting for tested thread finished");
+ thread.join();
+ log.display(" ... thread finished");
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for tested thread finished");
+ return singlestep002.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return singlestep002.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass extends Thread {
+ public TestedClass(String name) {
+ super(name);
+ }
+
+ public void run() {
+ log.display("Tested thread: started");
+
+ log.display("Breakpoint line reached");
+ // next line is for breakpoint
+ methodForStep(); // BREAKPOINT_LINE
+
+ // next line should be reached after step request removed
+ int foo = 0;
+
+ log.display("Tested thread: finished");
+ }
+
+ public void methodForStep() {
+ // next line is for SINGLE_STEP event
+ int foo = 100; // SINGLE_STEP_LINE
+ log.display("Method for step event entered");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep003.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,652 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.SINGLE_STEP;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP event: SINGLE_STEP.
+ *
+ * See singlestep003.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP event is tested in the method waitForTestedEvent().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class singlestep003 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Event.SINGLE_STEP";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "singlestep003";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP event constants
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.SINGLE_STEP;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+ static final int STEP_DEPTH = JDWP.StepDepth.OUT;
+ static final int STEP_SIZE = JDWP.StepSize.LINE;
+
+ // name and signature of the tested class
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+ static final String TESTED_THREAD_NAME = "TestedThread";
+
+ // name of field and method of tested class
+ static final String THREAD_FIELD_NAME = "thread";
+ static final String BREAKPOINT_METHOD_NAME = "methodForBreakpoint";
+ static final String STEP_METHOD_NAME = "run";
+ static final int BREAKPOINT_LINE = singlestep003a.BREAKPOINT_LINE;
+ static final int SINGLE_STEP_LINE = singlestep003a.SINGLE_STEP_LINE;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // obtained data
+ long testedClassID = 0;
+ long testedThreadID = 0;
+ long testedMethodID = 0;
+ long stepMethodID = 0;
+ JDWP.Location testedLocation = null;
+ int eventRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new singlestep003().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // prepare debuggee
+ log.display("\n>>> Getting prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP event
+ log.display("\n>>> Testing JDWP event \n");
+ log.display("Making request for SINGLE_STEP event for class:\n\t"
+ + TESTED_CLASS_NAME);
+ requestTestedEvent();
+ log.display(" ... got requestID: " + eventRequestID);
+ log.display("");
+
+ // resume debuggee
+ log.display("Resumindg debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+ log.display("");
+
+ // wait for tested SINGLE_STEP event
+ log.display("Waiting for SINGLE_STEP event received");
+ waitForTestedEvent();
+ log.display(" ... event received");
+ log.display("");
+
+ // clear tested request for SINGLE_STEP event
+ log.display("Clearing request for tested event");
+ clearTestedRequest();
+ log.display(" ... request removed");
+
+ // finish debuggee after testing
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Get debuggee prepared for testing and obtain required data.
+ */
+ void prepareForTest() {
+ // wait for tested class loaded
+ log.display("Waiting for tested class loaded");
+ testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... got classID: " + testedClassID);
+ log.display("");
+
+ // get methodID for the tested method
+ log.display("Getting tested methodID for method name: " + BREAKPOINT_METHOD_NAME);
+ testedMethodID = debugee.getMethodID(testedClassID, BREAKPOINT_METHOD_NAME, true);
+ log.display(" ... got methodID: " + testedMethodID);
+
+ // get methodID for the method with STEP_EVENT
+ log.display("Getting methodID for STEP_EVENT method name: " + STEP_METHOD_NAME);
+ stepMethodID = debugee.getMethodID(testedClassID, STEP_METHOD_NAME, true);
+ log.display(" ... got methodID: " + stepMethodID);
+
+ // get codeIndex for method entry line
+ log.display("Getting codeIndex for single step line: " + SINGLE_STEP_LINE);
+ long codeIndex = debugee.getCodeIndex(testedClassID, stepMethodID, SINGLE_STEP_LINE);
+ log.display(" ... got index: " + codeIndex);
+
+ // create location for method entry line
+ log.display("Creating location of single step event");
+ testedLocation = new JDWP.Location(JDWP.TypeTag.CLASS, testedClassID,
+ stepMethodID, codeIndex);
+ log.display(" ... got location: " + testedLocation);
+ log.display("");
+
+ // wait for breakpoint reached
+ log.display("Waiting for breakpoint reached at: "
+ + BREAKPOINT_METHOD_NAME + ":" + BREAKPOINT_LINE);
+ testedThreadID = debugee.waitForBreakpointReached(testedClassID,
+ BREAKPOINT_METHOD_NAME,
+ BREAKPOINT_LINE,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... breakpoint reached with threadID: " + testedThreadID);
+ log.display("");
+ }
+
+ /**
+ * Make request for tested SINGLE_STEP event.
+ */
+ void requestTestedEvent() {
+ Failure failure = new Failure("Error occured while makind request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Set");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set);
+ log.display(" eventKind: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" eventPolicy: " + TESTED_EVENT_SUSPEND_POLICY);
+ command.addByte(TESTED_EVENT_SUSPEND_POLICY);
+ log.display(" modifiers: " + 1);
+ command.addInt(1);
+ log.display(" modKind: " + JDWP.EventModifierKind.STEP + " (STEP)");
+ command.addByte(JDWP.EventModifierKind.STEP);
+ log.display(" threadID: " + testedThreadID);
+ command.addObjectID(testedThreadID);
+ log.display(" size: " + STEP_SIZE);
+ command.addInt(STEP_SIZE);
+ log.display(" depth: " + STEP_DEPTH);
+ command.addInt(STEP_DEPTH);
+ command.setLength();
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract requestID
+ int requestID = 0;
+ try {
+ requestID = reply.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract requestID from request reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // check requestID
+ if (requestID == 0) {
+ log.complain("Unexpected null requestID returned: " + requestID);
+ success = false;
+ throw failure;
+ }
+
+ eventRequestID = requestID;
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Clear request for tested SINGLE_STEP event.
+ */
+ void clearTestedRequest() {
+ Failure failure = new Failure("Error occured while clearing request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Clear");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear);
+ log.display(" event: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" requestID: " + eventRequestID);
+ command.addInt(eventRequestID);
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ log.display(" no data");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Wait for tested SINGLE_STEP event.
+ */
+ void waitForTestedEvent() {
+
+ EventPacket eventPacket = null;
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for event packet");
+ eventPacket = debugee.getEventPacket(timeout);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.complain("Unable to read tested event packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check suspendPolicy value
+ if (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY) {
+ log.complain("Unexpected SuspendPolicy in tested event packet: " +
+ suspendPolicy + " (expected: " + TESTED_EVENT_SUSPEND_POLICY + ")");
+ success = false;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ long eventThreadID = 0;
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check eventKind
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ log.complain("Unexpected VM_DEATH event received: " +
+ eventKind + " (expected: " + JDWP.EventKind.SINGLE_STEP + ")");
+ dead = true;
+ success = false;
+ return;
+ } else if (eventKind != JDWP.EventKind.SINGLE_STEP) {
+ log.complain("Unexpected eventKind of event " + i + " in tested event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.SINGLE_STEP + ")");
+ success = false;
+ return;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != eventRequestID) {
+ log.complain("Unexpected requestID of event " + i + " in tested event packet: " +
+ requestID + " (expected: " + eventRequestID + ")");
+ success = false;
+ }
+
+ // get threadID
+ long threadID = 0;
+ try {
+ threadID = eventPacket.getObjectID();
+ log.display(" threadID: " + threadID);
+ } catch (BoundException e) {
+ log.complain("Unable to get threadID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check threadID
+ if (threadID != testedThreadID) {
+ log.complain("Unexpected threadID of event " + i + " in tested event packet: " +
+ threadID + " (expected: " + testedThreadID + ")");
+ success = false;
+ }
+
+ // get location
+ JDWP.Location location = null;
+ try {
+ location = eventPacket.getLocation();
+ log.display(" location: " + location);
+ } catch (BoundException e) {
+ log.complain("Unable to get location of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check location
+ if (location.getTag() != testedLocation.getTag()) {
+ log.complain("Unexpected class tag of location of event " + i
+ + " in tested event packet: " + location.getTag()
+ + " (expected: " + testedLocation.getTag() + ")");
+ success = false;
+ }
+ if (location.getClassID() != testedLocation.getClassID()) {
+ log.complain("Unexpected classID of location of event " + i
+ + " in tested event packet: " + location.getClassID()
+ + " (expected: " + testedLocation.getClassID() + ")");
+ success = false;
+ }
+ if (location.getMethodID() != testedLocation.getMethodID()) {
+ log.complain("Unexpected methodID of location of event " + i
+ + " in tested event packet: " + location.getMethodID()
+ + " (expected: " + testedLocation.getMethodID() + ")");
+ success = false;
+ }
+ if (location.getIndex() != testedLocation.getIndex()) {
+ log.complain("Unexpected codeIndex of location of event " + i
+ + " in tested event packet: " + location.getIndex()
+ + " (expected: " + testedLocation.getIndex() + ")");
+ success = false;
+ }
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event packet parsed");
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep003/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Event/SINGLE_STEP/singlestep003.
+ * VM Testbase keywords: [quick, jpda, jdwp, exclude]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Event
+ * command: Composite
+ * command set: EventRequest
+ * command: Set, Clear
+ * event kind: SINGLE_STEP
+ * Test checks that
+ * 1) debuggee successfully creates SINGLE_STEP event request
+ * for particular threadID with attributes:
+ * depth=OUT, size=LINE
+ * 2) expected SINGLE_STEP event is received when the thread
+ * in debuggee steps to the next line after breakpoint
+ * 3) debuggee successfully removes event request
+ * Test consists of two compoments:
+ * debugger: singlestep003
+ * debuggee: singlestep003a
+ * First, debugger uses nsk.share support classes to launch debuggee,
+ * and obtains Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded and gets methodID
+ * and location for expected single step event out of invoked method.
+ * Then debugger waits for breakpoint reached with some thread
+ * and makes request for SINGLE_STEP event for this threadID.
+ * When event is received debugger checks if the received event is for
+ * expected request, thread, and location and has correct attributes.
+ * Then debugger removes event request.
+ * Finally, debugger disconnects debuggee, waits for it exited
+ * and exits too with proper exit code.
+ * COMMENTS
+ * Test was fixed due to test bug:
+ * 4797978 TEST_BUG: potential race condition in a number of JDWP tests
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Event.SINGLE_STEP.singlestep003
+ * nsk.jdwp.Event.SINGLE_STEP.singlestep003a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Event.SINGLE_STEP.singlestep003
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/SINGLE_STEP/singlestep003a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.Event.SINGLE_STEP;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class singlestep003a {
+
+ static final int BREAKPOINT_LINE = 101;
+ static final int SINGLE_STEP_LINE = 92;
+
+ static ArgumentHandler argumentHandler = null;
+ static Log log = null;
+
+ public static void main(String args[]) {
+ singlestep003a _singlestep003a = new singlestep003a();
+ System.exit(singlestep003.JCK_STATUS_BASE + _singlestep003a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // create tested thread
+ log.display("Creating tested thread");
+ TestedClass thread = new TestedClass(singlestep003.TESTED_THREAD_NAME);
+ log.display(" ... thread created");
+
+ // start tested thread
+ log.display("Starting tested thread");
+ thread.start();
+ log.display(" ... thread started");
+
+ // wait for thread finished
+ try {
+ log.display("Waiting for tested thread finished");
+ thread.join();
+ log.display(" ... thread finished");
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for tested thread finished");
+ return singlestep003.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return singlestep003.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass extends Thread {
+ public TestedClass(String name) {
+ super(name);
+ }
+
+ public void run() {
+ log.display("Tested thread: started");
+
+ log.display("Invoking tested method");
+ methodForBreakpoint();
+ // next line is for out step event
+ int foo = 0; // SINGLE_STEP_LINE
+ log.display(" ... tested method invoked");
+
+ log.display("Tested thread: finished");
+ }
+
+ public void methodForBreakpoint() {
+ log.display("Breakpoint line reached");
+ // next line is for breakpoint before out step event request
+ int foo = 100; // BREAKPOINT_LINE
+ foo = foo + 100;
+ foo = foo + 100;
+ foo = foo + 100;
+ foo = foo + 100;
+ log.display("Returned from tested method");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_DEATH/thrdeath001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,588 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.THREAD_DEATH;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP event: THREAD_DEATH.
+ *
+ * See thrdeath001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP event is tested in the method waitForTestedEvent().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class thrdeath001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Event.THREAD_DEATH";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "thrdeath001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP event constants
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.THREAD_DEATH;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+
+ // name and signature of the tested class
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+ static final String TESTED_THREAD_NAME = "TestedThread";
+
+ // name of field and method of tested class
+ static final String THREAD_FIELD_NAME = "thread";
+ static final String BREAKPOINT_METHOD_NAME = "ready";
+ static final int BREAKPOINT_LINE = thrdeath001a.BREAKPOINT_LINE;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // obtained data
+ long testedClassID = 0;
+ long testedThreadID = 0;
+ int eventRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new thrdeath001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // prepare debuggee
+ log.display("\n>>> Getting prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP event
+ log.display("\n>>> Testing JDWP event \n");
+ log.display("Making request for THREAD_DEATH event for class:\n\t"
+ + TESTED_CLASS_NAME);
+ requestTestedEvent();
+ log.display(" ... got requestID: " + eventRequestID);
+ log.display("");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+ log.display("");
+
+ // wait for tested THREAD_DEATH event
+ log.display("Waiting for THREAD_DEATH event received");
+ waitForTestedEvent();
+ log.display(" ... event received");
+ log.display("");
+
+ // clear tested request for THREAD_DEATH event
+ log.display("Clearing request for tested event");
+ clearTestedRequest();
+ log.display(" ... request removed");
+
+ // finish debuggee after testing
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Get debuggee prepared for testing and obtain required data.
+ */
+ void prepareForTest() {
+ // wait for tested class loaded
+ log.display("Waiting for tested class loaded");
+ testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... got classID: " + testedClassID);
+ log.display("");
+
+ // wait for breakpoint reached
+ log.display("Waiting for breakpoint reached at: "
+ + BREAKPOINT_METHOD_NAME + ":" + BREAKPOINT_LINE);
+ long threadID = debugee.waitForBreakpointReached(testedClassID,
+ BREAKPOINT_METHOD_NAME,
+ BREAKPOINT_LINE,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... breakpoint reached with threadID: " + threadID);
+ log.display("");
+
+ // get thread value from static field of tested class
+ log.display("Getting thread value from static field: " + THREAD_FIELD_NAME);
+ JDWP.Value value = debugee.getStaticFieldValue(testedClassID, THREAD_FIELD_NAME,
+ JDWP.Tag.THREAD);
+ testedThreadID = ((Long)value.getValue()).longValue();
+ log.display(" ... got threadID: " + testedThreadID);
+ }
+
+ /**
+ * Make request for tested THREAD_DEATH event.
+ */
+ void requestTestedEvent() {
+ Failure failure = new Failure("Error occured while makind request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Set");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set);
+ log.display(" eventKind: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" eventPolicy: " + TESTED_EVENT_SUSPEND_POLICY);
+ command.addByte(TESTED_EVENT_SUSPEND_POLICY);
+ log.display(" modifiers: " + 1);
+ command.addInt(1);
+ log.display(" modKind: " + JDWP.EventModifierKind.THREAD_ONLY);
+ command.addByte(JDWP.EventModifierKind.THREAD_ONLY);
+ log.display(" threadID: " + testedThreadID);
+ command.addObjectID(testedThreadID);
+ command.setLength();
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract requestID
+ int requestID = 0;
+ try {
+ requestID = reply.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract requestID from request reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // check requestID
+ if (requestID == 0) {
+ log.complain("Unexpected null requestID returned: " + requestID);
+ success = false;
+ throw failure;
+ }
+
+ eventRequestID = requestID;
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Clear request for tested THREAD_DEATH event.
+ */
+ void clearTestedRequest() {
+ Failure failure = new Failure("Error occured while clearing request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Clear");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear);
+ log.display(" event: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" requestID: " + eventRequestID);
+ command.addInt(eventRequestID);
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ log.display(" no data");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Wait for tested THREAD_DEATH event.
+ */
+ void waitForTestedEvent() {
+
+ EventPacket eventPacket = null;
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for event packet");
+ eventPacket = debugee.getEventPacket(timeout);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.complain("Unable to read tested event packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check suspendPolicy value
+ if (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY) {
+ log.complain("Unexpected SuspendPolicy in tested event packet: " +
+ suspendPolicy + " (expected: " + TESTED_EVENT_SUSPEND_POLICY + ")");
+ success = false;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ long eventThreadID = 0;
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check eventKind
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ log.complain("Unexpected VM_DEATH event received: " +
+ eventKind + " (expected: " + JDWP.EventKind.THREAD_DEATH + ")");
+ dead = true;
+ success = false;
+ return;
+ } else if (eventKind != JDWP.EventKind.THREAD_DEATH) {
+ log.complain("Unexpected eventKind of event " + i + " in tested event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.THREAD_DEATH + ")");
+ success = false;
+ return;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != eventRequestID) {
+ log.complain("Unexpected requestID of event " + i + " in tested event packet: " +
+ requestID + " (expected: " + eventRequestID + ")");
+ success = false;
+ }
+
+ // get threadID
+ long threadID = 0;
+ try {
+ threadID = eventPacket.getObjectID();
+ log.display(" threadID: " + threadID);
+ } catch (BoundException e) {
+ log.complain("Unable to get threadID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check threadID
+ if (threadID != testedThreadID) {
+ log.complain("Unexpected threadID of event " + i + " in tested event packet: " +
+ threadID + " (expected: " + testedThreadID + ")");
+ success = false;
+ }
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event packet parsed");
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_DEATH/thrdeath001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Event/THREAD_DEATH/thrdeath001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Event
+ * command: Composite
+ * command set: EventRequest
+ * command: Set, Clear
+ * event kind: THREAD_DEATH
+ * Test checks that
+ * 1) debuggee successfully creates THREAD_DEATH event request
+ * for particular threadID
+ * 2) expected THREAD_DEATH event is received when the thread
+ * finished into debuggee
+ * 3) debuggee successfully removes event request
+ * Test consists of two compoments:
+ * debugger: thrdeath001
+ * debuggee: thrdeath001a
+ * First, debugger uses nsk.share support classes to launch debuggee,
+ * and obtains Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded and breakpoint reached.
+ * Then debugger gets threadID from the class static field and makes
+ * THREAD_DEATH event request for this thread,
+ * When event is received debugger checks if the received event
+ * is for this thread and has correct attributes. Then debugger
+ * removes event request.
+ * Finally, debugger disconnects debuggee, waits for it exited
+ * and exits too with proper exit code.
+ * COMMENTS
+ * Test was fixed due to test bug:
+ * 4797978 TEST_BUG: potential race condition in a number of JDWP tests
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Event.THREAD_DEATH.thrdeath001
+ * nsk.jdwp.Event.THREAD_DEATH.thrdeath001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Event.THREAD_DEATH.thrdeath001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_DEATH/thrdeath001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.Event.THREAD_DEATH;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class thrdeath001a {
+
+ static final int BREAKPOINT_LINE = 93;
+
+ static ArgumentHandler argumentHandler = null;
+ static Log log = null;
+
+ public static void main(String args[]) {
+ thrdeath001a _thrdeath001a = new thrdeath001a();
+ System.exit(thrdeath001.JCK_STATUS_BASE + _thrdeath001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // create tested thread
+ log.display("Creating tested thread");
+ TestedClass.thread = new TestedClass(thrdeath001.TESTED_THREAD_NAME);
+ log.display(" ... thread created");
+
+ // reach breakpoint
+ TestedClass.ready();
+
+ // start tested thread
+ log.display("Starting tested thread");
+ TestedClass.thread.start();
+ log.display(" ... thread started");
+
+ // wait for thread finished
+ try {
+ log.display("Waiting for tested thread finished");
+ TestedClass.thread.join();
+ log.display(" ... thread finished");
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for tested thread finished");
+ return thrdeath001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return thrdeath001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass extends Thread {
+ public static volatile TestedClass thread = null;
+
+ public TestedClass(String name) {
+ super(name);
+ }
+
+ public static void ready() {
+ log.display("Breakpoint line reached");
+ // next line is for breakpoint
+ int foo = 0; // BREAKPOINT_LINE
+ log.display("Breakpoint line passed");
+ }
+
+ public void run() {
+ log.display("Tested thread: started");
+ log.display("Tested thread: finished");
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_START/thrstart001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,588 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.THREAD_START;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP event: THREAD_START.
+ *
+ * See thrstart001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP event is tested in the method waitForTestedEvent().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class thrstart001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Event.THREAD_START";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "thrstart001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP event constants
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.THREAD_START;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+
+ // name and signature of the tested class
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+ static final String TESTED_THREAD_NAME = "TestedThread";
+
+ // name of field and method of tested class
+ static final String THREAD_FIELD_NAME = "thread";
+ static final String BREAKPOINT_METHOD_NAME = "ready";
+ static final int BREAKPOINT_LINE = thrstart001a.BREAKPOINT_LINE;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // obtained data
+ long testedClassID = 0;
+ long testedThreadID = 0;
+ int eventRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new thrstart001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // prepare debuggee
+ log.display("\n>>> Getting prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP event
+ log.display("\n>>> Testing JDWP event \n");
+ log.display("Making request for THREAD_START event for class:\n\t"
+ + TESTED_CLASS_NAME);
+ requestTestedEvent();
+ log.display(" ... got requestID: " + eventRequestID);
+ log.display("");
+
+ // resume debuggee
+ log.display("Resumindg debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+ log.display("");
+
+ // wait for tested THREAD_START event
+ log.display("Waiting for THREAD_START event received");
+ waitForTestedEvent();
+ log.display(" ... event received");
+ log.display("");
+
+ // clear tested request for THREAD_START event
+ log.display("Clearing request for tested event");
+ clearTestedRequest();
+ log.display(" ... request removed");
+
+ // finish debuggee after testing
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Get debuggee prepared for testing and obtain required data.
+ */
+ void prepareForTest() {
+ // wait for tested class loaded
+ log.display("Waiting for tested class loaded");
+ testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... got classID: " + testedClassID);
+ log.display("");
+
+ // wait for breakpoint reached
+ log.display("Waiting for breakpoint reached at: "
+ + BREAKPOINT_METHOD_NAME + ":" + BREAKPOINT_LINE);
+ long threadID = debugee.waitForBreakpointReached(testedClassID,
+ BREAKPOINT_METHOD_NAME,
+ BREAKPOINT_LINE,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... breakpoint reached with threadID: " + threadID);
+ log.display("");
+
+ // get thread value from static field of tested class
+ log.display("Getting thread value from static field: " + THREAD_FIELD_NAME);
+ JDWP.Value value = debugee.getStaticFieldValue(testedClassID, THREAD_FIELD_NAME,
+ JDWP.Tag.THREAD);
+ testedThreadID = ((Long)value.getValue()).longValue();
+ log.display(" ... got threadID: " + testedThreadID);
+ }
+
+ /**
+ * Make request for tested THREAD_START event.
+ */
+ void requestTestedEvent() {
+ Failure failure = new Failure("Error occured while makind request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Set");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set);
+ log.display(" eventKind: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" eventPolicy: " + TESTED_EVENT_SUSPEND_POLICY);
+ command.addByte(TESTED_EVENT_SUSPEND_POLICY);
+ log.display(" modifiers: " + 1);
+ command.addInt(1);
+ log.display(" modKind: " + JDWP.EventModifierKind.THREAD_ONLY);
+ command.addByte(JDWP.EventModifierKind.THREAD_ONLY);
+ log.display(" threadID: " + testedThreadID);
+ command.addObjectID(testedThreadID);
+ command.setLength();
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract requestID
+ int requestID = 0;
+ try {
+ requestID = reply.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract requestID from request reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // check requestID
+ if (requestID == 0) {
+ log.complain("Unexpected null requestID returned: " + requestID);
+ success = false;
+ throw failure;
+ }
+
+ eventRequestID = requestID;
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Clear request for tested THREAD_START event.
+ */
+ void clearTestedRequest() {
+ Failure failure = new Failure("Error occured while clearing request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Clear");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear);
+ log.display(" event: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" requestID: " + eventRequestID);
+ command.addInt(eventRequestID);
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ log.display(" no data");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Wait for tested THREAD_START event.
+ */
+ void waitForTestedEvent() {
+
+ EventPacket eventPacket = null;
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for event packet");
+ eventPacket = debugee.getEventPacket(timeout);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.complain("Unable to read tested event packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check suspendPolicy value
+ if (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY) {
+ log.complain("Unexpected SuspendPolicy in tested event packet: " +
+ suspendPolicy + " (expected: " + TESTED_EVENT_SUSPEND_POLICY + ")");
+ success = false;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ long eventThreadID = 0;
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check eventKind
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ log.complain("Unexpected VM_DEATH event received: " +
+ eventKind + " (expected: " + JDWP.EventKind.THREAD_START + ")");
+ dead = true;
+ success = false;
+ return;
+ } else if (eventKind != JDWP.EventKind.THREAD_START) {
+ log.complain("Unexpected eventKind of event " + i + " in tested event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.THREAD_START + ")");
+ success = false;
+ return;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != eventRequestID) {
+ log.complain("Unexpected requestID of event " + i + " in tested event packet: " +
+ requestID + " (expected: " + eventRequestID + ")");
+ success = false;
+ }
+
+ // get threadID
+ long threadID = 0;
+ try {
+ threadID = eventPacket.getObjectID();
+ log.display(" threadID: " + threadID);
+ } catch (BoundException e) {
+ log.complain("Unable to get threadID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check threadID
+ if (threadID != testedThreadID) {
+ log.complain("Unexpected threadID of event " + i + " in tested event packet: " +
+ threadID + " (expected: " + testedThreadID + ")");
+ success = false;
+ }
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event packet parsed");
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_START/thrstart001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Event/THREAD_START/thrstart001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Event
+ * command: Composite
+ * command set: EventRequest
+ * command: Set, Clear
+ * event kind: THREAD_START
+ * Test checks that
+ * 1) debuggee successfully creates THREAD_START event request
+ * for particular threadID
+ * 2) expected THREAD_START event is received when the thread
+ * started into debuggee
+ * 3) debuggee successfully removes event request
+ * Test consists of two compoments:
+ * debugger: thrstart001
+ * debuggee: thrstart001a
+ * First, debugger uses nsk.share support classes to launch debuggee,
+ * and obtains Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded and breakpoint reached.
+ * Then debugger gets threadID from the class static field and makes
+ * THREAD_START event request for this thread,
+ * When event is received debugger checks if the received event
+ * is for this thread and has correct attributes. Then debugger
+ * removes event request.
+ * Finally, debugger disconnects debuggee, waits for it exited
+ * and exits too with proper exit code.
+ * COMMENTS
+ * Test was fixed due to test bug:
+ * 4797978 TEST_BUG: potential race condition in a number of JDWP tests
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Event.THREAD_START.thrstart001
+ * nsk.jdwp.Event.THREAD_START.thrstart001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Event.THREAD_START.thrstart001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/THREAD_START/thrstart001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.Event.THREAD_START;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class thrstart001a {
+
+ static final int BREAKPOINT_LINE = 93;
+
+ static ArgumentHandler argumentHandler = null;
+ static Log log = null;
+
+ public static void main(String args[]) {
+ thrstart001a _thrstart001a = new thrstart001a();
+ System.exit(thrstart001.JCK_STATUS_BASE + _thrstart001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // create tested thread
+ log.display("Creating tested thread");
+ TestedClass.thread = new TestedClass(thrstart001.TESTED_THREAD_NAME);
+ log.display(" ... thread created");
+
+ // reach breakpoint
+ TestedClass.ready();
+
+ // start tested thread
+ log.display("Starting tested thread");
+ TestedClass.thread.start();
+ log.display(" ... thread started");
+
+ // wait for thread finished
+ try {
+ log.display("Waiting for tested thread finished");
+ TestedClass.thread.join();
+ log.display(" ... thread finished");
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for tested thread finished");
+ return thrstart001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return thrstart001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass extends Thread {
+ public static volatile TestedClass thread = null;
+
+ public TestedClass(String name) {
+ super(name);
+ }
+
+ public static void ready() {
+ log.display("Breakpoint line reached");
+ // next line is for breakpoint
+ int foo = 0; // BREAKPOINT_LINE
+ log.display("Breakpoint line passed");
+ }
+
+ public void run() {
+ log.display("Tested thread: started");
+ log.display("Tested thread: finished");
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.VM_DEATH;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP event: VM_DEATH.
+ *
+ * See vmdeath001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP event is tested in the method waitForTestedEvent().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class vmdeath001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Event.VM_DEATH";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "vmdeath001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "Event.Composite";
+ static final int JDWP_COMMAND_ID = JDWP.Command.Event.Composite;
+ static final int JDWP_EVENT_KIND = JDWP.EventKind.VM_DEATH;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new vmdeath001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // resume debuggee
+ log.display("Resumindg debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for tested VM_DEATH event
+ log.display("\n>>> Testing JDWP event \n");
+ waitForTestedEvent();
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Wait for tested VM_DEATH event.
+ */
+ void waitForTestedEvent() {
+
+ EventPacket eventPacket = null;
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for event packet (for " + timeout + "ms timeout)");
+ eventPacket = debugee.getEventPacket(timeout);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.complain("Unable to read tested event packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is OK");
+ } catch (BoundException e) {
+ log.complain("Bad header of tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check suspendPolicy value
+ if (suspendPolicy != JDWP.SuspendPolicy.NONE) {
+ log.complain("Unexpected SuspendPolicy in tested event packet: " +
+ suspendPolicy + " (expected: " + JDWP.SuspendPolicy.NONE + ")");
+ success = false;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check eventKind
+ if (eventKind != JDWP.EventKind.VM_DEATH) {
+ log.complain("Unexpected eventKind of event " + i + " in tested event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.VM_DEATH + ")");
+ success = false;
+ return;
+ }
+ dead = true;
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != 0) {
+ log.complain("Unexpected requestID of event " + i + " in tested event packet: " +
+ requestID + " (expected: " + 0 + ")");
+ success = false;
+ return;
+ }
+
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event parsed");
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Event/VM_DEATH/vmdeath001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Event
+ * command: Composite
+ * event kind: VM_DEATH
+ * Test checks that debugee accept the event packet with correct
+ * attributes at debuggee's exit.
+ * Test consists of two compoments:
+ * debugger: vmdeath001
+ * debuggee: vmdeath001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Debugger waits for debuggee started and resumes it to allow debuggee
+ * to exit.
+ * Next, debugger waits for an event packet and check if the received
+ * event is a single VM_DEATH event with correct attributes.
+ * Finally, debugger disconnects debuggee, waits for it exited
+ * and exits too with proper exit code.
+ * COMMENTS
+ * Test was fixed due to test bug:
+ * 4797978 TEST_BUG: potential race condition in a number of JDWP tests
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Event.VM_DEATH.vmdeath001
+ * nsk.jdwp.Event.VM_DEATH.vmdeath001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Event.VM_DEATH.vmdeath001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.VM_DEATH;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class vmdeath001a {
+
+ public static void main(String args[]) {
+ vmdeath001a _vmdeath001a = new vmdeath001a();
+ System.exit(vmdeath001.JCK_STATUS_BASE + _vmdeath001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return vmdeath001.PASSED;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath002.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,550 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.VM_DEATH;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP event: VM_DEATH.
+ *
+ * See vmdeath002.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP event is tested in the method waitForTestedEvent().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class vmdeath002 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // VM capability constants
+ static final int VM_CAPABILITY_NUMBER = JDWP.Capability.CAN_REQUEST_VMDEATH_EVENT;
+ static final String VM_CAPABILITY_NAME = "canRequestVMDeathEvent";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Event.VM_DEATH";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "vmdeath002";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP event constants
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.VM_DEATH;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean resumed = false;
+ boolean success = true;
+
+ // obtained data
+ int eventRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new vmdeath002().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // check for VM capability
+ log.display("\n>>> Checking VM capability \n");
+ log.display("Getting VM capability: " + VM_CAPABILITY_NAME);
+ boolean capable = debugee.getNewCapability(VM_CAPABILITY_NUMBER, VM_CAPABILITY_NAME);
+ log.display(" ... got VM capability: " + capable);
+
+ // exit as PASSED if this capability is not supported
+ if (!capable) {
+ out.println("TEST PASSED: unsupported VM capability: "
+ + VM_CAPABILITY_NAME);
+ return PASSED;
+ }
+
+ // test JDWP event
+ log.display("\n>>> Testing JDWP event \n");
+ log.display("Making request for METHOD_DEATH event");
+ requestTestedEvent();
+ log.display(" ... got requestID: " + eventRequestID);
+ log.display("");
+
+ // resume debuggee
+ log.display("Resumindg debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+ log.display("");
+
+ // wait for tested VM_DEATH event
+ log.display("Waiting for VM_DEATH event received");
+ waitForTestedEvent();
+ log.display(" ... event received");
+ log.display("");
+
+ if (!dead) {
+ // clear tested request for VM_DEATH event
+ log.display("\n>>> Clearing request for tested event \n");
+ clearTestedRequest();
+
+ // finish debuggee after testing
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+ } else if (!resumed) {
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Make request for tested METHOD_ENTRY event.
+ */
+ void requestTestedEvent() {
+ Failure failure = new Failure("Error occured while makind request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Set");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set);
+ log.display(" eventKind: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" eventPolicy: " + TESTED_EVENT_SUSPEND_POLICY);
+ command.addByte(TESTED_EVENT_SUSPEND_POLICY);
+ log.display(" modifiers: " + 0);
+ command.addInt(0);
+ command.setLength();
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract requestID
+ int requestID = 0;
+ try {
+ requestID = reply.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract requestID from request reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // check requestID
+ if (requestID == 0) {
+ log.complain("Unexpected null requestID returned: " + requestID);
+ success = false;
+ throw failure;
+ }
+
+ eventRequestID = requestID;
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+
+ }
+
+ /**
+ * Clear request for tested METHOD_ENTRY event.
+ */
+ void clearTestedRequest() {
+ Failure failure = new Failure("Error occured while clearing request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Clear");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear);
+ log.display(" event: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" requestID: " + eventRequestID);
+ command.addInt(eventRequestID);
+ log.display(" ... command packet composed");
+ log.display("");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+ log.display("");
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ log.display(" no data");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Wait for tested VM_DEATH event.
+ */
+ void waitForTestedEvent() {
+
+ EventPacket eventPacket = null;
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for event packet");
+ eventPacket = debugee.getEventPacket(timeout);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.complain("Unable to read tested event packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is OK");
+ } catch (BoundException e) {
+ log.complain("Bad header of tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check suspendPolicy value
+ if (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY) {
+ log.complain("Unexpected SuspendPolicy in tested event packet: " +
+ suspendPolicy + " (expected: " + TESTED_EVENT_SUSPEND_POLICY + ")");
+ success = false;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ int eventReceived = 0;
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check eventKind
+ if (eventKind != TESTED_EVENT_KIND) {
+ log.complain("Unexpected eventKind of event " + i + " in tested event packet: " +
+ eventKind + " (expected: " + TESTED_EVENT_KIND + ")");
+ success = false;
+ continue;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ dead = true;
+ resumed = (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY);
+ return;
+ }
+
+ // check requestID
+ if (requestID == eventRequestID) {
+ eventReceived++;
+ } else if (requestID == 0) {
+ dead = true;
+ resumed = (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY);
+ } else {
+ log.complain("Unexpected requestID of event " + i + " in tested event packet: " +
+ requestID + " (expected: " + eventRequestID + " or 0)");
+ success = false;
+ return;
+ }
+
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ int extra = eventPacket.length() - eventPacket.currentPosition();
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString() + " (" + extra + " bytes)");
+ success = false;
+ }
+
+ log.display(" ... event packet parsed");
+
+ if (eventReceived <= 0) {
+ log.complain("No requested event received: " + eventReceived + " (expected: 1)");
+ success = false;
+ }
+
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath002/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Event/VM_DEATH/vmdeath002.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Event
+ * command: Composite
+ * event kind: VM_DEATH
+ * Test checks that resquested VM_DEATH event is received upon
+ * debuggee VM exit either together with automatically generated
+ * VM_DEATH event or in a singleton event packet.
+ * Test consists of two compoments:
+ * debugger: vmdeath002
+ * debuggee: vmdeath002a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Debugger waits for debuggee started and makes an request for VM_DEATH
+ * event. Then, it resumes debuggee to allow it to exit.
+ * Next, debugger waits for an event packet and check if the received
+ * event contains only VM_DEATH events either requested one or automatically
+ * generated one. Received event should have expected requestID and
+ * correct attributes.
+ * Finally, debugger disconnects debuggee, waits for it exited
+ * and exits too with proper exit code.
+ * COMMENTS
+ * Test was fixed due to test bug:
+ * 4797978 TEST_BUG: potential race condition in a number of JDWP tests
+ * Test was fixed due to test bug:
+ * 4863716 TEST_BUG: misprint in JDWP test vmdeath002
+ * Test was fixed due to test bug:
+ * 4973268 TEST_BUG: nsk/jdwp/Event/VM_DEATH/vmdeath002 needs to be updated
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Event.VM_DEATH.vmdeath002
+ * nsk.jdwp.Event.VM_DEATH.vmdeath002a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Event.VM_DEATH.vmdeath002
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_DEATH/vmdeath002a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.VM_DEATH;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class vmdeath002a {
+
+ public static void main(String args[]) {
+ vmdeath002a _vmdeath002a = new vmdeath002a();
+ System.exit(vmdeath002.JCK_STATUS_BASE + _vmdeath002a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return vmdeath002.PASSED;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_START/vmstart001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.VM_START;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP event: VM_START.
+ *
+ * See vmstart001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP event is tested in the method waitForTestedEvent().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class vmstart001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Event.VM_START";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "vmstart001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "Event.Composite";
+ static final int JDWP_COMMAND_ID = JDWP.Command.Event.Composite;
+ static final int JDWP_EVENT_KIND = JDWP.EventKind.VM_START;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new vmstart001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for tested VM_START event
+ log.display("\n>>> Testing JDWP event \n");
+ waitForTestedEvent();
+
+ // finish debuggee after testing
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Wait for tested VM_START event.
+ */
+ void waitForTestedEvent() {
+
+ EventPacket eventPacket = null;
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for event packet");
+ eventPacket = debugee.getEventPacket(timeout);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.complain("Unable to read tested event packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is OK");
+ } catch (BoundException e) {
+ log.complain("Bad header of tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ if (suspendPolicy != JDWP.SuspendPolicy.ALL) {
+ log.complain("Unexpected SuspendPolicy in tested event packet: " +
+ suspendPolicy + " (expected: " + JDWP.SuspendPolicy.ALL + ")");
+ success = false;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check eventKind
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ log.complain("Unexpected VM_DEATH event received: " +
+ eventKind + " (expected: " + JDWP.EventKind.THREAD_START + ")");
+ dead = true;
+ success = false;
+ return;
+ } else if (eventKind != JDWP.EventKind.VM_START) {
+ log.complain("Unexpected eventKind of event " + i + " in tested event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.VM_START + ")");
+ success = false;
+ return;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != 0) {
+ log.complain("Unexpected requestID of event " + i + " in tested event packet: " +
+ requestID + " (expected: " + 0 + ")");
+ success = false;
+ return;
+ }
+
+ // get threadID
+ long threadID = 0;
+ try {
+ threadID = eventPacket.getObjectID();
+ log.display(" threadID: " + threadID);
+ } catch (BoundException e) {
+ log.complain("Unable to get threadID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (threadID == 0) {
+ log.complain("Unexpected null threadID of event " + i + " in tested event packet: " +
+ threadID + " (expected: not " + 0 + ")");
+ success = false;
+ return;
+ }
+
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event parsed");
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_START/vmstart001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Event/VM_START/vmstart001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Event
+ * command: Composite
+ * event kind: VM_START
+ * Test checks that debugee accept the event packet with correct
+ * attributes at debuggee's startup.
+ * Test consists of two compoments:
+ * debugger: vmstart001
+ * debuggee: vmstart001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for an event packet and check if the received
+ * event is a single VM_START event with correct attributes.
+ * Finally, debugger disconnects debuggee, waits for it exited
+ * and exits too with proper exit code.
+ * COMMENTS
+ * Test was fixed due to test bug:
+ * 4797978 TEST_BUG: potential race condition in a number of JDWP tests
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Event.VM_START.vmstart001
+ * nsk.jdwp.Event.VM_START.vmstart001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Event.VM_START.vmstart001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Event/VM_START/vmstart001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Event.VM_START;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class vmstart001a {
+
+ public static void main(String args[]) {
+ vmstart001a _vmstart001a = new vmstart001a();
+ System.exit(vmstart001.JCK_STATUS_BASE + _vmstart001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return vmstart001.PASSED;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Clear/clear001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,477 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.EventRequest.Clear;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: EventRequest.Clear.
+ *
+ * See clear001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class clear001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.EventRequest.Clear";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "clear001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "EventRequest.Clear";
+ static final int JDWP_COMMAND_ID = JDWP.Command.EventRequest.Clear;
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.BREAKPOINT;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+
+ // name and signature of the tested class
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of field and method of tested class
+ static final String TESTED_METHOD_NAME = "run";
+ static final int BREAKPOINT_LINE = clear001a.BREAKPOINT_LINE;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // obtained data
+ long testedClassID = 0;
+ long testedMethodID = 0;
+ int eventRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new clear001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // get debuggee prepared for testing
+ log.display("\n>>> Get debuggee prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand();
+
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event instead of BREAKPOINT event");
+ waitForVMDeathEvent();
+
+ if (!dead) {
+ // resume debuggee after BREAKPOINT event
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for final VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ void prepareForTest() {
+ // wait for tested class loaded
+ log.display("Waiting for tested class loaded");
+ testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... got classID: " + testedClassID);
+ log.display("");
+
+ // get methodID for tested method
+ log.display("Getting tested methodID by name: " + TESTED_METHOD_NAME);
+ testedMethodID = debugee.getMethodID(testedClassID, TESTED_METHOD_NAME, true);
+ log.display(" ... got methodID: " + testedMethodID);
+
+ // make request for BREAKPOINT event
+ log.display("Making request for BREAKPOINT event at: "
+ + TESTED_METHOD_NAME + ":" + BREAKPOINT_LINE);
+ eventRequestID = debugee.requestBreakpointEvent(JDWP.TypeTag.CLASS, testedClassID,
+ testedMethodID, BREAKPOINT_LINE,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... got requestID: " + eventRequestID);
+ }
+
+
+ /**
+ * Test JDWP command.
+ */
+ void testCommand() {
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" event: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" requestID: " + eventRequestID);
+ command.addInt(eventRequestID);
+ command.setLength();
+ log.display(" ... command packet created");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // receive reply packet from debugee
+ ReplyPacket reply = new ReplyPacket();
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Wrong header of reply packet for tested command:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet data:");
+ reply.resetPosition();
+
+ // no out data
+ log.display(" no out data");
+
+ log.display(" ... packet data is parsed");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+ }
+
+ /**
+ * Wait for VM_DEATH event.
+ */
+ void waitForVMDeathEvent() {
+
+ EventPacket eventPacket = null;
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for event packet");
+ eventPacket = debugee.getEventPacket(timeout);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.complain("Unable to read tested event packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ long eventThreadID = 0;
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check eventKind
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ log.display("Expected VM_DEATH event received intead of BREAKPOINT event");
+ dead = true;
+ return;
+ } else if (eventKind == JDWP.EventKind.BREAKPOINT) {
+ log.complain("Unexpected BREAKPOINT event received in event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.VM_DEATH + ")");
+ success = false;
+ } else {
+ log.complain("Unexpected eventKind of event " + i + " in event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.VM_DEATH + ")");
+ success = false;
+ return;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from BREAKPOINT event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != eventRequestID) {
+ log.complain("Unexpected requestID of event " + i + " in BREAKPOINT event packet: " +
+ requestID + " (expected: " + eventRequestID + ")");
+ success = false;
+ }
+
+ // get threadID
+ long threadID = 0;
+ try {
+ threadID = eventPacket.getObjectID();
+ log.display(" threadID: " + threadID);
+ } catch (BoundException e) {
+ log.complain("Unable to get threadID of event #" + i + " from BREAKPOINT event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // get location
+ JDWP.Location location = null;
+ try {
+ location = eventPacket.getLocation();
+ log.display(" location: " + location);
+ } catch (BoundException e) {
+ log.complain("Unable to get location of event #" + i + " from BREAKPOINT event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event packet parsed");
+ }
+
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee if not dead
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Clear/clear001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/EventRequest/Clear/clear001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: EventRequest
+ * command: Clear
+ * event kind: BREAKPOINT
+ * Test checks that debuggee accept tested command and replies
+ * with correct reply packet. Also test checks that no breakpoint
+ * events occurs for cleared BREAKPOINT request.
+ * Test consists of two compoments:
+ * debugger: clear001
+ * debuggee: clear001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded into debuggee and
+ * makes request for BREAKPOINT at method run().
+ * Then, debugger creates creates command packet for command
+ * EventRequest.Clear with created requestID, sends it to debuggee,
+ * waits for reply packet and check that reply is correct and has
+ * no reply data.
+ * Then, debugger resumes debuggee and waits for an VM_DEATH event.
+ * If received event is BREAKPOINT event, debugger complains an error.
+ * Finally, debugger disconnects debuggee, waits for it exits
+ * and exits too with proper exit code.
+ * COMMENTS
+ * Test was fixed due to test bug:
+ * 4797978 TEST_BUG: potential race condition in a number of JDWP tests
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.EventRequest.Clear.clear001
+ * nsk.jdwp.EventRequest.Clear.clear001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.EventRequest.Clear.clear001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Clear/clear001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.EventRequest.Clear;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class clear001a {
+
+ static final int BREAKPOINT_LINE = 80;
+
+ static ArgumentHandler argumentHandler = null;
+ static Log log = null;
+
+ public static void main(String args[]) {
+ clear001a _clear001a = new clear001a();
+ System.exit(clear001.JCK_STATUS_BASE + _clear001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // ensure tested class is loaded
+ log.display("Creating object of tested class");
+ TestedClass object = new TestedClass();
+ log.display(" ... object created");
+
+ // invoke method with breakpoint
+ log.display("Invoking method with breakpoint");
+ object.run();
+ log.display(" ... method invoked");
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return clear001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass {
+ int foo = 0;
+
+ public TestedClass() {
+ foo = 1000;
+ }
+
+ public void run() {
+ log.display("Breakpoint line reached");
+ // next line is for breakpoint
+ foo = 0; // BREAKPOINT_LINE
+ log.display("Breakpoint line passed");
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,474 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.EventRequest.ClearAllBreakpoints;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: EventRequest.ClearAllBreakpoints.
+ *
+ * See clrallbreakp001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class clrallbreakp001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.EventRequest.ClearAllBreakpoints";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "clrallbreakp001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "EventRequest.ClearAllBreakpoints";
+ static final int JDWP_COMMAND_ID = JDWP.Command.EventRequest.ClearAllBreakpoints;
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.VM_START;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+
+ // name and signature of the tested class
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of field and method of tested class
+ static final String TESTED_METHOD_NAME = "run";
+ static final int BREAKPOINT_LINE = clrallbreakp001a.BREAKPOINT_LINE;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // obtained data
+ long testedClassID = 0;
+ long testedMethodID = 0;
+ int eventRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new clrallbreakp001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // get debuggee prepared for testing
+ log.display("\n>>> Get debuggee prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand();
+
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event instead of BREAKPOINT event");
+ waitForVMDeathEvent();
+
+ if (!dead) {
+ // resume debuggee after BREAKPOINT event
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for fianl VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ void prepareForTest() {
+ // wait for tested class loaded
+ log.display("Waiting for tested class loaded");
+ testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... got classID: " + testedClassID);
+ log.display("");
+
+ // get methodID for tested method
+ log.display("Getting tested methodID by name: " + TESTED_METHOD_NAME);
+ testedMethodID = debugee.getMethodID(testedClassID, TESTED_METHOD_NAME, true);
+ log.display(" ... got methodID: " + testedMethodID);
+
+ // make request for BREAKPOINT event
+ log.display("Making request for BREAKPOINT event at: "
+ + TESTED_METHOD_NAME + ":" + BREAKPOINT_LINE);
+ eventRequestID = debugee.requestBreakpointEvent(JDWP.TypeTag.CLASS, testedClassID,
+ testedMethodID, BREAKPOINT_LINE,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... got requestID: " + eventRequestID);
+ }
+
+
+ /**
+ * Test JDWP command.
+ */
+ void testCommand() {
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" no out data");
+ command.setLength();
+ log.display(" ... command packet created");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // receive reply packet from debugee
+ ReplyPacket reply = new ReplyPacket();
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Wrong header of reply packet for tested command:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet data:");
+ reply.resetPosition();
+
+ // no out data
+ log.display(" no out data");
+
+ log.display(" ... packet data is parsed");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+ }
+
+ /**
+ * Wait for VM_DEATH event.
+ */
+ void waitForVMDeathEvent() {
+
+ EventPacket eventPacket = null;
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for event packet");
+ eventPacket = debugee.getEventPacket(timeout);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.complain("Unable to read tested event packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ long eventThreadID = 0;
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check eventKind
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ log.display("Expected VM_DEATH event received intead of BREAKPOINT event");
+ dead = true;
+ return;
+ } else if (eventKind == JDWP.EventKind.BREAKPOINT) {
+ log.complain("Unexpected BREAKPOINT event received in event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.VM_DEATH + ")");
+ success = false;
+ } else {
+ log.complain("Unexpected eventKind of event " + i + " in event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.VM_DEATH + ")");
+ success = false;
+ return;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from BREAKPOINT event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != eventRequestID) {
+ log.complain("Unexpected requestID of event " + i + " in BREAKPOINT event packet: " +
+ requestID + " (expected: " + eventRequestID + ")");
+ success = false;
+ }
+
+ // get threadID
+ long threadID = 0;
+ try {
+ threadID = eventPacket.getObjectID();
+ log.display(" threadID: " + threadID);
+ } catch (BoundException e) {
+ log.complain("Unable to get threadID of event #" + i + " from BREAKPOINT event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // get location
+ JDWP.Location location = null;
+ try {
+ location = eventPacket.getLocation();
+ log.display(" location: " + location);
+ } catch (BoundException e) {
+ log.complain("Unable to get location of event #" + i + " from BREAKPOINT event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event packet parsed");
+ }
+
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee if not dead
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: EventRequest
+ * command: ClearAllBreakpoints
+ * Test checks that debuggee accept tested command and replies
+ * with correct reply packet. Also test checks that no breakpoint
+ * events occures for previously created BREAKPOINT request.
+ * Test consists of two compoments:
+ * debugger: clrallbreakp001
+ * debuggee: clrallbreakp001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded into debuggee and
+ * makes request for BREAKPOINT at method run().
+ * Then, debugger creates creates command packet for command
+ * EventRequest.ClearAllBreakpoints, sends it to debuggee, waits
+ * for reply packet and check that reply is correct and has no reply data.
+ * Then, debugger resumes debuggee and waits for an VM_DEATH event.
+ * If received event is BREAKPOINT event, debugger complains an error.
+ * Finally, debugger disconnectes debuggee, waits for it exits
+ * and exits too with proper exit code.
+ * COMMENTS
+ * Test was fixed due to test bug:
+ * 4797978 TEST_BUG: potential race condition in a number of JDWP tests
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.EventRequest.ClearAllBreakpoints.clrallbreakp001
+ * nsk.jdwp.EventRequest.ClearAllBreakpoints.clrallbreakp001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.EventRequest.ClearAllBreakpoints.clrallbreakp001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.EventRequest.ClearAllBreakpoints;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class clrallbreakp001a {
+
+ static final int BREAKPOINT_LINE = 80;
+
+ static ArgumentHandler argumentHandler = null;
+ static Log log = null;
+
+ public static void main(String args[]) {
+ clrallbreakp001a _clrallbreakp001a = new clrallbreakp001a();
+ System.exit(clrallbreakp001.JCK_STATUS_BASE + _clrallbreakp001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // ensure tested class is loaded
+ log.display("Creating object of tested class");
+ TestedClass object = new TestedClass();
+ log.display(" ... object created");
+
+ // invoke method with breakpoint
+ log.display("Invoking method with breakpoint");
+ object.run();
+ log.display(" ... method invoked");
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return clrallbreakp001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass {
+ int foo = 0;
+
+ public TestedClass() {
+ foo = 1000;
+ }
+
+ public void run() {
+ log.display("Breakpoint line reached");
+ // next line is for breakpoint
+ foo = 0; // BREAKPOINT_LINE
+ log.display("Breakpoint line passed");
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp002.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.EventRequest.ClearAllBreakpoints;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: EventRequest.ClearAllBreakpoints.
+ *
+ * See clrallbreakp002.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class clrallbreakp002 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.EventRequest.ClearAllBreakpoints";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "clrallbreakp002";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "EventRequest.ClearAllBreakpoints";
+ static final int JDWP_COMMAND_ID = JDWP.Command.EventRequest.ClearAllBreakpoints;
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.VM_START;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+
+ // name and signature of the tested class
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // obtained data
+ long testedClassID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new clrallbreakp002().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // get debuggee prepared for testing
+ log.display("\n>>> Getting prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand();
+
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Get debuggee prepared for testing and obtain required data.
+ */
+ void prepareForTest() {
+ // wait for tested class loaded
+ log.display("Waiting for tested class loaded");
+ testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... got classID: " + testedClassID);
+ log.display("");
+ }
+
+ /**
+ * Test JDWP command.
+ */
+ void testCommand() {
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" no out data");
+ command.setLength();
+ log.display(" ... command packet created");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // receive reply packet from debugee
+ ReplyPacket reply = new ReplyPacket();
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Wrong header of reply packet for tested command:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet data:");
+ reply.resetPosition();
+
+ // no out data
+ log.display(" no out data");
+
+ log.display(" ... packet data is parsed");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee if not dead
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp002/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp002.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: EventRequest
+ * command: ClearAllBreakpoints
+ * Test checks that debugee accepts command packet for tested command
+ * and replies with correct reply packet, even if no requests for
+ * BREAKPOINT event had been made before.
+ * Test consists of two compoments:
+ * debugger: clrallbreakp002
+ * debuggee: clrallbreakp002a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded, creates command packet
+ * for EventRequest.ClearAllBreakpoints command and sends it to debuggee.
+ * Then debugger reads reply packet and checks if reply packet is correct
+ * and has no reply data.
+ * Finally, debugger disconnectes debuggee, waits for it exits
+ * and exits too with proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.EventRequest.ClearAllBreakpoints.clrallbreakp002
+ * nsk.jdwp.EventRequest.ClearAllBreakpoints.clrallbreakp002a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.EventRequest.ClearAllBreakpoints.clrallbreakp002
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp002a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.EventRequest.ClearAllBreakpoints;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class clrallbreakp002a {
+
+ public static void main(String args[]) {
+ clrallbreakp002a _clrallbreakp002a = new clrallbreakp002a();
+ System.exit(clrallbreakp002.JCK_STATUS_BASE + _clrallbreakp002a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // ensure tested class is loaded
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+ log.display(" ... object created");
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return clrallbreakp002.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass {
+ int foo = 0;
+
+ public TestedClass() {
+ foo = 1000;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp003.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.EventRequest.ClearAllBreakpoints;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: EventRequest.ClearAllBreakpoints.
+ *
+ * See clrallbreakp003.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class clrallbreakp003 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.EventRequest.ClearAllBreakpoints";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "clrallbreakp003";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "EventRequest.ClearAllBreakpoints";
+ static final int JDWP_COMMAND_ID = JDWP.Command.EventRequest.ClearAllBreakpoints;
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.VM_START;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+
+ // name and signature of the tested class
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of field and method of tested class
+ static final String TESTED_METHOD_NAME = "run";
+ static final int BREAKPOINT_LINE = clrallbreakp003a.BREAKPOINT_LINE;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // obtained data
+ long testedClassID = 0;
+ long testedMethodID = 0;
+ int eventRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new clrallbreakp003().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // get debuggee prepared for testing
+ log.display("\n>>> Get debuggee prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand();
+
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for fianl VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ void prepareForTest() {
+ // wait for tested class loaded
+ log.display("Waiting for tested class loaded");
+ testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... got classID: " + testedClassID);
+ log.display("");
+
+ // get methodID for tested method
+ log.display("Getting tested methodID by name: " + TESTED_METHOD_NAME);
+ testedMethodID = debugee.getMethodID(testedClassID, TESTED_METHOD_NAME, true);
+ log.display(" ... got methodID: " + testedMethodID);
+
+ // make request for BREAKPOINT event
+ log.display("Making request for BREAKPOINT event at: "
+ + TESTED_METHOD_NAME + ":" + BREAKPOINT_LINE);
+ eventRequestID = debugee.requestBreakpointEvent(JDWP.TypeTag.CLASS, testedClassID,
+ testedMethodID, BREAKPOINT_LINE,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... got requestID: " + eventRequestID);
+
+ // clear request for BREAKPOINT event
+ log.display("Clearing BREAKPOINT event requestID: " + eventRequestID);
+ debugee.clearEventRequest(JDWP.EventKind.BREAKPOINT, eventRequestID);
+ log.display(" ... request removed");
+ }
+
+
+ /**
+ * Test JDWP command.
+ */
+ void testCommand() {
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" no out data");
+ command.setLength();
+ log.display(" ... command packet created");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // receive reply packet from debugee
+ ReplyPacket reply = new ReplyPacket();
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Wrong header of reply packet for tested command:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet data:");
+ reply.resetPosition();
+
+ // no out data
+ log.display(" no out data");
+
+ log.display(" ... packet data is parsed");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee if not dead
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp003/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp003.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: EventRequest
+ * command: ClearAllBreakpoints
+ * Test checks that debuggee accept tested command and replies
+ * with correct reply packet, even if all requests for breakpoint
+ * event had been cleared before.
+ * Test consists of two compoments:
+ * debugger: clrallbreakp003
+ * debuggee: clrallbreakp003a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded into debuggee,
+ * makes request for BREAKPOINT at method run() and immediately
+ * cleares this request.
+ * Then, debugger creates command packet for tested command
+ * EventRequest.ClearAllBreakpoints, sends it to debuggee, waits
+ * for reply packet and checks that reply is correct and has no
+ * reply data.
+ * Finally, debugger disconnectes debuggee, waits for it exits
+ * and exits too with proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.EventRequest.ClearAllBreakpoints.clrallbreakp003
+ * nsk.jdwp.EventRequest.ClearAllBreakpoints.clrallbreakp003a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.EventRequest.ClearAllBreakpoints.clrallbreakp003
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/ClearAllBreakpoints/clrallbreakp003a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.EventRequest.ClearAllBreakpoints;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class clrallbreakp003a {
+
+ static final int BREAKPOINT_LINE = 80;
+
+ static ArgumentHandler argumentHandler = null;
+ static Log log = null;
+
+ public static void main(String args[]) {
+ clrallbreakp003a _clrallbreakp003a = new clrallbreakp003a();
+ System.exit(clrallbreakp003.JCK_STATUS_BASE + _clrallbreakp003a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // ensure tested class is loaded
+ log.display("Creating object of tested class");
+ TestedClass object = new TestedClass();
+ log.display(" ... object created");
+
+ // invoke method with breakpoint
+ log.display("Invoking method with breakpoint");
+ object.run();
+ log.display(" ... method invoked");
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return clrallbreakp003.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass {
+ int foo = 0;
+
+ public TestedClass() {
+ foo = 1000;
+ }
+
+ public void run() {
+ log.display("Breakpoint line reached");
+ // next line is for breakpoint
+ foo = 0; // BREAKPOINT_LINE
+ log.display("Breakpoint line passed");
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,509 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.EventRequest.Set;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: EventRequest.Set.
+ *
+ * See set001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class set001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.EventRequest.Set";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "set001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "EventRequest.Set";
+ static final int JDWP_COMMAND_ID = JDWP.Command.EventRequest.Set;
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.BREAKPOINT;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+ static final byte TESTED_EVENT_MODIFIER = JDWP.EventModifierKind.LOCATION_ONLY;
+
+ // name and signature of the tested class
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of field and method of tested class
+ static final String TESTED_METHOD_NAME = "run";
+ static final int BREAKPOINT_LINE = set001a.BREAKPOINT_LINE;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // obtained data
+ long testedClassID = 0;
+ long testedMethodID = 0;
+ int eventRequestID = 0;
+ JDWP.Location breakpointLocation = null;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new set001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // get debuggee prepared for testing
+ log.display("\n>>> Get debuggee prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand();
+
+ if (success) {
+ log.display("\n>>> Checking request result \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for BREAKPOINT event
+ log.display("Waiting for BREAKPOINT event");
+ long threadID = debugee.waitForBreakpointEvent(eventRequestID);
+ log.display(" ... BREAKPOINT event received with threadID: " + threadID);
+ }
+
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debuggee for testing.
+ */
+ void prepareForTest() {
+ // wait for tested class loaded
+ log.display("Waiting for tested class loaded");
+ testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... got classID: " + testedClassID);
+ log.display("");
+
+ // get methodID for breakpoint method
+ log.display("Getting breakpoint methodID by name: " + TESTED_METHOD_NAME);
+ testedMethodID = debugee.getMethodID(testedClassID, TESTED_METHOD_NAME, true);
+ log.display(" ... got methodID: " + testedMethodID);
+
+ // get codeIndex for breakpoint line
+ log.display("Getting code index for breakpoint line: " + BREAKPOINT_LINE);
+ long codeIndex = debugee.getCodeIndex(testedClassID, testedMethodID, BREAKPOINT_LINE);
+ log.display(" ... got breakpoint codeIndex: " + codeIndex);
+
+ // create breakpoint location
+ log.display("Creating location for breakpoint at: "
+ + TESTED_METHOD_NAME + ":" + BREAKPOINT_LINE);
+ breakpointLocation = new JDWP.Location(JDWP.TypeTag.CLASS, testedClassID,
+ testedMethodID, codeIndex);
+ log.display(" ... got breakpoint location: " + breakpointLocation);
+ }
+
+ /**
+ * Test JDWP command.
+ */
+ void testCommand() {
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" event: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" suspendPolicy: " + TESTED_EVENT_SUSPEND_POLICY);
+ command.addByte(TESTED_EVENT_SUSPEND_POLICY);
+ log.display(" modifiers: " + 1);
+ command.addInt(1);
+ log.display(" modKind: " + TESTED_EVENT_MODIFIER);
+ command.addByte(TESTED_EVENT_MODIFIER);
+ log.display(" location: " + breakpointLocation);
+ command.addLocation(breakpointLocation);
+ command.setLength();
+ log.display(" ... command packet created");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // receive reply packet from debugee
+ ReplyPacket reply = new ReplyPacket();
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Wrong header of reply packet for tested command:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet data:");
+ reply.resetPosition();
+
+ // extract requestID
+ int requestID = 0;
+ try {
+ requestID = reply.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract requestID from request reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ }
+
+ // check requestID
+ if (requestID == 0) {
+ log.complain("Unexpected null requestID returned: " + requestID);
+ success = false;
+ }
+ eventRequestID = requestID;
+
+ log.display(" ... packet data is parsed");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+ }
+
+ /**
+ * Wait for VM_DEATH event.
+ */
+ void waitForVMDeathEvent() {
+
+ EventPacket eventPacket = null;
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for event packet");
+ eventPacket = debugee.getEventPacket(timeout);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.complain("Unable to read tested event packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ long eventThreadID = 0;
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check eventKind
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ log.display("Expected VM_DEATH event received intead of BREAKPOINT event");
+ dead = true;
+ return;
+ } else if (eventKind == JDWP.EventKind.BREAKPOINT) {
+ log.complain("Unexpected BREAKPOINT event received in event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.VM_DEATH + ")");
+ success = false;
+ } else {
+ log.complain("Unexpected eventKind of event " + i + " in event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.VM_DEATH + ")");
+ success = false;
+ return;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from BREAKPOINT event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != eventRequestID) {
+ log.complain("Unexpected requestID of event " + i + " in BREAKPOINT event packet: " +
+ requestID + " (expected: " + eventRequestID + ")");
+ success = false;
+ }
+
+ // get threadID
+ long threadID = 0;
+ try {
+ threadID = eventPacket.getObjectID();
+ log.display(" threadID: " + threadID);
+ } catch (BoundException e) {
+ log.complain("Unable to get threadID of event #" + i + " from BREAKPOINT event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // get location
+ JDWP.Location location = null;
+ try {
+ location = eventPacket.getLocation();
+ log.display(" location: " + location);
+ } catch (BoundException e) {
+ log.complain("Unable to get location of event #" + i + " from BREAKPOINT event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event packet parsed");
+ }
+
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee if not dead
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/EventRequest/Set/set001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: EventRequest
+ * command: Set
+ * event kind: BREAKPOINT
+ * Test checks that debuggee accept tested command and replies
+ * with correct reply packet. Also test checks that requested
+ * breakpoint events occurs for created request.
+ * Test consists of two compoments:
+ * debugger: set001
+ * debuggee: set001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded and constructs
+ * location for breakpoint request.
+ * Then, debugger creates command packet for command EventRequest.Set
+ * for this breakpoint location, sends it to debuggee and waits for
+ * reply packet. When reply packed is received, debugger extracts
+ * requestID and checks if it is not null.
+ * Then, debugger resumes debuggee and waits for expected BREAKPOINT
+ * event. If received event is not BREAKPOINT event, debugger
+ * complains an error.
+ * Finally, debugger disconnectes debuggee, waits for it exits
+ * and exits too with proper exit code.
+ * COMMENTS
+ * Test was fixed due to test bug:
+ * 4797978 TEST_BUG: potential race condition in a number of JDWP tests
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.EventRequest.Set.set001
+ * nsk.jdwp.EventRequest.Set.set001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.EventRequest.Set.set001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.EventRequest.Set;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class set001a {
+
+ static final int BREAKPOINT_LINE = 80;
+
+ static ArgumentHandler argumentHandler = null;
+ static Log log = null;
+
+ public static void main(String args[]) {
+ set001a _set001a = new set001a();
+ System.exit(set001.JCK_STATUS_BASE + _set001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // ensure tested class is loaded
+ log.display("Creating object of tested class");
+ TestedClass object = new TestedClass();
+ log.display(" ... object created");
+
+ // invoke method with breakpoint
+ log.display("Invoking method with breakpoint");
+ object.run();
+ log.display(" ... method invoked");
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return set001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass {
+ int foo = 0;
+
+ public TestedClass() {
+ foo = 1000;
+ }
+
+ public void run() {
+ log.display("Breakpoint line reached");
+ // next line is for breakpoint
+ foo = 0; // BREAKPOINT_LINE
+ log.display("Breakpoint line passed");
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set002.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,533 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.EventRequest.Set;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: EventRequest.Set.
+ *
+ * See set002.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #waitForTestedEvent()
+ */
+public class set002 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.EventRequest.Set";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "set002";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "EventRequest.Set";
+ static final int JDWP_COMMAND_ID = JDWP.Command.EventRequest.Set;
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.VM_START;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ int eventRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new set002().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // test JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand();
+
+ log.display("Resumindg debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for tested VM_START or VM_DEATH event
+ log.display("\n>>> Testing JDWP event \n");
+ waitForTestedEvent();
+
+ if (!dead) {
+ // clear tested request for VM_START event
+ log.display("\n>>> Clearing request for tested event \n");
+ clearTestedRequest();
+
+ // finish debuggee after testing
+ log.display("\n>>> Finishing debuggee \n");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for debuggee exited
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ dead = true;
+ log.display(" ... VM_DEATH event received");
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Test JDWP command.
+ */
+ void testCommand() {
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" event: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" suspendPolicy: " + TESTED_EVENT_SUSPEND_POLICY);
+ command.addByte(TESTED_EVENT_SUSPEND_POLICY);
+ log.display(" modifiers: " + 0);
+ command.addInt(0);
+ command.setLength();
+ log.display(" ... command packet created");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // receive reply packet from debugee
+ ReplyPacket reply = new ReplyPacket();
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Wrong header of reply packet for tested command:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet data:");
+ reply.resetPosition();
+
+ {
+ // extract requestID
+ try {
+ eventRequestID = reply.getInt();
+ log.display(" requestID: " + eventRequestID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract requestID from request reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ }
+
+ // check requestID
+ if (eventRequestID == 0) {
+ log.complain("Unexpected null requestID returned: " + eventRequestID);
+ success = false;
+ }
+
+ log.display(" ... packet data is parsed");
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+ }
+
+ /**
+ * Clear request for tested VM_START event.
+ */
+ void clearTestedRequest() {
+ Failure failure = new Failure("Error occured while clearing request for tested event");
+
+ // create command packet and fill requred out data
+ log.display("Create command packet: " + "EventRequest.Clear");
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear);
+ log.display(" event: " + TESTED_EVENT_KIND);
+ command.addByte(TESTED_EVENT_KIND);
+ log.display(" requestID: " + eventRequestID);
+ command.addInt(eventRequestID);
+ log.display(" ... command packet composed");
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ log.display(" ... command packet sent");
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ throw failure;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" .. packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ throw failure;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ log.display(" no data");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... reply packet parsed");
+ }
+
+ /**
+ * Wait for tested CLASS_UNLOAD event.
+ */
+ void waitForTestedEvent() {
+
+ EventPacket eventPacket = null;
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for event packet (for " + timeout + "ms timeout)");
+ eventPacket = debugee.getEventPacket(timeout);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.complain("Unable to read tested event packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in tested event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check if VM_DEATH event
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ log.display("Got VM_DEATH event while waiting for tested event");
+ dead = true;
+ log.display("No VM_START event occured so treat test as PASSED");
+ return;
+ }
+
+ // check eventKind
+ if (eventKind != JDWP.EventKind.VM_START) {
+ log.complain("Unexpected eventKind of event " + i + " in tested event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.VM_DEATH + ")");
+ success = false;
+ return;
+ }
+
+ if (eventKind == JDWP.EventKind.VM_START) {
+ log.complain("Unexpected VM_START event " + i + " in tested event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.VM_DEATH + ")");
+ success = false;
+ return;
+ }
+ // check suspendPolicy value
+ if (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY) {
+ log.complain("Unexpected SuspendPolicy in tested event packet: " +
+ suspendPolicy + " (expected: " + TESTED_EVENT_SUSPEND_POLICY + ")");
+ success = false;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != eventRequestID) {
+ log.complain("Unexpected requestID of event " + i + " in tested event packet: " +
+ requestID + " (expected: " + eventRequestID + ")");
+ success = false;
+ }
+
+ // get threadID
+ long threadID = 0;
+ try {
+ threadID = eventPacket.getObjectID();
+ log.display(" threadID: " + threadID);
+ } catch (BoundException e) {
+ log.complain("Unable to get threadID of event #" + i + " from tested event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check threadID
+ if (threadID == 0) {
+ log.complain("Unexpected threadID of event " + i + " in tested event packet: " +
+ requestID + " (expected: not 0)");
+ success = false;
+ }
+
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event packet parsed");
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee if not dead
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set002/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/EventRequest/Set/set002.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: EventRequest
+ * command: Set
+ * event kind: VM_START
+ * Test checks that debuggee accepts tested command and replies
+ * with no error code for VM_START event request. The tests also
+ * checks that requested VM_START event is never received after
+ * initial automatically generated VM_START event.
+ * Test consists of two compoments:
+ * debugger: set002
+ * debuggee: set002a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Then, debugger creates creates command packet for command
+ * EventRequest.Set with VM_START event and no event modifiers;
+ * and sends it to debuggee. After reply packet is received
+ * debuggeer checks if it has no errors and valid requestID.
+ * Then, debugger lets debuggee to run and exit and waits for any event
+ * is received. If VM_START event is received, then debugger complains
+ * error and removes event request. Otherwise, if event is VM_DEATH
+ * the test passes.
+ * Finally, debugger disconnectes debuggee, waits for it exits
+ * and exits too with proper exit code.
+ * COMMENTS
+ * Test fixed due to test bug:
+ * 4909273 TEST_BUG: Fix nsk/jdwp/EventRequest/Set/set002
+ * Test fixed due to test bug:
+ * 4973741 nsk/jdwp/EventRequest/Set/set002 expects request for VMStart event to fail
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.EventRequest.Set.set002
+ * nsk.jdwp.EventRequest.Set.set002a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.EventRequest.Set.set002
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/EventRequest/Set/set002a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.EventRequest.Set;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class set002a {
+
+ static ArgumentHandler argumentHandler = null;
+ static Log log = null;
+
+ public static void main(String args[]) {
+ set002a _set002a = new set002a();
+ System.exit(set002.JCK_STATUS_BASE + _set002a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return set002.PASSED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/Bytecodes/bytecodes001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Method.Bytecodes;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: Method.Bytecodes.
+ *
+ * See bytecodes001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class bytecodes001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Method.Bytecodes";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "bytecodes001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // VM capability constatnts
+ static final int VM_CAPABILITY_NUMBER = JDWP.Capability.CAN_GET_BYTECODES;
+ static final String VM_CAPABILITY_NAME = "canGetBytecodes";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "Method.Bytecodes";
+ static final int JDWP_COMMAND_ID = JDWP.Command.Method.Bytecodes;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // tested method name constant
+ static final String TESTED_METHOD_NAME = "testedMethod";
+
+ // expected values for bound line numbers
+ static final int FIRST_LINE_NUMBER = bytecodes001a.FIRST_LINE_NUMBER;
+ static final int LAST_LINE_NUMBER = bytecodes001a.LAST_LINE_NUMBER;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new bytecodes001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ try {
+ log.display("\n>>> Checking VM capability \n");
+
+ // check for VM capability
+ log.display("Checking VM capability: " + VM_CAPABILITY_NAME);
+ if (!debugee.getCapability(VM_CAPABILITY_NUMBER, VM_CAPABILITY_NAME)) {
+ out.println("TEST PASSED: unsupported VM capability: "
+ + VM_CAPABILITY_NAME);
+ return PASSED;
+ }
+
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for methodID of tested method (declared in the class)
+ log.display("Getting methodID by name: " + TESTED_METHOD_NAME);
+ long methodID = debugee.getMethodID(classID, TESTED_METHOD_NAME, true);
+ log.display(" got methodID: " + methodID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(classID, methodID);
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Perform testing JDWP command for specified TypeID.
+ */
+ void testCommand(long classID, long methodID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" referenceTypeID: " + classID);
+ command.addReferenceTypeID(classID);
+ log.display(" methodID: " + methodID);
+ command.addMethodID(methodID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract and check reply data
+
+ // extract number of lines
+ int bytes = 0;
+ try {
+ bytes = reply.getInt();
+ log.display(" bytes: " + bytes);
+ } catch (BoundException e) {
+ log.complain("Unable to extract number of bytes from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ if (bytes < 0) {
+ log.complain("Negative number of bytes in reply packet: " + bytes);
+ success = false;
+ return;
+ }
+
+ if (bytes == 0) {
+ log.complain("Zero number of bytes in reply packet: " + bytes);
+ success = false;
+ return;
+ }
+
+ // extract all bytes
+ ByteBuffer bytecode = new ByteBuffer();
+ for (int i = 0; i < bytes; i++) {
+ // extract next byte of bytecode
+ try {
+ byte aByte = reply.getByte();
+ bytecode.addByte(aByte);
+ } catch (BoundException e) {
+ log.complain("Unable to extract byte #" + i
+ + " from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+ }
+
+ log.display(" bytecode:\n" + bytecode);
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/Bytecodes/bytecodes001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Method/Bytecodes/bytecodes001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Method
+ * command: Bytecodes
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: bytecodes001
+ * debuggee: bytecodes001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains classID and methodID for the tested class
+ * and method from debuggee.
+ * Then, debugger creates command packet for Method.Bytecodes command
+ * with the found classID and methodID as arguments, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts all bytes of bytecode for requested method.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Method.Bytecodes.bytecodes001
+ * nsk.jdwp.Method.Bytecodes.bytecodes001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Method.Bytecodes.bytecodes001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/Bytecodes/bytecodes001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Method.Bytecodes;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class bytecodes001a {
+
+ public static final int FIRST_LINE_NUMBER = 65;
+ public static final int LAST_LINE_NUMBER = 76;
+
+ public static void main(String args[]) {
+ bytecodes001a _bytecodes001a = new bytecodes001a();
+ System.exit(bytecodes001.JCK_STATUS_BASE + _bytecodes001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // ensure tested class loaded
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + bytecodes001.READY);
+ pipe.println(bytecodes001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + bytecodes001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (! signal.equals(bytecodes001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + bytecodes001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return bytecodes001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return bytecodes001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass {
+ int foo = 0;
+
+ public void testedMethod() {
+ foo = 1; // foo == 1
+ foo++; // foo == 2
+ foo++; // foo == 3
+ foo++; // foo == 4
+ foo++; // foo == 5
+ foo++; // foo == 6
+ foo++; // foo == 7
+ foo++; // foo == 8
+ foo++; // foo == 9
+ foo++; // foo == 10
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Method.IsObsolete;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: Method.IsObsolete.
+ *
+ * See isobsolete001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class isobsolete001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Method.IsObsolete";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "isobsolete001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // VM capability constatnts
+ static final int VM_CAPABILITY_NUMBER = JDWP.Capability.CAN_REDEFINE_CLASSES;
+ static final String VM_CAPABILITY_NAME = "canRedefineClasses";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "Method.IsObsolete";
+ static final int JDWP_COMMAND_ID = JDWP.Command.Method.IsObsolete;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // tested method name constant
+ static final String TESTED_METHOD_NAME = "testedMethod";
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new isobsolete001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ try {
+ log.display("\n>>> Checking VM capability \n");
+
+ // check for VM capability
+ log.display("Checking VM capability: " + VM_CAPABILITY_NAME);
+ if (!debugee.getNewCapability(VM_CAPABILITY_NUMBER, VM_CAPABILITY_NAME)) {
+ out.println("TEST PASSED: unsupported VM capability: "
+ + VM_CAPABILITY_NAME);
+ return PASSED;
+ }
+
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for methodID of tested method (declared in the class)
+ log.display("Getting methodID by name: " + TESTED_METHOD_NAME);
+ long methodID = debugee.getMethodID(classID, TESTED_METHOD_NAME, true);
+ log.display(" got methodID: " + methodID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(classID, methodID);
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Perform testing JDWP command for specified TypeID.
+ */
+ void testCommand(long classID, long methodID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" referenceTypeID: " + classID);
+ command.addReferenceTypeID(classID);
+ log.display(" methodID: " + methodID);
+ command.addMethodID(methodID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract boolean result
+ byte isObsolete = 0;
+ try {
+ isObsolete = reply.getByte();
+ log.display(" isObsolete: " + isObsolete);
+ } catch (BoundException e) {
+ log.complain("Unable to extract isObsolete value from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ // check that result value is false
+ if (isObsolete != 0) {
+ log.complain("Unexpected true isObsolete value received for not obsolete method: "
+ + isObsolete);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Method/IsObsolete/isobsolete001.
+ * VM Testbase keywords: [quick, jpda, jdwp, redefine]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Method
+ * command: IsObsolete
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * return value is false, because method of not redefined class
+ * is not obsolete.
+ * Test consists of two compoments:
+ * debugger: isobsolete001
+ * debuggee: isobsolete001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains classID and methodID for the tested class
+ * and method from debuggee.
+ * Then, debugger creates command packet for Method.IsObsolete command
+ * with the found classID and methodID as arguments, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts boolean isObsolete value. Also test checks that extracted
+ * value is false.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Method.IsObsolete.isobsolete001
+ * nsk.jdwp.Method.IsObsolete.isobsolete001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Method.IsObsolete.isobsolete001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Method.IsObsolete;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class isobsolete001a {
+
+ public static void main(String args[]) {
+ isobsolete001a _isobsolete001a = new isobsolete001a();
+ System.exit(isobsolete001.JCK_STATUS_BASE + _isobsolete001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // ensure tested class loaded
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + isobsolete001.READY);
+ pipe.println(isobsolete001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + isobsolete001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (! signal.equals(isobsolete001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + isobsolete001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return isobsolete001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return isobsolete001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass {
+ int foo = 0;
+
+ public void testedMethod() {
+ foo = 1;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete002.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,490 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Method.IsObsolete;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: Method.IsObsolete.
+ *
+ * See isobsolete002.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class isobsolete002 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // VM capability constatnts
+ static final int VM_CAPABILITY_NUMBER = JDWP.Capability.CAN_REDEFINE_CLASSES;
+ static final String VM_CAPABILITY_NAME = "canRedefineClasses";
+
+ // package and classes names
+ static final String PACKAGE_NAME = "nsk.jdwp.Method.IsObsolete";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "isobsolete002";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command
+ static final String JDWP_COMMAND_NAME = "Method.IsObsolete";
+ static final int JDWP_COMMAND_ID = JDWP.Command.Method.IsObsolete;
+
+ // tested class name and signature
+ static final String TESTED_CLASS_NAME = TEST_CLASS_NAME + "b";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // tested method name
+ static final String TESTED_METHOD_NAME = "testedMethod";
+ static final int BREAKPOINT_LINE = isobsolete002a.BREAKPOINT_LINE;
+
+ // filename for redefined class
+// 4691123 TEST: some jdi tests contain precompiled .klass files undes SCCS
+// precomiled class was removed
+// static final String REDEFINED_CLASS_FILE_NAME = "isobsolete002b.klass";
+ static final String REDEFINED_CLASS_FILE_NAME = "newclass"
+ + File.separator + PACKAGE_NAME.replace('.',File.separatorChar)
+ + File.separator + "isobsolete002b.class";
+// + File.separator + "isobsolete002b.klass";
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ String testDir = null;
+ boolean dead = false;
+ boolean success = true;
+
+ // data obtained from debuggee
+ long testedClassID = 0;
+ long testedMethodID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new isobsolete002().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime(); // minutes
+ timeout = waitTime * 60 * 1000; // milliseconds
+
+ // get testDir as first positional parameter
+ String args[] = argumentHandler.getArguments();
+ if (args.length < 1) {
+ log.complain("Test dir required as the first positional argument");
+ return FAILED;
+ }
+ testDir = args[0];
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Loading redefined class \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee VM");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debuggee launched");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for VM_INIT event
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // check for VM capability
+ log.display("\n>>> Checking VM capability \n");
+ log.display("Getting new VM capability: " + VM_CAPABILITY_NAME);
+ boolean capable = debugee.getNewCapability(VM_CAPABILITY_NUMBER, VM_CAPABILITY_NAME);
+ log.display(" ... got VM capability: " + capable);
+
+ // exit as PASSED if this capability is not supported
+ if (!capable) {
+ out.println("TEST PASSED: unsupported VM capability: "
+ + VM_CAPABILITY_NAME);
+ return PASSED;
+ }
+
+ // prepare debuggee for testing and obtain required data
+ log.display("\n>>> Getting prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(testedMethodID, TESTED_METHOD_NAME);
+
+ // finish debuggee
+ log.display("\n>> Finishing debuggee \n");
+
+ // resume debuggee after testing command
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for VM_DEATH event
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ log.display(" ... VM_DEATH event received");
+ dead = true;
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ log.display("\n>>> Finishing test \n");
+
+ // disconnect debugee and wait for its exit
+ if (debugee != null) {
+ quitDebugee();
+ }
+ }
+
+ // check result
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+ out.println("TEST PASSED");
+ return PASSED;
+ }
+
+ /**
+ * Get debuggee prepared for testing and obtain required data.
+ */
+ void prepareForTest() {
+ // wait for debuggee and tested classes loaded on debuggee startup
+ log.display("Waiting for classes loaded:"
+ + "\n\t" + TESTED_CLASS_NAME);
+ testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... class loaded with classID: " + testedClassID);
+ log.display("");
+
+/*
+ // get tested methodID by names
+ log.display("Getting methodID for method name :" + TESTED_METHOD_NAME);
+ testedMethodID = debugee.getMethodID(testedClassID, TESTED_METHOD_NAME, true);
+ log.display(" ... got methodID: " + testedMethodID);
+ log.display("");
+*/
+
+ // wait for breakpoint reached
+ log.display("Waiting for breakpoint reached at: "
+ + TESTED_METHOD_NAME + ":" + BREAKPOINT_LINE);
+ long threadID = debugee.waitForBreakpointReached(testedClassID,
+ TESTED_METHOD_NAME,
+ BREAKPOINT_LINE,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... breakpoint reached with threadID: " + threadID);
+ log.display("");
+
+ // load class file for redefined class
+ log.display("Loading bytecode of redefined class from file: " +
+ REDEFINED_CLASS_FILE_NAME);
+ byte[] classBytes = loadClassBytes(REDEFINED_CLASS_FILE_NAME, testDir);
+ log.display(" ... loaded bytes: " + classBytes.length);
+
+ // redefine class
+ log.display("Redefine class by classID: " + testedClassID);
+ redefineClass(testedClassID, classBytes);
+ log.display(" ... class redefined");
+ log.display("");
+
+ // get top frameID of the thread
+ log.display("Getting top frameID of the threadID: " + threadID);
+ JDWP.Location location = queryTopFrameLocation(threadID);
+ log.display(" ... got location: " + location);
+
+ // get methodID of the top frameID
+ log.display("Getting methodID for the location :" + location);
+ testedMethodID = location.getMethodID();
+ log.display(" ... got methodID: " + testedMethodID);
+ log.display("");
+
+ }
+
+ /**
+ * Perform testing JDWP command for given methodID.
+ */
+ void testCommand(long testedMethodID, String methodName) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" refTypeID: " + testedClassID);
+ command.addReferenceTypeID(testedClassID);
+ log.display(" methodID: " + testedMethodID);
+ command.addMethodID(testedMethodID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet for method " + methodName + ":\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // receive reply packet from debugee
+ ReplyPacket reply = new ReplyPacket();
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet for method " + methodName + ":\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Wrong header of reply packet for method " + methodName + ":\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet data:");
+ reply.resetPosition();
+
+ // extract boolean isObsolete
+ byte isObsolete = 0;
+ try {
+ isObsolete = reply.getByte();
+ log.display(" isObsolete: " + isObsolete);
+ } catch (BoundException e) {
+ log.complain("Unable to extract isObsolete value from reply packet for method "
+ + methodName + ":\n\t" + e.getMessage());
+ success = false;
+ }
+
+ // check isObsolete
+ if (isObsolete == 0) {
+ log.complain("Unexpected isObsolete value for method "
+ + methodName + ": " + isObsolete + " (expected: not " + 0 + ")");
+ success = false;
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes in reply packet for "
+ + methodName + " method at: " + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... packed data parsed");
+ }
+
+ /**
+ * Redefine class bytes for given classID.
+ */
+ void redefineClass(long classID, byte[] classBytes) {
+ int length = classBytes.length;
+
+ CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.RedefineClasses);
+ command.addInt(1);
+ command.addReferenceTypeID(classID);
+ command.addInt(length);
+ command.addBytes(classBytes, 0, length);
+
+ // receive reply packet from debugee
+ ReplyPacket reply = debugee.receiveReplyFor(command, "VirtualMachine.RedefineClasses");
+ }
+
+ /**
+ * Query debuggee VM for top frameID of the thread.
+ */
+ JDWP.Location queryTopFrameLocation(long threadID) {
+ String error = "Error occured while getting top frameID for threadID: " + threadID;
+
+ CommandPacket command = new CommandPacket(JDWP.Command.ThreadReference.Frames);
+ command.addObjectID(threadID);
+ command.addInt(0);
+ command.addInt(1);
+ command.setLength();
+
+ ReplyPacket reply = debugee.receiveReplyFor(command, "ThreadReference.Frames");
+ reply.resetPosition();
+
+ // extract number of frames
+ int frames = 0;
+ try {
+ frames = reply.getInt();
+ } catch (BoundException e) {
+ log.complain("Unable to extract number of frames from reply packet:\n\t"
+ + e.getMessage());
+ throw new Failure(error);
+ }
+
+ // check frames count
+ if (frames != 1) {
+ log.complain("Unexpected number of frames returned: "
+ + frames + " (expected: " + 1 + ")");
+ throw new Failure(error);
+ }
+
+ // extract frame ID
+ long frameID = 0;
+ try {
+ frameID = reply.getFrameID();
+ } catch (BoundException e) {
+ log.complain("Unable to extract top frameID from reply packet:\n\t"
+ + e.getMessage());
+ throw new Failure(error);
+ }
+
+ // extract frame location
+ JDWP.Location location = null;
+ try {
+ location = reply.getLocation();
+ } catch (BoundException e) {
+ log.complain("Unable to extract location for top frame from reply packet:\n\t"
+ + e.getMessage());
+ throw new Failure(error);
+ }
+
+ return location;
+ }
+
+
+ /**
+ * Load class bytes form the given file.
+ */
+ byte[] loadClassBytes(String fileName, String dirName) {
+ String fileSep = System.getProperty("file.separator");
+ String filePath = dirName + fileSep + fileName;
+
+ String error = "Unable to read bytes from class file:\n\t" + filePath;
+
+ int length = 0;
+ byte bytes[] = null;
+ try {
+ File file = new File(filePath);
+ length = (int)file.length();
+ FileInputStream is = new FileInputStream(file);
+ bytes = new byte[length];
+ int number = is.read(bytes);
+ if (number < 0) {
+ log.complain("EOF reached while reading bytes from file");
+ throw new Failure(error);
+ } else if (number != length) {
+ log.complain("Unexpected number of bytes red from file: " + number
+ + " (expected: " + length + ")");
+ throw new Failure(error);
+ }
+ is.close();
+ } catch ( IOException e ) {
+ log.complain("Caught IOException while reading bytes from file:\n\t" + e);
+ throw new Failure(error);
+ }
+ return bytes;
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete002/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Method/IsObsolete/isobsolete002.
+ * VM Testbase keywords: [quick, jpda, jdwp, redefine]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Method
+ * command: IsObsolete
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet after class redefinition
+ * for redefined method being at that time with active stack
+ * frame.
+ * Test consists of two compoments:
+ * debugger: isobsolete002
+ * debuggee: isobsolete002a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * It waits for tested class is loaded, sets breakpoint on the tested
+ * method, and waits for breakpoint is reached.
+ * Then, it loads bytecode of redefined class from *.klass file and
+ * redefines the class. After class redefinition, debugger queries
+ * debiggi for the methodID of to level stack frame and checks this
+ * method.
+ * Debugger creates command packet with Method.IsObsolete command for
+ * the tested method, writes this packet to the transport channel,
+ * and waits for a reply packet. When reply packet is received,
+ * debugger parses the packet structure and checks if expected
+ * isObsolete value returned in the packet.
+ * Finally, debugger disconnects debuggee, waits for it exits
+ * and exits too with the proper exit code.
+ * COMMENTS
+ * First positional argument for the test should be path to the test
+ * work directory where loaded *.klass file should be located.
+ * Test was fixed due to test bug:
+ * 4514956 Method.isObsolete() returns false for redefined method
+ * Test was updated according to rfe:
+ * 4691123 TEST: some jdi tests contain precompiled .klass files undes SCCS.
+ * isobsolete002b.ja was moved into newclass directory and renamed
+ * to isobsolete002b.java.
+ * The precompiled class file is created during test base build process.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build ExecDriver
+ * @build nsk.jdwp.Method.IsObsolete.isobsolete002
+ * nsk.jdwp.Method.IsObsolete.isobsolete002a
+ * nsk.jdwp.Method.IsObsolete.isobsolete002b
+ * @run driver PropertyResolvingWrapper ExecDriver --cmd
+ * ${compile.jdk}/bin/javac
+ * -cp ${test.class.path}
+ * -d newclass
+ * newclass/isobsolete002b.java
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Method.IsObsolete.isobsolete002
+ * .
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete002/newclass/isobsolete002b.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2002, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.Method.IsObsolete;
+
+import nsk.share.*;
+
+/**
+ * This class is for redefinition.
+ */
+public class isobsolete002b {
+
+ // static field
+ public static int staticField = 0;
+ // object field
+ public int objectField = 0;
+
+ public static Log log;
+
+ // method to be redefined
+ public void testedMethod(int arg) {
+ log.display("Object method invoked: REDEFINED and MODIFIED"); // isobsolete002a.BREAKPOINT_LINE
+ objectField = arg;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete002a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Method.IsObsolete;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class isobsolete002a {
+
+ // scaffold objects
+ static volatile ArgumentHandler argumentHandler = null;
+ static volatile Log log = null;
+
+ // breakpoint line in isobsolete002b
+ static final int BREAKPOINT_LINE = 44;
+
+ public static void main(String args[]) {
+ System.exit(isobsolete002.JCK_STATUS_BASE + isobsolete002a.runIt(args, System.err));
+ }
+
+ public static int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // create tested thread
+ log.display("Creating object of tested class");
+ isobsolete002b.log = log;
+ isobsolete002b object = new isobsolete002b();
+ log.display(" ... object created");
+
+ log.display("Invoking tested method before class redefinition");
+ object.testedMethod(100);
+ log.display(" ... tested method invoked");
+
+ log.display("Invoking tested method after class redefinition");
+ object.testedMethod(100);
+ log.display(" ... tested method invoked");
+
+ // exit
+ log.display("Debugee PASSED");
+ return isobsolete002.PASSED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete002b.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.Method.IsObsolete;
+
+import nsk.share.*;
+
+/**
+ * This class is to be redefined.
+ */
+public class isobsolete002b {
+
+ // static field
+ public static int staticField = 0;
+ // object field
+ public int objectField = 0;
+
+ public static Log log;
+
+ // tested method to be redefined
+ public void testedMethod(int arg) {
+ int value = arg; // isobsolete002a.BREAKPOINT_LINE
+ log.display("Object method invoked: NOT_REDEFINED");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/LineTable/linetable001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Method.LineTable;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: Method.LineTable.
+ *
+ * See linetable001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class linetable001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Method.LineTable";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "linetable001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "Method.LineTable";
+ static final int JDWP_COMMAND_ID = JDWP.Command.Method.LineTable;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // tested method name constant
+ static final String TESTED_METHOD_NAME = "testedMethod";
+
+ // expected values for bound line numbers
+ static final int FIRST_LINE_NUMBER = linetable001a.FIRST_LINE_NUMBER;
+ static final int LAST_LINE_NUMBER = linetable001a.LAST_LINE_NUMBER;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new linetable001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for methodID of tested method (declared in the class)
+ log.display("Getting methodID by name: " + TESTED_METHOD_NAME);
+ long methodID = debugee.getMethodID(classID, TESTED_METHOD_NAME, true);
+ log.display(" got methodID: " + methodID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(classID, methodID);
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Perform testing JDWP command for specified TypeID.
+ */
+ void testCommand(long classID, long methodID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" referenceTypeID: " + classID);
+ command.addReferenceTypeID(classID);
+ log.display(" methodID: " + methodID);
+ command.addMethodID(methodID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract and check reply data
+
+ // extract start code index
+ long start = 0;
+ try {
+ start = reply.getLong();
+ log.display(" start: " + start);
+ } catch (BoundException e) {
+ log.complain("Unable to extract start line index from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that start code index is not negative
+ if (start < 0) {
+ log.complain("Negative value of start code index in reply packet: " + start);
+ success = false;
+ }
+
+ // extract end code index
+ long end = 0;
+ try {
+ end = reply.getLong();
+ log.display(" end: " + end);
+ } catch (BoundException e) {
+ log.complain("Unable to extract end line index from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that end code index is not negative
+ if (start < 0) {
+ log.complain("Negative value of end code index in reply packet: " + end);
+ success = false;
+ }
+
+ // check that start code is strongly less than end code index
+ if (start > end) {
+ log.complain("Start code index (" + start
+ + ") is greater than end code index (" + end + ")");
+ success = false;
+ } else if (start == end) {
+ log.complain("Start code index (" + start
+ + ") is equal to end code index (" + end + ")");
+ success = false;
+ }
+
+ // extract number of lines
+ int lines = 0;
+ try {
+ lines = reply.getInt();
+ log.display(" lines: " + lines);
+ } catch (BoundException e) {
+ log.complain("Unable to extract number of lines from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ if (lines < 0) {
+ log.complain("Negative number of lines in reply packet: " + lines);
+ success = false;
+ return;
+ }
+
+ if (lines == 0) {
+ log.complain("Zero number of lines in reply packet: " + lines);
+ success = false;
+ return;
+ }
+
+ // extract and check each line attributes
+ long lineCodeIndex = 0, prevLineCodeIndex = 0;
+ int lineNumber = 0, prevLineNumber = 0;
+
+ for (int i = 0; i < lines; i++) {
+ log.display(" line #" + i + ":");
+
+ // extract code index of a line
+ try {
+ lineCodeIndex = reply.getLong();
+ log.display(" lineCodeIndex: " + lineCodeIndex);
+ } catch (BoundException e) {
+ log.complain("Unable to extract code index of line #" + i
+ + " from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that code index is between start and end values
+ if (lineCodeIndex < start) {
+ log.complain("Code index of line #" + i + " (" + lineCodeIndex
+ + ") is less than start code index (" + start + ")");
+ success = false;
+ }
+
+ if (lineCodeIndex > end) {
+ log.complain("Code index of line #" + i + " (" + lineCodeIndex
+ + ") is greater than end code index (" + end + ")");
+ success = false;
+ }
+
+ // check that code index ot the first line is equal to start value
+ if (i == 0) {
+ if (lineCodeIndex != start) {
+ log.complain("Code index of first line (" + lineCodeIndex
+ + ") is not equal to start code index (" + start + ")");
+ success = false;
+ }
+ }
+
+ // check that code index of a line is strongly greater than for previous line
+ if (i > 0) {
+ if (lineCodeIndex < prevLineCodeIndex) {
+ log.complain("Code index of line #" + i + " (" + lineCodeIndex
+ + ") is less than code index of previous line ("
+ + prevLineCodeIndex + ")");
+ success = false;
+ } else if (lineCodeIndex == prevLineCodeIndex) {
+ log.complain("Code index of line #" + i + " (" + lineCodeIndex
+ + ") is equal to code index of previous line ("
+ + prevLineCodeIndex + ")");
+ success = false;
+ }
+ }
+
+ // extract number of a line
+ try {
+ lineNumber = reply.getInt();
+ log.display(" lineNumber: " + lineNumber);
+ } catch (BoundException e) {
+ log.complain("Unable to extract number of line #" + i
+ + " from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that code index ot the line is not negative
+ if (lineNumber < 0) {
+ log.complain("Number of line #" + i + " (" + lineNumber
+ + ") is negative");
+ success = false;
+ }
+
+ // check that code index ot the line is not less than expected
+ if (lineNumber < FIRST_LINE_NUMBER) {
+ log.complain("Number of line #" + i + " (" + lineNumber
+ + ") is less than expected (" + FIRST_LINE_NUMBER + ")");
+ success = false;
+ }
+
+ // check that code index ot the line is not greater than expected
+ if (lineNumber > LAST_LINE_NUMBER) {
+ log.complain("Number of line #" + i + " (" + lineNumber
+ + ") is greater than expected (" + LAST_LINE_NUMBER + ")");
+ success = false;
+ }
+
+ // check that line number follows directly to the number of previous line
+ if (i > 0) {
+ if (lineNumber < prevLineNumber) {
+ log.complain("Number of line #" + i + " (" + lineCodeIndex
+ + ") is less than number of previous line ("
+ + prevLineNumber + ")");
+ success = false;
+ } else if (lineNumber == prevLineNumber) {
+ log.complain("Number of line #" + i + " (" + lineCodeIndex
+ + ") is equal to number of previous line ("
+ + prevLineNumber + ")");
+ success = false;
+ } else if (lineNumber != prevLineNumber + 1) {
+ log.complain("Number of line #" + i + " (" + lineCodeIndex
+ + ") does not follows to number of previous line ("
+ + prevLineNumber + ")");
+ success = false;
+ }
+ }
+
+ // save values to use them as previous line attributes
+ prevLineCodeIndex = lineCodeIndex;
+ prevLineNumber = lineNumber;
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/LineTable/linetable001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Method/LineTable/linetable001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Method
+ * command: LineTable
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Also test checks that code index and number for returned lines
+ * have expected values, namely:
+ * 1) start code index is strongly less than
+ * end code index
+ * and for each line:
+ * 2) line code index is between start and end code index
+ * 3) line code index for previous line is strongly less
+ * then for next line
+ * 4) line number is between start and end line number
+ * 5) line number for previous line is no greater
+ * then for next line
+ * 6) number of next line follows directly to the number
+ * of previous line
+ * Test consists of two compoments:
+ * debugger: linetable001
+ * debuggee: linetable001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains classID and methodID for the tested class
+ * and method from debuggee.
+ * Then, debugger creates command packet for Method.LineTable command
+ * with the found classID and methodID as arguments, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts code index and number for each lines. Also test
+ * checks above mentioned assertions.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Method.LineTable.linetable001
+ * nsk.jdwp.Method.LineTable.linetable001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Method.LineTable.linetable001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/LineTable/linetable001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.Method.LineTable;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class linetable001a {
+
+ public static final int FIRST_LINE_NUMBER = 86;
+ public static final int LAST_LINE_NUMBER = 97;
+
+ public static void main(String args[]) {
+ linetable001a _linetable001a = new linetable001a();
+ System.exit(linetable001.JCK_STATUS_BASE + _linetable001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // ensure tested class loaded
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + linetable001.READY);
+ pipe.println(linetable001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + linetable001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (! signal.equals(linetable001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + linetable001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return linetable001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return linetable001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass {
+ int foo = 0;
+
+ public void testedMethod() { // FIRST_LINE_NUMBER
+ foo = 1; // foo == 1
+ foo++; // foo == 2
+ foo++; // foo == 3
+ foo++; // foo == 4
+ foo++; // foo == 5
+ foo++; // foo == 6
+ foo++; // foo == 7
+ foo++; // foo == 8
+ foo++; // foo == 9
+ foo++; // foo == 10
+ } // LAST_LINE_NUMBER
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTable/vartable001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,489 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Method.VariableTable;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: Method.VariableTable.
+ *
+ * See vartable001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class vartable001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Method.VariableTable";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "vartable001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "Method.VariableTable";
+ static final int JDWP_COMMAND_ID = JDWP.Command.Method.VariableTable;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // tested types signature conatants
+ static final String OBJECT_CLASS_SIGNATURE = "Ljava/lang/Object;";
+ static final String STRING_CLASS_SIGNATURE = "Ljava/lang/String;";
+
+
+ // tested method name constant
+ static final String TESTED_METHOD_NAME = "testedMethod";
+
+ // list of tested variables names and signatures
+ static final String variablesList[][] = {
+ // synthetic method arguments
+ {"this", TESTED_CLASS_SIGNATURE},
+ // method arguments
+ {"booleanArgument", "Z"},
+ {"byteArgument", "B"},
+ {"charArgument", "C"},
+ {"shortArgument", "S"},
+ {"intArgument", "I"},
+ {"longArgument", "J"},
+ {"floatArgument", "F"},
+ {"doubleArgument", "D"},
+ {"objectArgument", OBJECT_CLASS_SIGNATURE},
+ {"stringArgument", STRING_CLASS_SIGNATURE},
+ // local variables
+ {"booleanLocal", "Z"},
+ {"byteLocal", "B"},
+ {"charLocal", "C"},
+ {"shortLocal", "S"},
+ {"intLocal", "I"},
+ {"longLocal", "J"},
+ {"floatLocal", "F"},
+ {"doubleLocal", "D"},
+ {"objectLocal", OBJECT_CLASS_SIGNATURE},
+ {"stringLocal", STRING_CLASS_SIGNATURE}
+ };
+ static final int variablesCount = variablesList.length;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new vartable001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for methodID of tested method (declared in the class)
+ log.display("Getting methodID by name: " + TESTED_METHOD_NAME);
+ long methodID = debugee.getMethodID(classID, TESTED_METHOD_NAME, true);
+ log.display(" got methodID: " + methodID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(classID, methodID);
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Perform testing JDWP command for specified TypeID.
+ */
+ void testCommand(long classID, long methodID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" referenceTypeID: " + classID);
+ command.addReferenceTypeID(classID);
+ log.display(" methodID: " + methodID);
+ command.addMethodID(methodID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // clear list of found variables
+ int[] foundVariablesList = new int[variablesCount];
+ for (int i = 0; i < variablesCount; i++) {
+ foundVariablesList[i] = 0;
+ }
+
+ // extract and check reply data
+
+ // extract number of argumnets
+ int argCount = 0;
+ try {
+ argCount = reply.getInt();
+ log.display(" argCount: " + argCount);
+ } catch (BoundException e) {
+ log.complain("Unable to extract number of arguments from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that number of arguments is not negative
+ if (argCount < 0) {
+ log.complain("Negative of arguments in reply packet: " + argCount);
+ success = false;
+ }
+
+ // extract number of slots
+ int slots = 0;
+ try {
+ slots = reply.getInt();
+ log.display(" slots: " + slots);
+ } catch (BoundException e) {
+ log.complain("Unable to extract number of slots from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that number of slots is not negative
+ if (slots < 0) {
+ log.complain("Negative value of end code index in reply packet: " + slots);
+ success = false;
+ }
+
+ // check that start code is not less than expected
+ if (slots < variablesCount) {
+ log.complain("Number of slots (" + slots
+ + ") is less than expected (" + variablesCount + ")");
+ success = false;
+ }
+
+ // extract and check each slot attributes
+ for (int i = 0; i < slots; i++) {
+ log.display(" slot #" + i + ":");
+
+ // extract code index of a slot
+ long codeIndex = 0;
+ try {
+ codeIndex = reply.getLong();
+ log.display(" codeIndex: " + codeIndex);
+ } catch (BoundException e) {
+ log.complain("Unable to extract code index of slot #" + i
+ + " from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that code index is not negative
+ if (codeIndex < 0) {
+ log.complain("Negative code index of slot #" + i + ":" + codeIndex);
+ success = false;
+ }
+
+ // extract name of a slot
+ String name = null;
+ try {
+ name = reply.getString();
+ log.display(" name: " + name);
+ } catch (BoundException e) {
+ log.complain("Unable to extract name of slot #" + i
+ + " from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // extract signature of a slot
+ String signature = null;
+ try {
+ signature = reply.getString();
+ log.display(" signature: " + signature);
+ } catch (BoundException e) {
+ log.complain("Unable to extract signature of slot #" + i
+ + " from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // extract code length
+ int length = 0;
+ try {
+ length = reply.getInt();
+ log.display(" length: " + length);
+ } catch (BoundException e) {
+ log.complain("Unable to extract code length for slot #" + i
+ + " from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // extract code length
+ int slot = 0;
+ try {
+ slot = reply.getInt();
+ log.display(" slot: " + length);
+ } catch (BoundException e) {
+ log.complain("Unable to extract slot index of slot #" + i
+ + " from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // find slot name into list of expected variables
+ int found = -1;
+ for (int j = 0; j < variablesCount; j++) {
+ if (variablesList[j][0].equals(name)) {
+ found = j;
+ break;
+ }
+ }
+
+ // check if slot is found and not duplicated
+ if (found >= 0) {
+ if (foundVariablesList[found] > 0) {
+ log.complain("Slot #" + i + " is duplicated "
+ + foundVariablesList[found] + " times: "
+ + name);
+ success = false;
+/*
+ } else {
+ log.display("Found expected variable #" + found + ": "
+ + variablesList[found][0]);
+*/
+ }
+ foundVariablesList[found]++;
+
+ // check slot signature
+ if (!variablesList[found][1].equals(signature)) {
+ log.complain("Unexpected signature for slot #" + i + ": " + signature
+ + " (expected: " + variablesList[found][1] + ")");
+ success = false;
+ }
+ } else {
+ log.display("Unexpected slot #" + i + " (may be synthetic): " + name);
+ }
+
+ // check that code length is not negative
+ if (length < 0) {
+ log.complain("Code length for slot #" + i + " is negative: " + length);
+ success = false;
+ }
+
+ // check that slot index is not negative
+ if (slot < 0) {
+ log.complain("Index of slot #" + i + " is negative: " + slot);
+ success = false;
+ }
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ // check that all expected variables found
+ for (int i = 0; i < variablesCount; i++) {
+ if (foundVariablesList[i] <= 0) {
+ log.complain("No slot found in reply packet for variable: "
+ + variablesList[i][0]);
+ success = false;
+ }
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTable/vartable001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Method/VariableTable/vartable001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Method
+ * command: VariableTable
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Also test checks that names and signatures of returned
+ * arguments and local variables are equal to expected ones.
+ * Test consists of two compoments:
+ * debugger: vartable001
+ * debuggee: vartable001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains classID and methodID for the tested class
+ * and method from debuggee.
+ * Then, debugger creates command packet for Method.VariableTable command
+ * with the found classID and methodID as arguments, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts attributes of all arguments and variables. Also test
+ * checks that extracted attributes have expected values.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Method.VariableTable.vartable001
+ * nsk.jdwp.Method.VariableTable.vartable001a
+ * @comment debuggee should be compiled w/ debug info
+ * @clean nsk.jdwp.Method.VariableTable.vartable001a
+ * @compile -g:lines,source,vars ../vartable001a.java
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Method.VariableTable.vartable001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTable/vartable001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.Method.VariableTable;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class vartable001a {
+
+ public static void main(String args[]) {
+ vartable001a _vartable001a = new vartable001a();
+ System.exit(vartable001.JCK_STATUS_BASE + _vartable001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // ensure tested class loaded
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + vartable001.READY);
+ pipe.println(vartable001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + vartable001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (! signal.equals(vartable001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + vartable001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return vartable001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return vartable001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass {
+ int foo = 0;
+
+ // tested method
+ public void testedMethod(
+ boolean booleanArgument,
+ byte byteArgument,
+ char charArgument,
+ short shortArgument,
+ int intArgument,
+ long longArgument,
+ float floatArgument,
+ double doubleArgument,
+ Object objectArgument,
+ String stringArgument
+ ) {
+
+ boolean booleanLocal = booleanArgument;
+ byte byteLocal = byteArgument;
+ char charLocal = charArgument;
+ short shortLocal = shortArgument;
+ int intLocal = intArgument;
+ long longLocal = longArgument;
+ float floatLocal = floatArgument;
+ double doubleLocal = doubleArgument;
+ Object objectLocal = objectArgument;
+ String stringLocal = stringArgument;
+
+ System.out.println(
+ "booleanLocal = " + booleanLocal + "\n" +
+ "byteLocal = " + byteLocal + "\n" +
+ "charLocal = " + charLocal + "\n" +
+ "shortLocal = " + shortLocal + "\n" +
+ "intLocal = " + intLocal + "\n" +
+ "longLocal = " + longLocal + "\n" +
+ "floatLocal = " + floatLocal + "\n" +
+ "doubleLocal = " + doubleLocal + "\n" +
+ "objectLocal = " + objectLocal + "\n" +
+ "stringLocal = " + stringLocal + "\n"
+ );
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTableWithGeneric/vartblwithgen001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,531 @@
+/*
+ * Copyright (c) 2004, 2018, 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.
+ */
+
+package nsk.jdwp.Method.VariableTableWithGeneric;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: Method.VariableTableWithGeneric.
+ *
+ * See vartblwithgen001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class vartblwithgen001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.Method.VariableTableWithGeneric";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "vartblwithgen001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "Method.VariableTableWithGeneric";
+ static final int JDWP_COMMAND_ID = JDWP.Command.Method.VariableTableWithGeneric;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+ static final String THIS_GENERIC_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + "<TT;TN;>" + ";";
+
+ // tested types signature conatants
+ static final String OBJECT_CLASS_SIGNATURE = "Ljava/lang/Object;";
+ static final String STRING_CLASS_SIGNATURE = "Ljava/lang/String;";
+
+
+ // tested method name constant
+ static final String TESTED_METHOD_NAME = "testedMethod";
+
+ // list of tested variables names and signatures
+ static final String variablesList[][] = {
+
+ // synthetic arguments
+ {"this", TESTED_CLASS_SIGNATURE, THIS_GENERIC_SIGNATURE},
+
+ // not generic arguments
+ {"arg11PrimBoolean", "Z", ""},
+ {"arg12PrimInt", "I", ""},
+ {"arg13Object", "Ljava/lang/Object;", ""},
+ {"arg14String", "Ljava/lang/String;", ""},
+ {"arg15PrimArrShort", "[S", ""},
+ {"arg16ObjArrObject", "[Ljava/lang/Object;", ""},
+
+ // generic arguments
+ {"arg21GenObject", "Ljava/lang/Object;", "TT;"},
+ {"arg22GenNumber", "Ljava/lang/Number;", "TN;"},
+ {"arg23GenObjectArr", "[Ljava/lang/Object;", "[TT;"},
+ {"arg24GenNumberArr", "[Ljava/lang/Number;", "[TN;"},
+ {"arg25GenObjectList", "Ljava/util/List;", "Ljava/util/List<TT;>;"},
+ {"arg26GenNumberList", "Ljava/util/List;", "Ljava/util/List<TN;>;"},
+ {"arg27GenObjectDerivedList", "Ljava/util/List;", "Ljava/util/List<+TT;>;"},
+ {"arg28GenNumberDerivedList", "Ljava/util/List;", "Ljava/util/List<+TN;>;"},
+
+ // not generic variables
+ {"var11PrimBoolean", "Z", ""},
+ {"var12PrimInt", "I", ""},
+ {"var13Object", "Ljava/lang/Object;", ""},
+ {"var14String", "Ljava/lang/String;", ""},
+ {"var15PrimArrShort", "[S", ""},
+ {"var16ObjArrObject", "[Ljava/lang/Object;", ""},
+
+ // generic variables
+ {"var21GenObject", "Ljava/lang/Object;", "TT;"},
+ {"var22GenNumber", "Ljava/lang/Number;", "TN;"},
+ {"var23GenObjectArr", "[Ljava/lang/Object;", "[TT;"},
+ {"var24GenNumberArr", "[Ljava/lang/Number;", "[TN;"},
+ {"var25GenObjectList", "Ljava/util/List;", "Ljava/util/List<TT;>;"},
+ {"var26GenNumberList", "Ljava/util/List;", "Ljava/util/List<TN;>;"},
+ {"var27GenObjectDerivedList", "Ljava/util/List;", "Ljava/util/List<+TT;>;"},
+ {"var28GenNumberDerivedList", "Ljava/util/List;", "Ljava/util/List<+TN;>;"},
+
+ };
+ static final int variablesCount = variablesList.length;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new vartblwithgen001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for methodID of tested method (declared in the class)
+ log.display("Getting methodID by name: " + TESTED_METHOD_NAME);
+ long methodID = debugee.getMethodID(classID, TESTED_METHOD_NAME, true);
+ log.display(" got methodID: " + methodID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(classID, methodID);
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Perform testing JDWP command for specified TypeID.
+ */
+ void testCommand(long classID, long methodID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" referenceTypeID: " + classID);
+ command.addReferenceTypeID(classID);
+ log.display(" methodID: " + methodID);
+ command.addMethodID(methodID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // clear list of found variables
+ int[] foundVariablesList = new int[variablesCount];
+ for (int i = 0; i < variablesCount; i++) {
+ foundVariablesList[i] = 0;
+ }
+
+ // extract and check reply data
+
+ // extract number of argumnets
+ int argCount = 0;
+ try {
+ argCount = reply.getInt();
+ log.display(" argCount: " + argCount);
+ } catch (BoundException e) {
+ log.complain("Unable to extract number of arguments from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that number of arguments is not negative
+ if (argCount < 0) {
+ log.complain("Negative of arguments in reply packet: " + argCount);
+ success = false;
+ }
+
+ // extract number of slots
+ int slots = 0;
+ try {
+ slots = reply.getInt();
+ log.display(" slots: " + slots);
+ } catch (BoundException e) {
+ log.complain("Unable to extract number of slots from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that number of slots is not negative
+ if (slots < 0) {
+ log.complain("Negative value of end code index in reply packet: " + slots);
+ success = false;
+ }
+
+ // check that start code is not less than expected
+ if (slots < variablesCount) {
+ log.complain("Number of slots (" + slots
+ + ") is less than expected (" + variablesCount + ")");
+ success = false;
+ }
+
+ // extract and check each slot attributes
+ for (int i = 0; i < slots; i++) {
+ log.display(" slot #" + i + ":");
+
+ // extract code index of a slot
+ long codeIndex = 0;
+ try {
+ codeIndex = reply.getLong();
+ log.display(" codeIndex: " + codeIndex);
+ } catch (BoundException e) {
+ log.complain("Unable to extract code index of slot #" + i
+ + " from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that code index is not negative
+ if (codeIndex < 0) {
+ log.complain("Negative code index of slot #" + i + ":" + codeIndex);
+ success = false;
+ }
+
+ // extract name of a slot
+ String name = null;
+ try {
+ name = reply.getString();
+ log.display(" name: " + name);
+ } catch (BoundException e) {
+ log.complain("Unable to extract name of slot #" + i
+ + " from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // extract signature of a slot
+ String signature = null;
+ try {
+ signature = reply.getString();
+ log.display(" signature: " + signature);
+ } catch (BoundException e) {
+ log.complain("Unable to extract signature of slot #" + i
+ + " from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // extract generic signature of a slot
+ String genericSignature = null;
+ try {
+ genericSignature = reply.getString();
+ log.display(" generic: " + genericSignature);
+ } catch (BoundException e) {
+ log.complain("Unable to extract generic signature of slot #" + i
+ + " from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // extract code length
+ int length = 0;
+ try {
+ length = reply.getInt();
+ log.display(" length: " + length);
+ } catch (BoundException e) {
+ log.complain("Unable to extract code length for slot #" + i
+ + " from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // extract code length
+ int slot = 0;
+ try {
+ slot = reply.getInt();
+ log.display(" slot: " + length);
+ } catch (BoundException e) {
+ log.complain("Unable to extract slot index of slot #" + i
+ + " from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // find slot name into list of expected variables
+ int found = -1;
+ for (int j = 0; j < variablesCount; j++) {
+ if (variablesList[j][0].equals(name)) {
+ found = j;
+ break;
+ }
+ }
+
+ // check if slot is found and not duplicated
+ if (found >= 0) {
+ if (foundVariablesList[found] > 0) {
+ log.complain("Slot #" + i + " is duplicated "
+ + foundVariablesList[found] + " times: "
+ + name);
+ success = false;
+/*
+ } else {
+ log.display("Found expected variable #" + found + ": "
+ + variablesList[found][0]);
+*/
+ }
+ foundVariablesList[found]++;
+
+ // check slot signature
+ if (!variablesList[found][1].equals(signature)) {
+ log.complain("Unexpected signature for slot #" + i + ": " + signature
+ + " (expected: " + variablesList[found][1] + ")");
+ success = false;
+ }
+
+ // check slot generic signature
+ if (variablesList[found][2] == null && genericSignature != null) {
+ log.complain("Unexpected generic signature for slot #" + i + ": " + genericSignature
+ + " (expected: " + variablesList[found][2] + ")");
+ success = false;
+ } else if (!variablesList[found][2].equals(genericSignature)) {
+ log.complain("Unexpected generic signature for slot #" + i + ": " + genericSignature
+ + " (expected: " + variablesList[found][2] + ")");
+ success = false;
+ }
+
+ } else {
+ log.display("Unexpected slot #" + i + " (may be synthetic): " + name);
+ }
+
+ // check that code length is not negative
+ if (length < 0) {
+ log.complain("Code length for slot #" + i + " is negative: " + length);
+ success = false;
+ }
+
+ // check that slot index is not negative
+ if (slot < 0) {
+ log.complain("Index of slot #" + i + " is negative: " + slot);
+ success = false;
+ }
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ // check that all expected variables found
+ for (int i = 0; i < variablesCount; i++) {
+ if (foundVariablesList[i] <= 0) {
+ log.complain("No slot found in reply packet for variable: "
+ + variablesList[i][0]);
+ success = false;
+ }
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTableWithGeneric/vartblwithgen001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/Method/VariableTableWithGeneric/vartblwithgen001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: Method
+ * command: VariableTableWithGeneric
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Also test checks that names and generic signatures of returned
+ * arguments and local variables are equal to expected ones.
+ * Test consists of two compoments:
+ * debugger: vartblwithgen001
+ * debuggee: vartblwithgen001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains classID and methodID for the tested class
+ * and method from debuggee.
+ * Then, debugger creates command packet for Method.VariableTableWithGeneric
+ * command with the found classID and methodID as arguments, writes packet
+ * to the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts attributes of all arguments and variables. Also test
+ * checks that extracted attributes have expected values.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.Method.VariableTableWithGeneric.vartblwithgen001
+ * nsk.jdwp.Method.VariableTableWithGeneric.vartblwithgen001a
+ * @comment debuggee should be compiled w/ debug info
+ * @clean nsk.jdwp.Method.VariableTableWithGeneric.vartblwithgen001a
+ * @compile -g:lines,source,vars ../vartblwithgen001a.java
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.Method.VariableTableWithGeneric.vartblwithgen001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/VariableTableWithGeneric/vartblwithgen001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2004, 2018, 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.
+ */
+
+package nsk.jdwp.Method.VariableTableWithGeneric;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class vartblwithgen001a {
+
+ public static void main(String args[]) {
+ vartblwithgen001a _vartblwithgen001a = new vartblwithgen001a();
+ System.exit(vartblwithgen001.JCK_STATUS_BASE + _vartblwithgen001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // ensure tested class loaded
+ log.display("Creating object of tested class");
+ TestedClass<String, Long> foo = new TestedClass<String, Long>();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + vartblwithgen001.READY);
+ pipe.println(vartblwithgen001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + vartblwithgen001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (! signal.equals(vartblwithgen001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + vartblwithgen001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return vartblwithgen001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return vartblwithgen001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass<T, N extends Number> {
+ int foo = 0;
+
+ // tested method
+ public void testedMethod(
+ // not generic argumments
+ boolean arg11PrimBoolean,
+ int arg12PrimInt,
+ Object arg13Object,
+ String arg14String,
+ short[] arg15PrimArrShort,
+ Object[] arg16ObjArrObject,
+
+ // generic arguments
+ T arg21GenObject,
+ N arg22GenNumber,
+ T[] arg23GenObjectArr,
+ N[] arg24GenNumberArr,
+ List<T> arg25GenObjectList,
+ List<N> arg26GenNumberList,
+ List<? extends T> arg27GenObjectDerivedList,
+ List<? extends N> arg28GenNumberDerivedList
+ ) {
+
+ // not generic variables
+ boolean var11PrimBoolean = arg11PrimBoolean;
+ int var12PrimInt = arg12PrimInt;
+ Object var13Object = arg13Object;
+ String var14String = arg14String;
+ short[] var15PrimArrShort = arg15PrimArrShort;
+ Object[] var16ObjArrObject = arg16ObjArrObject;
+
+ // generic variables
+ T var21GenObject = arg21GenObject;
+ N var22GenNumber = arg22GenNumber;
+ T[] var23GenObjectArr = arg23GenObjectArr;
+ N[] var24GenNumberArr = arg24GenNumberArr;
+ List<T> var25GenObjectList = arg25GenObjectList;
+ List<N> var26GenNumberList = arg26GenNumberList;
+ List<? extends T> var27GenObjectDerivedList = arg27GenObjectDerivedList;
+ List<? extends N> var28GenNumberDerivedList = arg28GenNumberDerivedList;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/DisableCollection/disablecol001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ObjectReference.DisableCollection;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ObjectReference.DisableCollection.
+ *
+ * See disablecol001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class disablecol001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String ERROR = "error";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ObjectReference.DisableCollection";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "disablecol001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ObjectReference.DisableCollection";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ObjectReference.DisableCollection;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the tested thread and statioc field with thread value
+ static final String OBJECT_FIELD_NAME = disablecol001a.OBJECT_FIELD_NAME;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new disablecol001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ try {
+ log.display("\n>>> Obtaining requred data from debuggee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for objectID value from static field
+ log.display("Getting objectID value from static field: "
+ + OBJECT_FIELD_NAME);
+ long objectID = queryObjectID(classID,
+ OBJECT_FIELD_NAME, JDWP.Tag.OBJECT);
+ log.display(" got objectID: " + objectID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(objectID);
+
+ } finally {
+ log.display("\n>>> Finishing test \n");
+
+ // quit debugee
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ } else if (signal.equals(ERROR)) {
+ throw new TestBug("Debugee was not able to start tested thread"
+ + " (received signal: " + signal + ")");
+ } else if (!signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for objectID value of static class field.
+ */
+ long queryObjectID(long classID, String fieldName, byte tag) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != tag) {
+ throw new Failure("Wrong objectID tag received from field \"" + fieldName
+ + "\": " + value.getTag() + " (expected: " + tag + ")");
+ }
+
+ // extract threadID from the value
+ long objectID = ((Long)value.getValue()).longValue();
+ return objectID;
+ }
+
+ /**
+ * Perform testing JDWP command for specified threadID.
+ */
+ void testCommand(long objectID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" objectID: " + objectID);
+ command.addObjectID(objectID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/DisableCollection/disablecol001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ObjectReference/DisableCollection/disablecol001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ObjectReference
+ * command: DisableCollection
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: disablecol001
+ * debuggee: disablecol001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains from debuggee classID for the tested class
+ * and objectID as the value of the class static field.
+ * Then, debugger creates command packet for ObjectReference.DisableCollection
+ * command with the found objectID as an argument, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and checks that there is no reply data in the package.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ObjectReference.DisableCollection.disablecol001
+ * nsk.jdwp.ObjectReference.DisableCollection.disablecol001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ObjectReference.DisableCollection.disablecol001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/DisableCollection/disablecol001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ObjectReference.DisableCollection;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class disablecol001a {
+
+ // name for the tested thread
+ public static final String OBJECT_FIELD_NAME = "object";
+
+ public static void main(String args[]) {
+ disablecol001a _disablecol001a = new disablecol001a();
+ System.exit(disablecol001.JCK_STATUS_BASE + _disablecol001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // load tested class and create tested thread
+ log.display("Creating object of tested class");
+ TestedClass.object = new TestedClass();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + disablecol001.READY);
+ pipe.println(disablecol001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + disablecol001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(disablecol001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + disablecol001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return disablecol001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return disablecol001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass {
+
+ // static field with the tested object value
+ public static volatile TestedClass object = null;
+
+ private int foo = 0;
+
+ public TestedClass() {
+ foo = 100;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/EnableCollection/enablecol001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ObjectReference.EnableCollection;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ObjectReference.EnableCollection.
+ *
+ * See enablecol001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class enablecol001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String ERROR = "error";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ObjectReference.EnableCollection";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "enablecol001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ObjectReference.EnableCollection";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ObjectReference.EnableCollection;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the tested thread and statioc field with thread value
+ static final String OBJECT_FIELD_NAME = enablecol001a.OBJECT_FIELD_NAME;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new enablecol001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ try {
+ log.display("\n>>> Obtaining requred data from debuggee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for objectID value from static field
+ log.display("Getting objectID value from static field: "
+ + OBJECT_FIELD_NAME);
+ long objectID = queryObjectID(classID,
+ OBJECT_FIELD_NAME, JDWP.Tag.OBJECT);
+ log.display(" got objectID: " + objectID);
+
+ // query debuggee to disable garbage collection for this object
+ log.display("Disabling garbage collection for objectID: " + objectID);
+ disableObjectCollection(objectID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(objectID);
+
+ } finally {
+ log.display("\n>>> Finishing test \n");
+
+ // quit debugee
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ } else if (signal.equals(ERROR)) {
+ throw new TestBug("Debugee was not able to start tested thread"
+ + " (received signal: " + signal + ")");
+ } else if (!signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for objectID value of static class field.
+ */
+ long queryObjectID(long classID, String fieldName, byte tag) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != tag) {
+ throw new Failure("Wrong objectID tag received from field \"" + fieldName
+ + "\": " + value.getTag() + " (expected: " + tag + ")");
+ }
+
+ // extract threadID from the value
+ long objectID = ((Long)value.getValue()).longValue();
+ return objectID;
+ }
+
+ /**
+ * Perform testing JDWP command for specified threadID.
+ */
+ void disableObjectCollection(long objectID) {
+ CommandPacket command = new CommandPacket(JDWP.Command.ObjectReference.DisableCollection);
+ command.addObjectID(objectID);
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+ }
+
+ /**
+ * Perform testing JDWP command for specified threadID.
+ */
+ void testCommand(long objectID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" objectID: " + objectID);
+ command.addObjectID(objectID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/EnableCollection/enablecol001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ObjectReference/EnableCollection/enablecol001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ObjectReference
+ * command: EnableCollection
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: enablecol001
+ * debuggee: enablecol001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains from debuggee classID for the tested class
+ * and objectID as the value of the class static field. Debugger
+ * queries debuggee to disable garbage collection for this object.
+ * Then, debugger creates command packet for ObjectReference.EnableCollection
+ * command with the found objectID as an argument, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and checks that there is no reply data in the package.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ObjectReference.EnableCollection.enablecol001
+ * nsk.jdwp.ObjectReference.EnableCollection.enablecol001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ObjectReference.EnableCollection.enablecol001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/EnableCollection/enablecol001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ObjectReference.EnableCollection;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class enablecol001a {
+
+ // name for the tested thread
+ public static final String OBJECT_FIELD_NAME = "object";
+
+ public static void main(String args[]) {
+ enablecol001a _enablecol001a = new enablecol001a();
+ System.exit(enablecol001.JCK_STATUS_BASE + _enablecol001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // load tested class and create tested thread
+ log.display("Creating object of tested class");
+ TestedClass.object = new TestedClass();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + enablecol001.READY);
+ pipe.println(enablecol001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + enablecol001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(enablecol001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + enablecol001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return enablecol001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return enablecol001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass {
+
+ // static field with the tested object value
+ public static volatile TestedClass object = null;
+
+ private int foo = 0;
+
+ public TestedClass() {
+ foo = 100;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/GetValues/getvalues001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ObjectReference.GetValues;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ObjectReference.GetValues.
+ *
+ * See getvalues001.README for description of test execution.
+ *
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class getvalues001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ObjectReference.GetValues";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "getvalues001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ObjectReference.GetValues";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ObjectReference.GetValues;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the static field in the tested class with the tested object value
+ static final String OBJECT_FIELD_NAME = getvalues001a.OBJECT_FIELD_NAME;
+
+ // names and expected values of the tested fields
+ static final Object fields [][] = {
+ { "booleanValue", "boolean", new Boolean(true), "own"},
+ { "byteValue", "byte", new Byte((byte)0x0F), "own"},
+ { "charValue", "char", new Character('Z'), "own"},
+ { "intValue", "int", new Integer(100), "own"},
+ { "shortValue", "short", new Short((short)10), "own"},
+ { "longValue", "long", new Long((long)1000000), "own"},
+ { "floatValue", "float", new Float((float)3.14), "own"},
+ { "doubleValue", "double", new Double((double)2.8e-12), "own"},
+ { "objectValue", "objectID", new Long((long)0), "own"},
+
+ };
+ static final int FIELDS_COUNT = fields.length;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new getvalues001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debugee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debugee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debugee for TypeID of tested class
+ log.display("Getting ReferenceTypeID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for objectID value from static field
+ log.display("Getting objectID value from static field: "
+ + OBJECT_FIELD_NAME);
+ long objectID = queryObjectID(classID,
+ OBJECT_FIELD_NAME, JDWP.Tag.OBJECT);
+ log.display(" got objectID: " + objectID);
+
+ // query debugee for fieldIDs of tested class static fields
+ log.display("Getting fieldIDs the tested class with the tested values");
+ long fieldIDs[] = queryClassFieldIDs(classID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(objectID, fieldIDs);
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ e.printStackTrace(out);
+ success = false;
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception:\n" + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received form debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for objectID value of static class field.
+ */
+ long queryObjectID(long classID, String fieldName, byte tag) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != tag) {
+ throw new Failure("Wrong objectID tag received from field \"" + fieldName
+ + "\": " + value.getTag() + " (expected: " + tag + ")");
+ }
+
+ // extract threadID from the value
+ long objectID = ((Long)value.getValue()).longValue();
+ return objectID;
+ }
+
+ /**
+ * Query debugee for fieldIDs and them into nested_classesIDs array.
+ */
+ long[] queryClassFieldIDs(long typeID) {
+ // create array for expected filedIDs
+ long fieldIDs[] = new long[FIELDS_COUNT];
+ for (int i = 0; i < FIELDS_COUNT; i++) {
+ fieldIDs[i] = 0;
+ }
+
+ // obtain requested fieldIDs form debuggee
+ int count = 0;
+ try {
+ CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.Fields);
+ command.addReferenceTypeID(typeID);
+ command.setLength();
+
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+ reply.resetPosition();
+
+ long declared = reply.getInt();
+ if (declared < FIELDS_COUNT) {
+ throw new Failure("Too few fields of the tested class returned: " + declared
+ + " (expected: at least " + FIELDS_COUNT + ")");
+ }
+
+ for (int i = 0; i < declared; i++ ) {
+ long fieldID = reply.getFieldID();
+ String name = reply.getString();
+ String signature = reply.getString();
+ int modBits = reply.getInt();
+
+ for (int j = 0; j < FIELDS_COUNT; j++) {
+ if (fields[j][0].equals(name)) {
+ fieldIDs[j] = fieldID;
+ break;
+ }
+ }
+ }
+
+ if (!reply.isParsed()) {
+ throw new Failure("Extra trailing bytes found in the reply packet at: "
+ + reply.currentPosition());
+ }
+
+ } catch (BoundException e) {
+ throw new Failure("Unable to extract field IDs from the reply packet:\n"
+ + e.getMessage());
+ }
+
+ return fieldIDs;
+ }
+
+ /**
+ * Extract and check i-th value from the reply packet.
+ */
+ void checkValue(int i, JDWP.Value value) {
+ if (!fields[i][2].equals(value.getValue())) {
+ log.complain("Unexpected value for " + i + " field received: " + value
+ + " (expected: " + fields[i][2] + ")");
+ success = false;
+ }
+ }
+
+ /**
+ * Perform testing JDWP command for specified objectID.
+ */
+ void testCommand(long objectID, long fieldIDs[]) {
+ int count = fieldIDs.length;
+
+ // create command packet
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+
+ // add out data to the command packet
+ log.display(" objectID: " + objectID);
+ command.addObjectID(objectID);
+ log.display(" fields: " + count);
+ command.addInt(count);
+ for (int i = 0; i < count; i++) {
+ log.display(" #" + i +": fieldID: " + fieldIDs[i]);
+ command.addFieldID(fieldIDs[i]);
+ }
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet: " + e.getMessage());
+ success = false;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract and check number of values
+ int values = 0;
+ try {
+ values = reply.getInt();
+ log.display(" values: " + values);
+
+ } catch (BoundException e) {
+ log.complain("Unable to extract number of values form reply packet:\n" + e.getMessage());
+ success = false;
+ }
+
+ // check if number of values are as expected
+ if (values < 0) {
+ log.complain("Negative number of values received:" + values
+ + " (expected: " + count + ")");
+ success = false;
+ } else if (values != count) {
+ log.complain("Unexpected number of values received:" + values
+ + " (expected: " + count + ")");
+ success = false;
+ }
+
+ // extract and check each value
+ for (int i = 0; i < values; i++ ) {
+ log.display(" value #" + i + " (field: " + fields[i][0] + ")");
+
+ // extract value
+ JDWP.Value value = null;
+ try {
+ value = reply.getValue();
+ log.display(" value: " + value);
+ } catch (BoundException e) {
+ log.complain("Unable to extract " + i + " value:\n" + e.getMessage());
+ success = false;
+ break;
+ }
+
+ // extract and check value by known type tag
+ checkValue(i, value);
+ }
+
+ // check for extra data in reply packet
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + "0x" + reply.toHexString(reply.currentDataPosition(), 4));
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/GetValues/getvalues001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ObjectReference/GetValues/getvalues001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ObjectReference
+ * command: GetValues
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * the returned values of requested fields are equal to
+ * the expected ones.
+ * Test consists of two compoments:
+ * debugger: getvalues001
+ * debuggee: getvalues001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization messages.
+ * Next, debugger obtains from debuggee classID for the tested class and
+ * objectID as the value of the class static field. Also debugger obtains
+ * fieldIDs for all tested fields of the class.
+ * Then, debugger creates command packet for GetValues command with the
+ * found objectID and list of fieldIDs as arguments, writes packet
+ * to the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts values of the requested fields. Also test checks
+ * that extracted values are equal to the expected ones.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ObjectReference.GetValues.getvalues001
+ * nsk.jdwp.ObjectReference.GetValues.getvalues001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ObjectReference.GetValues.getvalues001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/GetValues/getvalues001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ObjectReference.GetValues;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class getvalues001a {
+
+ public static final String OBJECT_FIELD_NAME = "object";
+
+ public static void main(String args[]) {
+ getvalues001a _getvalues001a = new getvalues001a();
+ System.exit(getvalues001.JCK_STATUS_BASE + _getvalues001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // meke communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // ensure tested class loaded
+ log.display("Creating object of tested class");
+ TestedClass.object = new TestedClass();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + getvalues001.READY);
+ pipe.println(getvalues001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + getvalues001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (! signal.equals(getvalues001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + getvalues001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return getvalues001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return getvalues001.PASSED;
+ }
+
+ // tested class with own static fields values
+ public static class TestedClass {
+
+ // static field with tested object
+ public static TestedClass object = null;
+
+ // fields with tested values
+ private boolean booleanValue = true;
+ private final byte byteValue = (byte)0x0F;
+ protected char charValue = 'Z';
+ protected final int intValue = 100;
+ public short shortValue = (short)10;
+ public final long longValue = (long)1000000;
+ float floatValue = (float)3.14;
+ final double doubleValue = (double)2.8e-12;
+ TestedClass objectValue = null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/InvokeMethod/invokemeth001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ObjectReference.InvokeMethod;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ObjectReference.InvokeMethod.
+ *
+ * See invokemeth001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class invokemeth001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names
+ static final String PACKAGE_NAME = "nsk.jdwp.ObjectReference.InvokeMethod";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "invokemeth001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command
+ static final String JDWP_COMMAND_NAME = "ObjectReference.InvokeMethod";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ObjectReference.InvokeMethod;
+
+ // tested class name and signature
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedObjectClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // field and method names
+ static final String OBJECT_FIELD_NAME = "object";
+ static final String RESULT_FIELD_NAME = "result";
+ static final String TESTED_METHOD_NAME = "testedMethod";
+ static final String BREAKPOINT_METHOD_NAME = "run";
+ static final int BREAKPOINT_LINE_NUMBER = invokemeth001a.BREAKPOINT_LINE_NUMBER;
+
+ // data for invoked method
+ static final int ARGUMENTS_COUNT = 1;
+ static final int INITIAL_VALUE = invokemeth001a.INITIAL_VALUE;
+ static final int ARGUMENT_VALUE = invokemeth001a.FINAL_VALUE;
+ static final int RETURN_VALUE = INITIAL_VALUE;
+ static final int INVOKE_OPTIONS = 0;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+ boolean dead = false;
+
+ // data obtained from debuggee
+ long classID = 0;
+ long threadID = 0;
+ long methodID = 0;
+ long objectID = 0;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new invokemeth001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee VM");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debuggee launched");
+
+ // set timeout for debuggee responces
+ int waitTime = argumentHandler.getWaitTime(); // minutes
+ long timeout = waitTime * 60 * 1000; // milliseconds
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for VM_INIT event
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // run the test
+ runTest();
+
+ // wait for VM_DEATH event
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ log.display(" ... VM_DEATH event received");
+ dead = true;
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ log.display("\n>>> Finishing test \n");
+
+ // disconnect debugee and wait for its exit
+ if (debugee != null) {
+ quitDebugee();
+ }
+ }
+
+ // check result
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+ out.println("TEST PASSED");
+ return PASSED;
+ }
+
+ /**
+ * Obtain required data and test JDWP command.
+ */
+ void runTest() {
+ log.display("\n>>> Obtaining required data \n");
+
+ // wait for tested class loaded on debuggee startup and obtain its classID
+ log.display("Waiting for class loaded:\n\t" + TESTED_CLASS_NAME);
+ classID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... got classID: " + classID);
+ log.display("");
+
+ // query debuggee for tested methodID
+ log.display("Getting tested methodID by name: " + TESTED_METHOD_NAME);
+ methodID = debugee.getMethodID(classID, TESTED_METHOD_NAME, true);
+ log.display(" ... got methodID: " + methodID);
+ log.display("");
+
+ // set breakpoint and wait for debugee reached it
+ log.display("Waiting for breakpoint reached at: "
+ + BREAKPOINT_METHOD_NAME + ":" + BREAKPOINT_LINE_NUMBER);
+ threadID = debugee.waitForBreakpointReached(classID,
+ BREAKPOINT_METHOD_NAME,
+ BREAKPOINT_LINE_NUMBER,
+ JDWP.SuspendPolicy.EVENT_THREAD);
+ log.display(" ... breakpoint reached with threadID: " + threadID);
+ log.display("");
+
+ // get object value from static field
+ log.display("Getting object value from static field: " + OBJECT_FIELD_NAME);
+ objectID = queryObjectID(classID, OBJECT_FIELD_NAME, JDWP.Tag.OBJECT);
+ log.display(" ... got objectID: " + objectID);
+
+
+ // test JDWP command
+ log.display("\n>> Testing JDWP command \n");
+ testCommand();
+
+ // check command results
+ if (success) {
+ log.display("\n>>> Checking command results \n");
+ checkResult();
+ }
+
+ // resume debuggee after the command
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+ }
+
+ /**
+ * Perform testing JDWP command.
+ */
+ void testCommand() {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" objectID: " + objectID);
+ command.addObjectID(objectID);
+ log.display(" threadID: " + threadID);
+ command.addObjectID(threadID);
+ log.display(" classID: " + classID);
+ command.addReferenceTypeID(classID);
+ log.display(" methodID: " + methodID);
+ command.addMethodID(methodID);
+ log.display(" arguments: " + ARGUMENTS_COUNT);
+ command.addInt(ARGUMENTS_COUNT);
+ for (int i = 0; i < ARGUMENTS_COUNT; i++) {
+ JDWP.Value value = new JDWP.Value(JDWP.Tag.INT, new Integer(ARGUMENT_VALUE));
+ log.display(" arg: " + value);
+ command.addValue(value);
+ }
+ log.display(" options: " + INVOKE_OPTIONS);
+ command.addInt(INVOKE_OPTIONS);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // receive reply packet from debugee
+ ReplyPacket reply = new ReplyPacket();
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet for tested command:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Wrong header of reply packet for tested command:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet data:");
+ reply.resetPosition();
+
+ // extract return value
+ JDWP.Value returnValue = null;
+ try {
+ returnValue = reply.getValue();
+ log.display(" returnValue: " + returnValue);
+ } catch (BoundException e) {
+ log.complain("Unable to extract returnValues from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // extract exception tag
+ JDWP.Value exception = null;
+ try {
+ exception = reply.getValue();
+ log.display(" exception: " + exception);
+ } catch (BoundException e) {
+ log.complain("Unable to extract exception from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... packed data parsed");
+
+ // check that return value is an integer
+ if (returnValue.getTag() != JDWP.Tag.INT) {
+ log.complain("Unexpected tag of returnValue returned: " + returnValue.getTag()
+ + " (expected: " + JDWP.Tag.INT + ")");
+ success = false;
+ }
+
+ // check that return value is as expected
+ int intValue = ((Integer)returnValue.getValue()).intValue();
+ if (intValue != RETURN_VALUE) {
+ log.complain("Unexpected value of returnValue returned: " + intValue
+ + " (expected: " + RETURN_VALUE + ")");
+ success = false;
+ }
+
+ // check that exception value is an object
+ if (exception.getTag() != JDWP.Tag.OBJECT) {
+ log.complain("Unexpected tag of exception returned: " + exception.getTag()
+ + " (expected: " + JDWP.Tag.OBJECT + ")");
+ success = false;
+ }
+
+ // check that exception object is null
+ long exceptionID = ((Long)exception.getValue()).longValue();
+ if (exceptionID != 0) {
+ log.complain("Non-null exception object returned: " + exceptionID
+ + " (expected: " + 0 + ")");
+ success = false;
+ }
+ }
+
+ /**
+ * Check result of the tested JDWP command.
+ */
+ void checkResult() {
+ // query debuggee for result value from a static field
+ log.display("Getting result value from static field: " + RESULT_FIELD_NAME);
+ int result = queryInt(classID, RESULT_FIELD_NAME, JDWP.Tag.INT);
+ log.display(" ... got result: " + result);
+
+ // check if the result value is changed as expected
+ if (result != ARGUMENT_VALUE) {
+ log.complain("Method has not been really invoked: \n\t"
+ + "variable not changed by the method: " + result
+ + " (expected: " + ARGUMENT_VALUE + ")");
+ success = false;
+ } else {
+ log.display("Method has been really invoked: \n\t"
+ + " variable changed by the method: " + result
+ + " (expected: " + ARGUMENT_VALUE + ")");
+ }
+ }
+
+ /**
+ * Query debuggee for value of static field of the class.
+ */
+ JDWP.Value queryFieldValue(long classID, String fieldName, byte tag) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != tag) {
+ log.complain("unexpedted value tag returned from debuggee: " + value.getTag()
+ + " (expected: " + tag + ")");
+ throw new Failure("Error occured while getting value from static field: "
+ + fieldName);
+ }
+
+ return value;
+ }
+
+ /**
+ * Query debuggee for objectID value of static field of the class.
+ */
+ long queryObjectID(long classID, String fieldName, byte tag) {
+ JDWP.Value value = queryFieldValue(classID, fieldName, tag);
+ long objectID = ((Long)value.getValue()).longValue();
+ return objectID;
+ }
+
+ /**
+ * Query debuggee for int value of static field of the class.
+ */
+ int queryInt(long classID, String fieldName, byte tag) {
+ JDWP.Value value = queryFieldValue(classID, fieldName, tag);
+ int intValue = ((Integer)value.getValue()).intValue();
+ return intValue;
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debuggee if not dead
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally dispose debuggee:\n\t" + e.getMessage());
+ }
+ }
+
+ // wait for debugee exits
+ log.display("Waiting for debuggee exits");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee finished with exit code: " + code);
+
+ // analize debuggee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/InvokeMethod/invokemeth001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ObjectReference/InvokeMethod/invokemeth001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ObjectReference
+ * command: InvokeMethod
+ * Test checks that debugee accept the command packet and replies
+ * with correct reply packet. Also test checks that the tested method
+ * is really invoked for an object into debuggee.
+ * Test consists of two compoments:
+ * debugger: invokemeth001
+ * debuggee: invokemeth001a
+ * First, debugger uses nsk.share.* support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded, requests methodID
+ * for tested method, sets breakpoint and wait for breakpoint reached.
+ * When breakpoint event received the tested thread into debuggee
+ * is suspended by this event. Debugger gets objectID value for tested
+ * object from static field of the tested class.
+ * Then, debugger creates command packet for ObjectReference.InvokeMethod
+ * command with the found objectID, classID, methodID, threadID, and also
+ * adds one integer argument for the method invocation. Then debugger writes
+ * packet to the transport channel and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts method's result value and exception objectID. Test checks
+ * if result value is an expected integer and exception objectID is null.
+ * Also test gets value of static field, wich should be modified by
+ * the invoked method, to verify if this method was really invoked
+ * into debuggee.
+ * Finally, debugger disconnects debuggee, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ObjectReference.InvokeMethod.invokemeth001
+ * nsk.jdwp.ObjectReference.InvokeMethod.invokemeth001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ObjectReference.InvokeMethod.invokemeth001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/InvokeMethod/invokemeth001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.ObjectReference.InvokeMethod;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class invokemeth001a {
+
+ // name of the tested thread
+ public static final String THREAD_NAME = "testedThread";
+
+ // line nunber for breakpoint
+ public static final int BREAKPOINT_LINE_NUMBER = 90;
+
+ // initial and final value of variable changed by the method invoked from debugger
+ public static final int INITIAL_VALUE = 10;
+ public static final int FINAL_VALUE = 1234;
+
+ // scaffold objects
+ private static volatile ArgumentHandler argumentHandler = null;
+ private static volatile Log log = null;
+
+ public static void main(String args[]) {
+ invokemeth001a _invokemeth001a = new invokemeth001a();
+ System.exit(invokemeth001.JCK_STATUS_BASE + _invokemeth001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // create tested of tested class
+ log.display("Creating object of tested class");
+ TestedObjectClass.object = new TestedObjectClass();
+ log.display(" ... object created");
+
+ // invoke method with breakpoint
+ TestedObjectClass.run();
+
+ log.display("Debugee PASSED");
+ return invokemeth001.PASSED;
+ }
+
+ // tested object class
+ public static class TestedObjectClass {
+
+ // tested object value
+ public static volatile TestedObjectClass object = null;
+
+ // result of invoking tested mathod
+ public static volatile int result = INITIAL_VALUE;
+
+ // start the thread and suspend on breakpoint
+ public static void run() {
+ log.display("Tested thread: started");
+
+ log.display("Breakpoint line reached");
+ // next line is for breakpoint
+ int foo = 0; // BREAKPOINT_LINE_NUMBER
+ log.display("Breakpoint line passed");
+
+ log.display("Tested thread: finished");
+ }
+
+ // tested method for invokation from debugger
+ public int testedMethod(int arg) {
+ log.display("Tested method invoked with argument:" + arg);
+ int old = result;
+ result = arg;
+ log.display("Tested method returned with result:" + old);
+ return old;
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/IsCollected/iscollected001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,321 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ObjectReference.IsCollected;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ObjectReference.IsCollected.
+ *
+ * See iscollected001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class iscollected001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String ERROR = "error";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ObjectReference.IsCollected";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "iscollected001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ObjectReference.IsCollected";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ObjectReference.IsCollected;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the tested thread and statioc field with thread value
+ static final String OBJECT_FIELD_NAME = iscollected001a.OBJECT_FIELD_NAME;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new iscollected001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ try {
+ log.display("\n>>> Obtaining requred data from debuggee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for objectID value from static field
+ log.display("Getting objectID value from static field: "
+ + OBJECT_FIELD_NAME);
+ long objectID = queryObjectID(classID,
+ OBJECT_FIELD_NAME, JDWP.Tag.OBJECT);
+ log.display(" got objectID: " + objectID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(objectID, classID);
+
+ } finally {
+ log.display("\n>>> Finishing test \n");
+
+ // quit debugee
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ } else if (signal.equals(ERROR)) {
+ throw new TestBug("Debugee was not able to start tested thread"
+ + " (received signal: " + signal + ")");
+ } else if (!signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for objectID value of static class field.
+ */
+ long queryObjectID(long classID, String fieldName, byte tag) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != tag) {
+ throw new Failure("Wrong objectID tag received from field \"" + fieldName
+ + "\": " + value.getTag() + " (expected: " + tag + ")");
+ }
+
+ // extract threadID from the value
+ long objectID = ((Long)value.getValue()).longValue();
+ return objectID;
+ }
+
+ /**
+ * Perform testing JDWP command for specified threadID.
+ */
+ void testCommand(long objectID, long classID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" objectID: " + objectID);
+ command.addObjectID(objectID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract boolean result value
+ byte isCollected = (byte)0;
+ try {
+ isCollected = reply.getByte();
+ log.display(" isCollected: " + isCollected);
+ } catch (BoundException e) {
+ log.complain("Unable to extract isCollected boolean value from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ // check that isCollected is false (i.e. 0)
+ if (isCollected != 0) {
+ log.complain("Unexpected true isCollected value received:" + isCollected
+ + " (expected" + 0);
+ success = false;
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/IsCollected/iscollected001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ObjectReference/IsCollected/iscollected001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ObjectReference
+ * command: IsCollected
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Also test checks that the returned isCollected value is false
+ * because tested object is not garbage collected into debuggee.
+ * Test consists of two compoments:
+ * debugger: iscollected001
+ * debuggee: iscollected001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains from debuggee classID for the tested class
+ * and objectID as the value of the class static field.
+ * Then, debugger creates command packet for ObjectReference.IsCollected
+ * command with the found objectID as an argument, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts isCollected boolean value. Also test checks that the
+ * extracted isCollected value is false.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ObjectReference.IsCollected.iscollected001
+ * nsk.jdwp.ObjectReference.IsCollected.iscollected001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ObjectReference.IsCollected.iscollected001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/IsCollected/iscollected001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ObjectReference.IsCollected;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class iscollected001a {
+
+ // name for the tested thread
+ public static final String OBJECT_FIELD_NAME = "object";
+
+ public static void main(String args[]) {
+ iscollected001a _iscollected001a = new iscollected001a();
+ System.exit(iscollected001.JCK_STATUS_BASE + _iscollected001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // load tested class and create tested thread
+ log.display("Creating object of tested class");
+ TestedClass.object = new TestedClass();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + iscollected001.READY);
+ pipe.println(iscollected001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + iscollected001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(iscollected001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + iscollected001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return iscollected001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return iscollected001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass {
+
+ // static field with the tested object value
+ public static volatile TestedClass object = null;
+
+ private int foo = 0;
+
+ public TestedClass() {
+ foo = 100;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/MonitorInfo/monitorinfo001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,487 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ObjectReference.MonitorInfo;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ObjectReference.MonitorInfo.
+ *
+ * See monitorinfo001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class monitorinfo001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String ERROR = "error";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ObjectReference.MonitorInfo";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "monitorinfo001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // VM capability constatnts
+ static final int VM_CAPABILITY_NUMBER = JDWP.Capability.CAN_GET_MONITOR_INFO;
+ static final String VM_CAPABILITY_NAME = "canGetMonitorInfo";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ObjectReference.MonitorInfo";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ObjectReference.MonitorInfo;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME =
+ DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE =
+ "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the tested thread and statioc field with thread value
+ static final String OBJECT_FIELD_NAME =
+ monitorinfo001a.OBJECT_FIELD_NAME;
+ static final String MONITOR_OWNER_FIELD_NAME =
+ monitorinfo001a.MONITOR_OWNER_FIELD_NAME;
+ static final String MONITOR_WAITER_FIELD_NAMES[] =
+ monitorinfo001a.MONITOR_WAITER_FIELD_NAMES;
+
+ // threadIDs of threads owning or waiting for monitor of the tested object
+ long ownerThreadID = 0;
+ long waiterThreadIDs[] = null;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new monitorinfo001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ try {
+ log.display("\n>>> Checking VM capability \n");
+
+ // check for VM capability
+ log.display("Checking VM capability: " + VM_CAPABILITY_NAME);
+ if (!debugee.getCapability(VM_CAPABILITY_NUMBER, VM_CAPABILITY_NAME)) {
+ out.println("TEST PASSED: unsupported VM capability: "
+ + VM_CAPABILITY_NAME);
+ return PASSED;
+ }
+
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for objectID value static field
+ log.display("Getting objectID value from static field: "
+ + OBJECT_FIELD_NAME);
+ long objectID = queryObjectID(classID,
+ OBJECT_FIELD_NAME, JDWP.Tag.OBJECT);
+ log.display(" got objectID: " + objectID);
+
+ // query debuggee for threadIDs from static fields
+ queryThreadIDs(classID);
+
+ log.display("\n>>> Testing JDWP command \n");
+
+ // suspend all threads into debuggee
+ log.display("Suspending all threads into debuggee");
+ debugee.suspend();
+ log.display(" debuggee suspended");
+
+ // perform testing JDWP command
+ testCommand(objectID);
+
+ } finally {
+ log.display("\n>>> Finishing test \n");
+
+ // resume all threads into debuggee
+ log.display("resuming all threads into debuggee");
+ debugee.resume();
+ log.display(" debuggee resumed");
+
+ // quit debugee
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ } else if (signal.equals(ERROR)) {
+ throw new TestBug("Debugee was not able to start tested threads"
+ + " (received signal: " + signal + ")");
+ } else if (!signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for objectID value of static class field.
+ */
+ long queryObjectID(long classID, String fieldName, byte tag) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != tag) {
+ throw new Failure("Wrong objectID tag received from field \"" + fieldName
+ + "\": " + value.getTag() + " (expected: " + tag + ")");
+ }
+
+ // extract threadID from the value
+ long objectID = ((Long)value.getValue()).longValue();
+ return objectID;
+ }
+
+ /**
+ * Query debuggee for threadID values of static class fields.
+ */
+ void queryThreadIDs(long classID) {
+
+ // get threadID for thread which ownes monitor of the tested object
+ ownerThreadID = queryObjectID(classID, MONITOR_OWNER_FIELD_NAME, JDWP.Tag.THREAD);
+
+ // get threadIDs for threads which wait for monitor of the tested object
+ int count = MONITOR_WAITER_FIELD_NAMES.length;
+ waiterThreadIDs = new long[count];
+ for (int i = 0; i < count; i++) {
+ waiterThreadIDs[i] = queryObjectID(classID,
+ MONITOR_WAITER_FIELD_NAMES[i], JDWP.Tag.THREAD);
+ }
+ }
+
+ /**
+ * Perform testing JDWP command for specified objectID.
+ */
+ void testCommand(long objectID) {
+ // make an array for results of found expected monitor waiters
+ int expectedWaiters = waiterThreadIDs.length;
+ int foundWaiters[] = new int[expectedWaiters];
+ for (int i = 0; i < expectedWaiters; i++) {
+ foundWaiters[i] = 0;
+ }
+
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" objectID: " + objectID);
+ command.addObjectID(objectID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract monitor owner threadID
+ long owner = 0;
+ try {
+ owner = reply.getObjectID();
+ log.display(" owner: " + owner);
+ } catch (BoundException e) {
+ log.complain("Unable to extract monitor owner threadID from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that monitor owner is as expected
+ if (owner < 0) {
+ log.complain("Negative value of monitor owner threadID received: "
+ + owner);
+ success = false;
+ } else if (owner == 0) {
+ log.complain("No monitor owner threadID received: "
+ + owner + " (expected: " + ownerThreadID + ")");
+ success = false;
+ } else if (owner != ownerThreadID) {
+ log.complain("Unexpected monitor owner threadID received: "
+ + owner + " (expected: " + ownerThreadID + ")");
+ success = false;
+ }
+
+ // extract number of monitor entries
+ int entryCount = 0;
+ try {
+ entryCount = reply.getInt();
+ log.display(" entryCount: " + entryCount);
+ } catch (BoundException e) {
+ log.complain("Unable to extract monitor entryCount from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that number of waiters is not negative and not zero
+ if (entryCount < 0) {
+ log.complain("Negative number of monitor entryCount received: "
+ + entryCount);
+ success = false;
+ } else if (entryCount == 0) {
+ log.complain("Zero number of monitor entryCount received: "
+ + entryCount);
+ success = false;
+ }
+
+ // extract number of monitor waiter threads
+ int waiters = 0;
+ try {
+ waiters = reply.getInt();
+ log.display(" waiters: " + waiters);
+ } catch (BoundException e) {
+ log.complain("Unable to extract number of monitor waiters from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that number of waiters is not negative
+ if (waiters < 0) {
+ log.complain("Negative number of monitor waiters received: "
+ + waiters);
+ success = false;
+ }
+
+ // check that number of waiters is as expected
+ if (waiters != expectedWaiters) {
+ log.complain("Unexpected number of monitors waiters received: "
+ + waiters + " (expected: " + expectedWaiters + ")");
+ success = false;
+ }
+
+ // extract monitor waiter threadIDs
+ for (int i = 0; i < waiters; i++) {
+
+ log.display(" waiter #" + i + ":");
+
+ // extract threadID
+ long threadID = 0;
+ try {
+ threadID = reply.getObjectID();
+ log.display(" threadID: " + threadID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract " + i + " monitor waiter threadID from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // find threadID among expected monitor owner threadIDs
+ boolean found = false;
+ for (int j = 0; j < expectedWaiters; j++) {
+ if (threadID == waiterThreadIDs[j]) {
+ foundWaiters[j]++;
+ found = true;
+ }
+ }
+ if (!found) {
+ log.complain("Unexpected monitor waiter threadID received: " + threadID);
+ success = false;
+ }
+
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ // check if all expected monitor waiter threadIDs found
+ for (int j = 0; j < expectedWaiters; j++) {
+ if (foundWaiters[j] <= 0) {
+ log.complain("Expected monitor waiter threadID NOT received: "
+ + waiterThreadIDs[j]);
+ success = false;
+ } else if (foundWaiters[j] > 1) {
+ log.complain("Expected monitor waiter threadID (" +
+ + waiterThreadIDs[j] + ") received multiply times: "
+ + foundWaiters[j]);
+ success = false;
+ }
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/MonitorInfo/monitorinfo001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ObjectReference/MonitorInfo/monitorinfo001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ObjectReference
+ * command: MonitorInfo
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Also test checks that expected threadIDs returned either for
+ * monitor owner and waiter threads.
+ * Test consists of two compoments:
+ * debugger: monitorinfo001
+ * debuggee: monitorinfo001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Debuggee created oan object of the tested class as value of the class
+ * static field and starts several threads, which are waiting for this
+ * object monitor, and one thread, which ownes the object monitor.
+ * Then debuggee sends signal READY to the debugger.
+ * Debugger obtains from debuggee classID for tested class and objectID
+ * as the value of the class static field. Also debugger obtains threadIDs
+ * for all tested thread into debuggee.
+ * Debugger suspends debuggee (and all threads into it) before sending
+ * tested JDWP command.
+ * Then, debugger creates command packet for ObjectReference.MonitorInfo
+ * command with the found objectID as an argument, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts threadIDs of thread waiting and owning the object monitor.
+ * Debugger checks that extracted threadIDs are equals to the expected ones..
+ * Finally, debugger resumes debuggee, sends it signal to quit, waits
+ * for it exits and exits too with the proper exit code.
+ * COMMENTS
+ * For JDK 1.4.0-beta3 (build 1.4.0-beta3-b84) and earlier this test passed
+ * because target VM does not support VM capability: canGetMonitorInfo
+ * Test was fixed due to test bug:
+ * 4864492 TEST_BUG: potential race in JDWP test monitorinfo001
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ObjectReference.MonitorInfo.monitorinfo001
+ * nsk.jdwp.ObjectReference.MonitorInfo.monitorinfo001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ObjectReference.MonitorInfo.monitorinfo001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/MonitorInfo/monitorinfo001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ObjectReference.MonitorInfo;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class monitorinfo001a {
+
+ // static field names for the tested objects
+ public static final String OBJECT_FIELD_NAME = "object";
+ public static final String MONITOR_OWNER_FIELD_NAME = "monitorOwner";
+ public static final String MONITOR_WAITER_FIELD_NAMES[] =
+ { "monitorWaiter1", "monitorWaiter2" };
+
+ // lock object to prevent thread from exit
+ private static Object threadExiting = new Object();
+
+ // scaffold objects
+ private static volatile ArgumentHandler argumentHandler = null;
+ private static volatile Log log = null;
+
+ public static void main(String args[]) {
+ monitorinfo001a _monitorinfo001a = new monitorinfo001a();
+ System.exit(monitorinfo001.JCK_STATUS_BASE + _monitorinfo001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ // make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ long timeout = argumentHandler.getWaitTime() * 60 * 1000;
+
+ boolean success = true;
+
+ // lock the object to prevent threads from exit
+ synchronized (threadExiting) {
+
+ // load tested class and create tested object and threads
+ log.display("Creating object of tested class and threads");
+ TestedClass.object = new TestedClass();
+ TestedClass.monitorOwner = new MonitorOwnerThread("MonitorOwnerThread");
+ TestedClass.monitorWaiter1 = new MonitorWaiterThread("MonitorWaiterThread1");
+ TestedClass.monitorWaiter2 = new MonitorWaiterThread("MonitorWaiterThread2");
+
+ // start MonitorWaiterThreads and wait for them become ready
+ if (success) {
+ if (!startMonitorWaiterThread(TestedClass.monitorWaiter1))
+ success = false;
+ }
+ if (success) {
+ if (!startMonitorWaiterThread(TestedClass.monitorWaiter2))
+ success = false;
+ }
+
+ // start MonitorOwnerThread and wait for it becomes ready
+ if (success) {
+ if (!startMonitorOwnerThread(TestedClass.monitorOwner))
+ success = false;
+ }
+
+ // notify debugger if all threads started
+ if (success) {
+ log.display("Send signal to debugger: " + monitorinfo001.READY);
+ pipe.println(monitorinfo001.READY);
+ } else {
+ log.complain("Send signal to debugger: " + monitorinfo001.ERROR);
+ pipe.println(monitorinfo001.ERROR);
+ }
+
+ if (success) {
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + monitorinfo001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(monitorinfo001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + monitorinfo001.QUIT + ")");
+ success = false;
+ }
+ }
+
+ // allow started threads to exit
+ }
+
+ // finish monitor owner thread
+ finishThread(TestedClass.monitorOwner, timeout);
+
+ // notify monitor waiting threads
+ synchronized (TestedClass.object) {
+ TestedClass.object.notifyAll();
+ }
+
+ // finish monitor waiting threads
+ finishThread(TestedClass.monitorWaiter2, timeout);
+ finishThread(TestedClass.monitorWaiter1, timeout);
+
+ // exit debugee
+ if (!success) {
+ log.display("Debugee FAILED");
+ return monitorinfo001.FAILED;
+ }
+
+ log.display("Debugee PASSED");
+ return monitorinfo001.PASSED;
+ }
+
+ // start MonitorWaiterThread and waits for it becomes ready
+ private boolean startMonitorWaiterThread(MonitorWaiterThread thread) {
+ // start thread and wait for it becomes ready
+ synchronized (thread.ready) {
+ thread.start();
+ try {
+ thread.ready.wait();
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for MonitorWaiterThread started:\n\t"
+ + e);
+ return false;
+ }
+ }
+
+ // ensure that thread becomes waiting for tested object
+ synchronized (TestedClass.object) {
+ return true;
+ }
+ }
+
+ // start MonitorOwnrerThread and waits for it becomes ready
+ private boolean startMonitorOwnerThread(MonitorOwnerThread thread) {
+ // start thread an wait for it becomes ready
+ synchronized (thread.ready) {
+ thread.start();
+ try {
+ thread.ready.wait();
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for MonitorOwnerThread started:\n\t"
+ + e);
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ // interrupt thread if it is alive
+ private void finishThread(Thread thread, long timeout) {
+ try {
+ thread.join(timeout);
+ } catch (InterruptedException e) {
+ throw new Failure("Interruption while waiting for thread to finish:\n\t" + e);
+ }
+
+ if (thread.isAlive()) {
+ log.display("Interrupting alive thread: " + thread.getName());
+ thread.interrupt();
+ }
+ }
+
+ /////////////////// Tested class and threads ////////////////
+
+ // tested thread class
+ public static class TestedClass {
+
+ // field with the tested object value
+ public static volatile TestedClass object = null;
+
+ // field with the thread which ownes monitor of the tested object
+ public static MonitorOwnerThread monitorOwner = null;
+
+ // fields with the threads which wait for monitor of the tested object
+ public static MonitorWaiterThread monitorWaiter1 = null;
+ public static MonitorWaiterThread monitorWaiter2 = null;
+
+ // internal field
+ private int foo = 0;
+
+ // constructor
+ public TestedClass() {
+ foo = 100;
+ }
+
+ } // TestedClass class
+
+ // thread which will owns monitor of the tested object
+ public static class MonitorOwnerThread extends Thread {
+
+ public Object ready = new Object();
+
+ public MonitorOwnerThread(String name) {
+ super(name);
+ }
+
+ // start the thread and recursive invoke makeFrames()
+ public void run() {
+ log.display(getName() + " started");
+
+ // get ownership for monitor of the tested object
+ synchronized (TestedClass.object) {
+ log.display(getName() + " owns monitor of the tested object");
+
+ // notify debuggee that thread is ready
+ synchronized (ready) {
+ ready.notifyAll();
+ }
+
+ // wait for debuggee releses object to finish threads
+ synchronized (threadExiting) {
+ log.display(getName() + " finished");
+ }
+
+ }
+
+ }
+
+ } // MonitorOwnerThreadClass
+
+ // thread which will wait for monitor of the tested object
+ public static class MonitorWaiterThread extends Thread {
+
+ public Object ready = new Object();
+
+ public MonitorWaiterThread(String name) {
+ super(name);
+ }
+
+ // start the thread and recursive invoke makeFrames()
+ public void run() {
+ log.display(getName() + " started");
+
+ // get ownership for object monitor for futher waiting
+ synchronized (TestedClass.object) {
+
+ // notify debuggee that thread is ready
+ synchronized (ready) {
+ ready.notifyAll();
+ }
+
+ // go to the waiting state for monitor of the tested object
+ log.display(getName() + " waits for monitor of the tested object");
+ try {
+ TestedClass.object.wait();
+ } catch (InterruptedException e) {
+ log.display(getName() + " is interrupted while waiting for tested object");
+ }
+ }
+
+ // wait for debuggee releses object to finish threads
+ synchronized (threadExiting) {
+ log.display(getName() + " finished");
+ }
+
+ }
+
+ } // MonitorWaiterThread class
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferenceType/referencetype001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,345 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ObjectReference.ReferenceType;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ObjectReference.ReferenceType.
+ *
+ * See referencetype001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class referencetype001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String ERROR = "error";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ObjectReference.ReferenceType";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "referencetype001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ObjectReference.ReferenceType";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ObjectReference.ReferenceType;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the tested thread and statioc field with thread value
+ static final String OBJECT_FIELD_NAME = referencetype001a.OBJECT_FIELD_NAME;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new referencetype001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ long threadID = 0;
+ try {
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for objectID value from static field
+ log.display("Getting objectID value from static field: "
+ + OBJECT_FIELD_NAME);
+ long objectID = queryObjectID(classID,
+ OBJECT_FIELD_NAME, JDWP.Tag.OBJECT);
+ log.display(" got objectID: " + objectID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(objectID, classID);
+
+ } finally {
+ log.display("\n>>> Finishing test \n");
+
+ // quit debugee
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ } else if (signal.equals(ERROR)) {
+ throw new TestBug("Debugee was not able to start tested thread"
+ + " (received signal: " + signal + ")");
+ } else if (!signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for objectID value of static class field.
+ */
+ long queryObjectID(long classID, String fieldName, byte tag) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != tag) {
+ throw new Failure("Wrong objectID tag received from field \"" + fieldName
+ + "\": " + value.getTag() + " (expected: " + tag + ")");
+ }
+
+ // extract threadID from the value
+ long objectID = ((Long)value.getValue()).longValue();
+ return objectID;
+ }
+
+ /**
+ * Perform testing JDWP command for specified threadID.
+ */
+ void testCommand(long objectID, long classID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" objectID: " + objectID);
+ command.addObjectID(objectID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract type tag
+ byte tag = (byte)0;
+ try {
+ tag = reply.getByte();
+ log.display(" refTypeTag: " + tag);
+ } catch (BoundException e) {
+ log.complain("Unable to extract refTypeTag from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // extract typeID
+ long typeID = 0;
+ try {
+ typeID = reply.getReferenceTypeID();
+ log.display(" typeID: " + typeID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract referencTypeID from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that tag is an CLASS type tag
+ if (tag != JDWP.TypeTag.CLASS) {
+ log.complain("Unexpected referenceTypetag received:" + tag
+ + " (expected" + JDWP.TypeTag.CLASS);
+ success = false;
+ }
+
+ // check that typeID is not negative integer
+ if (typeID < 0) {
+ log.complain("Negative value of typeID received: " + typeID);
+ success = false;
+ }
+
+ // check that typeID is equal to the expected classID
+ if (typeID != classID) {
+ log.display("Unexpected typeID received: " + typeID
+ + " (expected" + classID);
+ success = false;
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferenceType/referencetype001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ObjectReference/ReferenceType/referencetype001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ObjectReference
+ * command: ReferenceType
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Also test checks that the returned referenceTypeID for the tested
+ * object is equals to the expected typeID of the tested class.
+ * Test consists of two compoments:
+ * debugger: referencetype001
+ * debuggee: referencetype001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains from debuggee classID for tested thread class
+ * and objectID as the value of a class static field.
+ * thread is waiting for the object at this moment.
+ * Then, debugger creates command packet for ObjectReference.ReferenceType
+ * command with the found objectID as an argument, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts typeTag and typeID for the requested object type.
+ * Also test checks that the extracted objectID is equals to the
+ * expected classID and typeTag is a CLASS type tag.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ObjectReference.ReferenceType.referencetype001
+ * nsk.jdwp.ObjectReference.ReferenceType.referencetype001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ObjectReference.ReferenceType.referencetype001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferenceType/referencetype001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ObjectReference.ReferenceType;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class referencetype001a {
+
+ // name for the tested thread
+ public static final String OBJECT_FIELD_NAME = "object";
+
+ public static void main(String args[]) {
+ referencetype001a _referencetype001a = new referencetype001a();
+ System.exit(referencetype001.JCK_STATUS_BASE + _referencetype001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // load tested class and create tested thread
+ log.display("Creating object of tested class");
+ TestedClass.object = new TestedClass();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + referencetype001.READY);
+ pipe.println(referencetype001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + referencetype001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(referencetype001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + referencetype001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return referencetype001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return referencetype001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass {
+
+ // static field with the tested object value
+ public static volatile TestedClass object = null;
+
+ private int foo = 0;
+
+ public TestedClass() {
+ foo = 100;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferringObjects/referringObjects001/referringObjects001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2007, 2018, 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 converted from VM Testbase nsk/jdwp/ObjectReference/ReferringObjects/referringObjects001.
+ * VM Testbase keywords: [quick, jpda, jdwp, feature_jdk6_jpda, vm6, monitoring]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ObjectReference
+ * command: ReferringObjects
+ * Test checks that debuggee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: referringObjects001
+ * debuggee: referringObjects001a
+ * Debuggee during startup initializes static field 'testInstance' with java.lang.Object instance
+ * and creates objects refer to this instance via references with types which should be supported
+ * by command ObjectReference.ReferringObjects:
+ * - strong reference
+ * - soft reference
+ * - weak reference
+ * - phantom reference
+ * Debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with execution commands.
+ * For maxReferrers in [1, 0, Interger.MAX_VALUE]
+ * do
+ * Debugger obtains objectID for instance assigned to the debuggee's static field 'testInstance'.
+ * Then, debugger creates command packet for ReferringObjects command with the
+ * found objectID and maxReferrers as an arguments, writes packet to the transport
+ * channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts number of referring objects and referring objects ids.
+ * Debugger checks that received number of referring objects is correct:
+ * - if maxReferrers=1 only 1 referring object should be returned
+ * - if maxReferrers=0 or maxReferrers=Integer.MAX_VALUE all referring objects should be returned
+ * done
+ * Also, test performs checks for cases when incorrect data is sent in command.
+ * Following cases are tested:
+ * - create command with maxReferrers=-1, expect ILLEGAL_ARGUMENT error
+ * - create command with objectID = -1, expect INVALID_OBJECT error
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ObjectReference.ReferringObjects.referringObjects001.referringObjects001
+ * @run main/othervm/native PropertyResolvingWrapper
+ * nsk.jdwp.ObjectReference.ReferringObjects.referringObjects001.referringObjects001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="-Xmx128M ${test.vm.opts} ${test.java.opts}"
+ */
+
+package nsk.jdwp.ObjectReference.ReferringObjects.referringObjects001;
+
+import java.io.*;
+import nsk.share.Consts;
+import nsk.share.jdwp.*;
+import nsk.share.jpda.AbstractDebuggeeTest;
+
+public class referringObjects001 extends TestDebuggerType1 {
+
+ protected String getDebugeeClassName() {
+ return nsk.jdwp.ObjectReference.ReferringObjects.referringObjects001.referringObjects001a.class.getName();
+ }
+
+ public static void main(String argv[]) {
+ System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new referringObjects001().runIt(argv, out);
+ }
+
+ private void testCommand(long objectID, int maxReferrers, int expectedReferrersCount, boolean expectError, int errorCode) {
+ try {
+ int JDWP_COMMAND_ID = JDWP.Command.ObjectReference.ReferringObjects;
+
+ log.display("Create command: " + JDWP.commandNames.get(JDWP_COMMAND_ID));
+ log.display("objectID = " + objectID);
+ log.display("maxReferrers = " + maxReferrers);
+
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addObjectID(objectID);
+ command.addInt(maxReferrers);
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ ReplyPacket reply;
+
+ reply = getReply(command, expectError, errorCode);
+
+ if (expectError)
+ return;
+
+ int referringObjects = reply.getInt();
+ log.display("referringObjects = " + referringObjects);
+
+ // check that correct 'referringObjects' value was received
+ if (referringObjects != expectedReferrersCount) {
+ log.complain("Unexpected value 'referringObjects': " + referringObjects + " expected is " + expectedReferrersCount);
+ setSuccess(false);
+ }
+
+ for (int i = 0; i < referringObjects; i++) {
+ JDWP.Value value = reply.getValue();
+ log.display("tagged-ObjectID = " + value);
+ }
+
+ if (!reply.isParsed()) {
+ setSuccess(false);
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ }
+ } catch (Exception e) {
+ setSuccess(false);
+ log.complain("Caught exception while testing JDWP command: " + e);
+ e.printStackTrace(log.getOutStream());
+ }
+ }
+
+ public void doTest() {
+ /*
+ * Provoke GC here to be sure that GC won't start during test execution
+ */
+ forceGC();
+ pipe.println(referringObjects001a.COMMAND_CREATE_TEST_INSTANCES);
+
+ if (!isDebuggeeReady())
+ return;
+
+
+ int referrersCount = referringObjects001a.expectedCount;
+
+ long objectID = queryObjectID(debuggee.getReferenceTypeID(createTypeSignature(getDebugeeClassName())), "testInstance", JDWP.Tag.OBJECT);
+
+ // create command with maxReferrers=1, only 1 referrer should be returned
+ testCommand(objectID, 1, 1, false, 0);
+ // create command with maxReferrers=0, all referrers should be returned
+ testCommand(objectID, 0, referrersCount, false, 0);
+ // create command with maxReferrers=Integer.MAX_VALUE, all referrers should be returned
+ testCommand(objectID, Integer.MAX_VALUE, referrersCount, false, 0);
+
+ // create command with maxReferrers=-1, expect ILLEGAL_ARGUMENT error
+ testCommand(objectID, -1, referrersCount, true, JDWP.Error.ILLEGAL_ARGUMENT);
+
+ // create command with objectID = -1, expect INVALID_OBJECT error
+ testCommand(-1, Integer.MAX_VALUE, referrersCount, true, JDWP.Error.INVALID_OBJECT);
+
+ resetStatusIfGC();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferringObjects/referringObjects001/referringObjects001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 2018, 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.
+ */
+package nsk.jdwp.ObjectReference.ReferringObjects.referringObjects001;
+
+import java.util.*;
+import nsk.share.ReferringObjectSet;
+import nsk.share.jdi.HeapwalkingDebuggee;
+import nsk.share.jdwp.*;
+
+public class referringObjects001a extends AbstractJDWPDebuggee {
+ public static Object testInstance;
+
+ public static final String COMMAND_CREATE_TEST_INSTANCES = "COMMAND_CREATE_TEST_INSTANCES";
+
+ public static final int expectedCount = HeapwalkingDebuggee.includedIntoReferrersCountTypes.size() + 1;
+
+ private ArrayList<ReferringObjectSet> referrers = new ArrayList<ReferringObjectSet>();
+
+ public boolean parseCommand(String command) {
+ if (super.parseCommand(command))
+ return true;
+
+ if (command.equals(COMMAND_CREATE_TEST_INSTANCES)) {
+ testInstance = new Object();
+
+ // create objects refering to 'testInstance' via references with types which should be supported by command ObjectReference.ReferringObjects
+ for (String referenceType : HeapwalkingDebuggee.includedIntoReferrersCountTypes) {
+ referrers.add(new ReferringObjectSet(testInstance, 1, referenceType));
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public static void main(String args[]) {
+ new referringObjects001a().doTest(args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferringObjects/referringObjects002/referringObjects002.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2007, 2018, 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 converted from VM Testbase nsk/jdwp/ObjectReference/ReferringObjects/referringObjects002.
+ * VM Testbase keywords: [quick, jpda, jdwp, feature_jdk6_jpda, vm6, monitoring]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ObjectReference
+ * command: ReferringObjects
+ * Test checks that debuggee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: referringObjects002
+ * debuggee: referringObjects002a
+ * Debuggee contains static field 'testInstance' which initialized with java.lang.Object instance.
+ * Also debuggee contains 6 static fields with names referringObject1, ..., referringObject6, this fields
+ * are initialized with objects which refer to 'testInstance' and there are no more objects referring to
+ * the 'testInstance'.
+ * Debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with execution commands.
+ * Debugger obtains objectID for instance assigned to the debuggee's static field 'testInstance'.
+ * Then, debugger creates command packet for ReferringObjects command with the
+ * found objectID and maxReferrers=0 as an arguments, writes packet to the transport
+ * channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts number of referring objects and referring objects ids.
+ * Debugger checks that number of referring objects is correct - 6.
+ * Debugger obtains objectIDs for object instances stored in debuggee's fields referringObject1, ..., referringObject6
+ * and checks that this values and referring objects ids received via JDWP command are identical.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ObjectReference.ReferringObjects.referringObjects002.referringObjects002
+ * @run main/othervm/native PropertyResolvingWrapper
+ * nsk.jdwp.ObjectReference.ReferringObjects.referringObjects002.referringObjects002
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
+package nsk.jdwp.ObjectReference.ReferringObjects.referringObjects002;
+
+import java.io.PrintStream;
+import nsk.share.Consts;
+import nsk.share.jdwp.*;
+
+public class referringObjects002 extends TestDebuggerType1 {
+ protected String getDebugeeClassName() {
+ return nsk.jdwp.ObjectReference.ReferringObjects.referringObjects002.referringObjects002a.class.getName();
+ }
+
+ public static void main(String argv[]) {
+ System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new referringObjects002().runIt(argv, out);
+ }
+
+ private void testCommand() {
+ try {
+ int JDWP_COMMAND_ID = JDWP.Command.ObjectReference.ReferringObjects;
+
+ long objectID = queryObjectID(
+ debuggee.getReferenceTypeID(createTypeSignature(getDebugeeClassName())),
+ "testInstance",
+ JDWP.Tag.OBJECT);
+
+ // create command with maxReferrers=0 (receive all referrers)
+ log.display("Create command: " + JDWP.commandNames.get(JDWP_COMMAND_ID));
+ log.display("objectID = " + objectID);
+ log.display("maxReferrers = " + 0);
+
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addObjectID(objectID);
+ command.addInt(0);
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ ReplyPacket reply;
+
+ reply = getReply(command);
+
+ int referringObjects = reply.getInt();
+ log.display("referringObjects = " + referringObjects);
+
+ // there are 6 referrers in debuggee
+ int expectedReferrersCount = 6;
+
+ if (referringObjects != expectedReferrersCount) {
+ log.complain("Unexpected value 'referringObjects': " + referringObjects + " expected is " + expectedReferrersCount);
+ setSuccess(false);
+ }
+
+ long expectedReferrersID[] = new long[expectedReferrersCount];
+
+ // initialize expected IDs of referrers
+ for (int i = 0; i < expectedReferrersCount; i++) {
+ expectedReferrersID[i] = queryObjectID(debuggee.getReferenceTypeID(createTypeSignature(getDebugeeClassName())), "referringObject"
+ + (i + 1));
+ }
+
+ long receivedReferrersID[] = new long[referringObjects];
+
+ for (int i = 0; i < referringObjects; i++) {
+ JDWP.Value value = reply.getValue();
+ log.display("tagged-ObjectID = " + value);
+
+ receivedReferrersID[i] = ((Long) value.getValue()).longValue();
+ }
+
+ // check that correct IDs of referrers was received
+ for (int i = 0; i < referringObjects; i++) {
+ boolean isIDExpected = false;
+
+ for (int j = 0; j < expectedReferrersID.length; j++) {
+ if (receivedReferrersID[i] == expectedReferrersID[j]) {
+ isIDExpected = true;
+ break;
+ }
+ }
+
+ if (!isIDExpected) {
+ setSuccess(false);
+ log.complain("Unexpected 'referrerID' value: " + receivedReferrersID[i]);
+ }
+ }
+
+ if (!getSuccess()) {
+ log.complain("Expected IDs:");
+ for (int i = 0; i < expectedReferrersID.length; i++)
+ log.complain("" + expectedReferrersID[i]);
+ }
+
+ if (!reply.isParsed()) {
+ setSuccess(false);
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ }
+ } catch (Exception e) {
+ setSuccess(false);
+ log.complain("Caught exception while testing JDWP command: " + e);
+ e.printStackTrace(log.getOutStream());
+ }
+ }
+
+ public void doTest() {
+ testCommand();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/ReferringObjects/referringObjects002/referringObjects002a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2007, 2018, 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.
+ */
+package nsk.jdwp.ObjectReference.ReferringObjects.referringObjects002;
+
+import nsk.share.ObjectInstancesManager;
+import nsk.share.ReferringObject;
+import nsk.share.jdwp.*;
+
+public class referringObjects002a extends AbstractJDWPDebuggee {
+ public static Object testInstance = new Object();
+
+ // create 5 referrers for 'testInstance'
+ public static ReferringObject referringObject1 = new ReferringObject(testInstance, ObjectInstancesManager.STRONG_REFERENCE);
+
+ public static ReferringObject referringObject2 = new ReferringObject(testInstance, ObjectInstancesManager.STRONG_REFERENCE);
+
+ public static ReferringObject referringObject3 = new ReferringObject(testInstance, ObjectInstancesManager.STRONG_REFERENCE);
+
+ public static ReferringObject referringObject4 = new ReferringObject(testInstance, ObjectInstancesManager.STRONG_REFERENCE);
+
+ public static ReferringObject referringObject5 = new ReferringObject(testInstance, ObjectInstancesManager.STRONG_REFERENCE);
+
+ // since 'testInstance' is static field one of the referrers is referringObjects002a.class
+ public static Class<?> referringObject6 = referringObjects002a.class;
+
+ public static void main(String args[]) {
+ new referringObjects002a().doTest(args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/SetValues/setvalues001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,467 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ObjectReference.SetValues;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ObjectReference.SetValues.
+ *
+ * See setvalues001.README for description of test execution.
+ *
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class setvalues001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String RUN = "run";
+ static final String DONE = "done";
+ static final String ERROR = "error";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ObjectReference.SetValues";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "setvalues001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ObjectReference.SetValues";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ObjectReference.SetValues;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // target values class name and signature constants
+ static final String TARGET_VALUES_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TargetValuesClass";
+ static final String TARGET_VALUES_CLASS_SIGNATURE = "L" + TARGET_VALUES_CLASS_NAME.replace('.', '/') + ";";
+
+ // name and siagnature of a class with static field with the tested object value
+ static final String OBJECT_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "ObjectClass";
+ static final String OBJECT_CLASS_SIGNATURE = "L" + OBJECT_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the static field in the tested class with the tested object value
+ static final String OBJECT_FIELD_NAME = setvalues001a.OBJECT_FIELD_NAME;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new setvalues001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debugee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debugee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debugee for classID for the class with target values
+ log.display("Getting classID for class with target values by signature:\n"
+ + " " + TARGET_VALUES_CLASS_SIGNATURE);
+ long targetValuesClassID =
+ debugee.getReferenceTypeID(TARGET_VALUES_CLASS_SIGNATURE);
+ log.display(" got classID: " + targetValuesClassID);
+
+ // query debugee for fieldIDs of the class static fields
+ log.display("Getting fieldIDs for static fields of the class");
+ long targetValuesFieldIDs[] = queryClassFieldIDs(targetValuesClassID);
+ log.display(" got fields: " + targetValuesFieldIDs.length);
+ int count = targetValuesFieldIDs.length;
+
+ // query debugee for values of the fields
+ log.display("Getting values of the static fields");
+ JDWP.Value targetValues[] =
+ queryClassFieldValues(targetValuesClassID, targetValuesFieldIDs);
+ log.display(" got values: " + targetValues.length);
+ if (targetValues.length != count) {
+ throw new Failure("Unexpected number of static fields values received: "
+ + targetValues.length + "(expected: " + count + ")");
+ }
+
+ // query debugee for classID of the tested class
+ log.display("Getting tested classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long testedClassID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + testedClassID);
+
+ // query debugee for fieldIDs of tested class fields
+ log.display("Getting fieldIDs for tested fields of the tested class");
+ long testedFieldIDs[] = queryClassFieldIDs(testedClassID);
+ log.display(" got fields: " + testedFieldIDs.length);
+ if (testedFieldIDs.length != count) {
+ throw new Failure("Unexpected number of fields of tested class received: "
+ + testedFieldIDs.length + "(expected: " + count + ")");
+ }
+
+ // query debugee for classID of the object class
+ log.display("Getting object classID by signature:\n"
+ + " " + OBJECT_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(OBJECT_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for objectID value from static field
+ log.display("Getting objectID value from static field: "
+ + OBJECT_FIELD_NAME);
+ long objectID = queryObjectID(classID,
+ OBJECT_FIELD_NAME, JDWP.Tag.OBJECT);
+ log.display(" got objectID: " + objectID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(objectID, testedFieldIDs, targetValues);
+
+ // check confirmation from debuggee that values have been set properly
+ log.display("\n>>> Checking that the values have been set properly \n");
+ checkValuesChanged();
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ e.printStackTrace(out);
+ success = false;
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception:\n" + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received form debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debugee for fieldID's of the class static fields.
+ */
+ long[] queryClassFieldIDs(long classID) {
+ // compose ReferenceType.Fields command packet
+ CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.Fields);
+ command.addReferenceTypeID(classID);
+ command.setLength();
+
+ // send the command and receive reply
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+
+ // extract fieldIDs from the reply packet
+ try {
+ reply.resetPosition();
+
+ int declared = reply.getInt();
+ long[] fieldIDs = new long[declared];
+
+ int j = 0;
+ for (int i = 0; i < declared; i++ ) {
+ long fieldID = reply.getFieldID();
+ String name = reply.getString();
+ String signature = reply.getString();
+ int modBits = reply.getInt();
+
+ fieldIDs[i] = fieldID;
+ }
+ return fieldIDs;
+ } catch (BoundException e) {
+ log.complain("Unable to parse reply packet for ReferenceType.Fields command:\n\t"
+ + e);
+ log.complain("Received reply packet:\n"
+ + reply);
+ throw new Failure("Error occured while getting static fieldIDs for classID: " + classID);
+ }
+ }
+
+ /**
+ * Query debugee for values of the class fields.
+ */
+ JDWP.Value[] queryClassFieldValues(long classID, long fieldIDs[]) {
+ // compose ReferenceType.Fields command packet
+ int count = fieldIDs.length;
+ CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.GetValues);
+ command.addReferenceTypeID(classID);
+ command.addInt(count);
+ for (int i = 0; i < count; i++) {
+ command.addFieldID(fieldIDs[i]);
+ }
+ command.setLength();
+
+ // send the command and receive reply
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+
+ // extract values from the reply packet
+ try {
+ reply.resetPosition();
+
+ int valuesCount = reply.getInt();
+ JDWP.Value values[] = new JDWP.Value[valuesCount];
+ for (int i = 0; i < valuesCount; i++ ) {
+ JDWP.Value value = reply.getValue();
+ values[i] = value;
+ }
+ return values;
+ } catch (BoundException e) {
+ log.complain("Unable to parse reply packet for ReferenceType.GetValues command:\n\t"
+ + e);
+ log.complain("Received reply packet:\n"
+ + reply);
+ throw new Failure("Error occured while getting static fields values for classID: " + classID);
+ }
+ }
+
+ /**
+ * Query debuggee for objectID value of static class field.
+ */
+ long queryObjectID(long classID, String fieldName, byte tag) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != tag) {
+ throw new Failure("Wrong objectID tag received from field \"" + fieldName
+ + "\": " + value.getTag() + " (expected: " + tag + ")");
+ }
+
+ // extract threadID from the value
+ long objectID = ((Long)value.getValue()).longValue();
+ return objectID;
+ }
+
+ /**
+ * Perform testing JDWP command for specified classID.
+ */
+ void testCommand(long objectID, long fieldIDs[], JDWP.Value values[]) {
+ int count = fieldIDs.length;
+
+ // create command packet
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+
+ // add out data to the command packet
+ log.display(" objectID: " + objectID);
+ command.addObjectID(objectID);
+ log.display(" values: " + count);
+ command.addInt(count);
+ for (int i = 0; i < count; i++) {
+ log.display(" field #" + i +":");
+ log.display(" fieldID: " + fieldIDs[i]);
+ command.addFieldID(fieldIDs[i]);
+
+ JDWP.Value value = values[i];
+ JDWP.UntaggedValue untaggedValue =
+ new JDWP.UntaggedValue(value.getValue());
+ log.display(" untagged_value: " + untaggedValue.getValue());
+ command.addUntaggedValue(untaggedValue, value.getTag());
+ }
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet: " + e.getMessage());
+ success = false;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // no data to extract
+
+ // check for extra data in reply packet
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + "0x" + reply.toHexString(reply.currentDataPosition(), 4));
+ success = false;
+ }
+ }
+
+ /**
+ * Check confiramtion from debuggee that values are changed.
+ */
+ void checkValuesChanged() {
+ // send debugee signal RUN
+ log.display("Sending signal to debugee: " + RUN);
+ pipe.println(RUN);
+
+ // wait for DONE signal from debugee
+ log.display("Waiting for signal from debugee: " + DONE);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+
+ // check received signal
+ if (signal == null) {
+ throw new TestBug("<null> signal received from debugee: " + signal
+ + " (expected: " + DONE + ")");
+ } else if (signal.equals(DONE)) {
+ log.display("All fields values have been correctly set into debuggee VM");
+ } else if (signal.equals(ERROR)) {
+ log.complain("Not all fields values have been correctly set into debuggee VM");
+ success = false;
+ } else {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + DONE + ")");
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/SetValues/setvalues001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ObjectReference/SetValues/setvalues001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ObjectReference
+ * command: SetValues
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * the values are correctly set to debuggee class fields.
+ * Test consists of two compoments:
+ * debugger: setvalues001
+ * debuggee: setvalues001a
+ * To set values to the static fields of the tested class
+ * and check that they are set correctly, test defines
+ * following classes into debuggee VM:
+ * OriginalValuesClass - class with original values of static fields
+ * TargetValuesClass - class with target values of static fields
+ * TestedClass - tested class with tested fields to set values to
+ * ObjectClass - class with one static field for the tested object
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization messages.
+ * Next, debugger obtains classIDs for the tested class and class with
+ * the target values from debugee. It obtains also fieldIDs for thess
+ * classese and target values of the fields. It obtains also objectID
+ * as the value of a static field of the object class.
+ * Then, debugger creates command packet for SetValues command with the
+ * found objectID and list of fieldIDs as arguments, writes packet
+ * to the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and and checks that there is no data in the reply packet.
+ * Then debugger sends signal RUN to debuggee to ask it to verify
+ * new fields values of tested class. Debuggee compares these values
+ * with the original and target values and sends ERROR signal
+ * to debugger if the values was not set correctly.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ObjectReference.SetValues.setvalues001
+ * nsk.jdwp.ObjectReference.SetValues.setvalues001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ObjectReference.SetValues.setvalues001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ObjectReference/SetValues/setvalues001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,345 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ObjectReference.SetValues;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part of the test.
+ */
+public class setvalues001a {
+
+ public static final String OBJECT_FIELD_NAME = "object";
+
+ static ArgumentHandler argumentHandler = null;
+ static Log log = null;
+
+ public static void main(String args[]) {
+ setvalues001a _setvalues001a = new setvalues001a();
+ System.exit(setvalues001.JCK_STATUS_BASE + _setvalues001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ // make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // ensure tested class loaded
+ log.display("Creating object of all required classes");
+ OriginalValuesClass original = new OriginalValuesClass();
+ TargetValuesClass target = new TargetValuesClass();
+ ObjectClass.object = new TestedClass();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + setvalues001.READY);
+ pipe.println(setvalues001.READY);
+
+ // wait for signal RUN from debugeer
+ log.display("Waiting for signal from debugger: " + setvalues001.RUN);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+ // check received signal
+ if (signal == null || !signal.equals(setvalues001.RUN)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + setvalues001.RUN + ")");
+ log.display("Debugee FAILED");
+ return setvalues001.FAILED;
+ }
+
+ // check assigned values
+ if (checkValues(ObjectClass.object)) {
+ log.display("Sending signal to debugger: " + setvalues001.DONE);
+ pipe.println(setvalues001.DONE);
+ } else {
+ log.display("Sending signal to debugger: " + setvalues001.ERROR);
+ pipe.println(setvalues001.ERROR);
+ }
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + setvalues001.QUIT);
+ signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+ // check received signal
+ if (! signal.equals(setvalues001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + setvalues001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return setvalues001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return setvalues001.PASSED;
+ }
+
+ // check values of static fields for both classes
+ static boolean checkValues(TestedClass object) {
+ int different = 0;
+ log.display("Checking that values have been set correctly:");
+
+ // check value of the field
+ if (object.booleanValue != TargetValuesClass.booleanValue) {
+ different++;
+ log.complain(" booleanValue = " + object.booleanValue + "\n"
+ + " setting: " + OriginalValuesClass.booleanValue
+ + " -> " + TargetValuesClass.booleanValue);
+ if (object.booleanValue == OriginalValuesClass.booleanValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" booleanValue: " + OriginalValuesClass.booleanValue
+ + " -> " + TargetValuesClass.booleanValue);
+ }
+
+ // check value of the field
+ if (object.byteValue != TargetValuesClass.byteValue) {
+ different++;
+ log.complain(" byteValue = " + object.byteValue + "\n"
+ + " setting: " + OriginalValuesClass.byteValue
+ + " -> " + TargetValuesClass.byteValue);
+ if (object.byteValue == OriginalValuesClass.byteValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" byteValue: " + OriginalValuesClass.byteValue
+ + " -> " + TargetValuesClass.byteValue);
+ }
+
+ // check value of the field
+ if (object.charValue != TargetValuesClass.charValue) {
+ different++;
+ log.complain(" charValue = " + object.charValue + "\n"
+ + " setting: " + OriginalValuesClass.charValue
+ + " -> " + TargetValuesClass.charValue);
+ if (object.charValue == OriginalValuesClass.charValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" charValue: " + OriginalValuesClass.charValue
+ + " -> " + TargetValuesClass.charValue);
+ }
+
+ // check value of the field
+ if (object.intValue != TargetValuesClass.intValue) {
+ different++;
+ log.complain(" intValue = " + object.intValue + "\n"
+ + " setting: " + OriginalValuesClass.intValue
+ + " -> " + TargetValuesClass.intValue);
+ if (object.intValue == OriginalValuesClass.intValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" intValue: " + OriginalValuesClass.intValue
+ + " -> " + TargetValuesClass.intValue);
+ }
+
+ // check value of the field
+ if (object.shortValue != TargetValuesClass.shortValue) {
+ different++;
+ log.complain(" shortValue = " + object.shortValue + "\n"
+ + " setting: " + OriginalValuesClass.shortValue
+ + " -> " + TargetValuesClass.shortValue);
+ if (object.shortValue == OriginalValuesClass.shortValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" shortValue: " + OriginalValuesClass.shortValue
+ + " -> " + TargetValuesClass.shortValue);
+ }
+
+ // check value of the field
+ if (object.longValue != TargetValuesClass.longValue) {
+ different++;
+ log.complain(" longValue = " + object.longValue + "\n"
+ + " setting: " + OriginalValuesClass.longValue
+ + " -> " + TargetValuesClass.longValue);
+ if (object.longValue == OriginalValuesClass.longValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" longValue: " + OriginalValuesClass.longValue
+ + " -> " + TargetValuesClass.longValue);
+ }
+
+ // check value of the field
+ if (object.floatValue != TargetValuesClass.floatValue) {
+ different++;
+ log.complain(" floatValue = " + object.floatValue + "\n"
+ + " setting: " + OriginalValuesClass.floatValue
+ + " -> " + TargetValuesClass.floatValue);
+ if (object.floatValue == OriginalValuesClass.floatValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" floatValue: " + OriginalValuesClass.floatValue
+ + " -> " + TargetValuesClass.floatValue);
+ }
+
+ // check value of the field
+ if (object.doubleValue != TargetValuesClass.doubleValue) {
+ different++;
+ log.complain(" doubleValue = " + object.doubleValue + "\n"
+ + " setting: " + OriginalValuesClass.doubleValue
+ + " -> " + TargetValuesClass.doubleValue);
+ if (object.doubleValue == OriginalValuesClass.doubleValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" doubleValue: " + OriginalValuesClass.doubleValue
+ + " -> " + TargetValuesClass.doubleValue);
+ }
+
+ // check value of the field
+ if (object.stringValue != TargetValuesClass.stringValue) {
+ different++;
+ log.complain(" stringValue = " + object.stringValue + "\n"
+ + " setting: " + OriginalValuesClass.stringValue
+ + " -> " + TargetValuesClass.stringValue);
+ if (object.stringValue == OriginalValuesClass.stringValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" stringValue: " + OriginalValuesClass.stringValue
+ + " -> " + TargetValuesClass.stringValue);
+ }
+
+ // check value of the field
+ if (object.objectValue != TargetValuesClass.objectValue) {
+ different++;
+ log.complain(" objectValue = " + object.objectValue + "\n"
+ + " setting: " + OriginalValuesClass.objectValue
+ + " -> " + TargetValuesClass.objectValue);
+ if (object.objectValue == OriginalValuesClass.objectValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" objectValue: " + OriginalValuesClass.objectValue
+ + " -> " + TargetValuesClass.objectValue);
+ }
+
+/*
+ // check value of the field
+ if (object.Value != TargetValuesClass.Value) {
+ different++;
+ log.complain(" Value = " + object.Value + "\n"
+ + " setting: " + OriginalValuesClass.Value
+ + " -> " + TargetValuesClass.Value);
+ if (object.Value == OriginalValuesClass.Value) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" Value: " + OriginalValuesClass.Value
+ + " -> " + TargetValuesClass.Value);
+ }
+*/
+
+ // check taht no any changed value differs from target
+ if (different > 0) {
+ log.complain("Values of " + different + " fields have not been set correctly");
+ return false;
+ }
+
+ log.display("Values of all fields have been set correctly");
+ return true;
+ }
+
+ // class with the original values of static fields
+ public static class OriginalValuesClass {
+ static final boolean booleanValue = true;
+ static final byte byteValue = (byte)0x01;
+ static final char charValue = 'Z';
+ static final int intValue = 100;
+ static final short shortValue = (short)10;
+ static final long longValue = (long)1000000;
+ static final float floatValue = (float)3.14;
+ static final double doubleValue = (double)2.8e-12;
+ static final String stringValue = "text";
+ static final Object objectValue = new OriginalValuesClass();
+ }
+
+ // class with the original values of static fields
+ public static class TargetValuesClass {
+ static final boolean booleanValue = false;
+ static final byte byteValue = (byte)0x0F;
+ static final char charValue = 'A';
+ static final int intValue = 999;
+ static final short shortValue = (short)88;
+ static final long longValue = (long)11111111;
+ static final float floatValue = (float)7.19;
+ static final double doubleValue = (double)4.6e24;
+ static final String stringValue = "new text";
+ static final Object objectValue = new TargetValuesClass();
+ }
+
+ // tested class with own static fields values
+ public static class TestedClass {
+ private boolean booleanValue = OriginalValuesClass.booleanValue;
+ private byte byteValue = OriginalValuesClass.byteValue;
+ protected char charValue = OriginalValuesClass.charValue;
+ protected int intValue = OriginalValuesClass.intValue;
+ public short shortValue = OriginalValuesClass.shortValue;
+ public long longValue = OriginalValuesClass.longValue;
+ float floatValue = OriginalValuesClass.floatValue;
+ double doubleValue = OriginalValuesClass.doubleValue;
+ String stringValue = OriginalValuesClass.stringValue;
+ Object objectValue = OriginalValuesClass.objectValue;
+ }
+
+ // class with static field with the tested object
+ public static class ObjectClass {
+ // static field with the tested object
+ public static TestedClass object = null;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassLoader/classloader001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.ClassLoader;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class classloader001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.ReferenceType.ClassLoader";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "classloader001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "ReferenceType.ClassLoader";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ReferenceType.ClassLoader;
+
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new classloader001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ try {
+ long typeID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+
+ // begin test of JDWP command
+
+ log.display("Create command " + JDWP_COMMAND_NAME
+ + " with ReferenceTypeID: " + typeID);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addReferenceTypeID(typeID);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ long classLoaderID = reply.getObjectID();
+ log.display(" classLoaderID: " + classLoaderID);
+
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ success = false;
+ } else {
+ log.display("Reply packet parsed successfully");
+ }
+
+ // end test of JDWP command
+
+ } catch (Exception e) {
+ log.complain("Caught exception while testing JDWP command: " + e);
+ success = false;
+ } finally {
+
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception while connecting to debugee: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Caught unexpected exception while starting the test: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassLoader/classloader001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ReferenceType/ClassLoader/classloader001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ReferenceType
+ * command: ClassLoader
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: classloader001
+ * debuggee: classloader001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with execution commands.
+ * Next, debugger obtains referenceTypeID for debuggee class, which
+ * will be used to test JDWP command.
+ * Then, debugger creates command packet for ClassLoader command with the
+ * found referenceTypeID as an argument, writes packet to the transport
+ * channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts classLoaderID.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ReferenceType.ClassLoader.classloader001
+ * nsk.jdwp.ReferenceType.ClassLoader.classloader001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ReferenceType.ClassLoader.classloader001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassLoader/classloader001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.ClassLoader;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class classloader001a {
+
+ public static void main(String args[]) {
+ classloader001a _classloader001a = new classloader001a();
+ System.exit(classloader001.JCK_STATUS_BASE + _classloader001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return classloader001.PASSED;
+ }
+
+ static public class TestedClass {
+ int foo = 0;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassObject/classobj001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.ClassObject;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class classobj001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.ReferenceType.ClassObject";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "classobj001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "ReferenceType.ClassObject";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ReferenceType.ClassObject;
+
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new classobj001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ try {
+ long typeID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+
+ // begin test of JDWP command
+
+ log.display("Create command " + JDWP_COMMAND_NAME
+ + " with ReferenceTypeID: " + typeID);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addReferenceTypeID(typeID);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ long classObjectID = reply.getObjectID();
+ log.display(" classObjectID: " + classObjectID);
+
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ success = false;
+ } else {
+ log.display("Reply packet parsed successfully");
+ }
+
+ // end test of JDWP command
+
+ } catch (Exception e) {
+
+ log.complain("Caught exception while testing JDWP command: " + e);
+ success = false;
+
+ } finally {
+
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception while connecting to debugee: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Caught unexpected exception while starting the test: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassObject/classobj001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ReferenceType/ClassObject/classobj001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ReferenceType
+ * command: ClassObject
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: classobj001
+ * debuggee: classobj001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with execution commands.
+ * Next, debugger obtains referenceTypeID for debuggee class, which
+ * will be used to test JDWP command.
+ * Then, debugger creates command packet for ClassObject command with the
+ * found referenceTypeID as an argument, writes packet to the transport
+ * channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts classObjectID.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ReferenceType.ClassObject.classobj001
+ * nsk.jdwp.ReferenceType.ClassObject.classobj001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ReferenceType.ClassObject.classobj001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/ClassObject/classobj001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.ClassObject;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class classobj001a {
+
+ public static void main(String args[]) {
+ classobj001a _classobj001a = new classobj001a();
+ System.exit(classobj001.JCK_STATUS_BASE + _classobj001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return classobj001.PASSED;
+ }
+
+ static public class TestedClass {
+ int foo = 0;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Fields/fields001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.Fields;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class fields001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.ReferenceType.Fields";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "fields001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "ReferenceType.Fields";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ReferenceType.Fields;
+
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ static final String[][] fields = {
+ {"byteField", "B"},
+ {"booleanField", "Z"},
+ {"charField", "C"},
+ {"shortField", "S"},
+ {"intField", "I"},
+ {"longField", "J"},
+ {"floatField", "F"},
+ {"doubleField", "D"},
+ {"stringField", "Ljava/lang/String;"},
+ {"objectField", TESTED_CLASS_SIGNATURE},
+ {"intArrayField", "[I"}
+ };
+ static final int DECLARED_FIELDS = fields.length;
+ static final int FIELD_MODIFIER_FLAGS = JDWP.ModifierFlag.PUBLIC;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new fields001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ try {
+
+ long typeID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+
+ // begin test of JDWP command
+
+ log.display("Create command " + JDWP_COMMAND_NAME
+ + " with ReferenceTypeID: " + typeID);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addReferenceTypeID(typeID);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ long declared = reply.getInt();
+ log.display(" declared: " + declared);
+
+ if (declared != DECLARED_FIELDS) {
+ log.complain("Unexpected number of declared fields in the reply packet :" + declared
+ + " (expected: " + DECLARED_FIELDS + ")");
+ success = false;
+ }
+
+ for (int i = 0; i < declared; i++ ) {
+
+ log.display(" field #" + i);
+
+ long fieldID = reply.getFieldID();
+ log.display(" fieldID: " + fieldID);
+
+ String name = reply.getString();
+ log.display(" name: " + name);
+ if (! name.equals(fields[i][0])) {
+ log.complain("Unexpected name of field #" + i + " in the reply packet: " + name
+ + " (expected: " + fields[i][0] + ")");
+ success = false;
+ }
+
+ String signature = reply.getString();
+ log.display(" signature: " + signature);
+ if (! signature.equals(fields[i][1])) {
+ log.complain("Unexpected type signature of field #" + i + " in the reply packet: " + signature
+ + " (expected: " + fields[i][1] + ")");
+ success = false;
+ }
+
+ int modBits = reply.getInt();
+ String modBitsString = "0x" + Packet.toHexString(modBits, 8);
+ log.display(" modBits: " + modBitsString);
+ modBits &= JDWP.ModifierFlag.FIELD_MASK;
+ if (modBits != FIELD_MODIFIER_FLAGS) {
+ String expectedModBitsString = "0x" + Packet.toHexString(FIELD_MODIFIER_FLAGS, 8);
+ log.complain("Unexpected modifier flag of field #" + i + " in the reply packet: " + modBitsString
+ + " (expected: " + expectedModBitsString + ")");
+ success = false;
+ }
+
+ }
+
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ success = false;
+ } else {
+ log.display("Reply packet parsed successfully");
+ }
+
+ // end test of JDWP command
+
+ } catch (Exception e) {
+ log.complain("Caught exception while testing JDWP command: " + e);
+ success = false;
+ } finally {
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception while communicating with debugee: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Caught unexpected exception while starting the test: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Fields/fields001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ReferenceType/Fields/fields001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ReferenceType
+ * command: Fields
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * reply contains expected set of fields.
+ * Test consists of two compoments:
+ * debugger: fields001
+ * debuggee: fields001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with execution commands.
+ * Next, debugger obtains referenceTypeID for debuggee class, which
+ * will be used to test JDWP command.
+ * Then, debugger creates command packet for Fields command with the
+ * found referenceTypeID as an argument, writes packet to the transport
+ * channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts fields info. Test checks that all fields are equal to
+ * expected.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ReferenceType.Fields.fields001
+ * nsk.jdwp.ReferenceType.Fields.fields001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ReferenceType.Fields.fields001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Fields/fields001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.Fields;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class fields001a {
+
+ public static void main(String args[]) {
+ fields001a _fields001a = new fields001a();
+ System.exit(fields001.JCK_STATUS_BASE + _fields001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return fields001.PASSED;
+ }
+
+ static class TestedClass {
+ public byte byteField = (byte) 0xEE;
+ public boolean booleanField = false;
+ public char charField = 'Z';
+ public short shortField = 10;
+ public int intField = 100;
+ public long longField = 1000000;
+ public float floatField = (float) 3.14;
+ public double doubleField = 2.48e-10;
+ public String stringField = "stringFieldValue";
+ public TestedClass objectField = this;
+ public int[] intArrayField = {intField};
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2003, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.FieldsWithGeneric;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * This test checks that the JDWP command <code>FieldsWithGeneric</code>
+ * from the <code>ReferenceType</code> command set returns generic signature
+ * information properly.<br>
+ * Debuggee part of the test contains several tested fields. Some of them
+ * are generic including the inherited fields. Debugger part obtains
+ * information for each field in a reference type of a tested class.
+ * Proper generic signature should be returned for the generic fields, or
+ * an empty string for non-generic ones. Information for the inherited
+ * fields should not be returned.
+ */
+public class fldwithgeneric001 {
+ static final String DEBUGGEE_CLASS =
+ "nsk.jdwp.ReferenceType.FieldsWithGeneric.fldwithgeneric001t";
+ static final String TESTED_CLASS_SIGNATURE =
+ "Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001a;";
+
+ static final String JDWP_COMMAND_NAME = "ReferenceType.FieldsWithGeneric";
+ static final int JDWP_COMMAND_ID =
+ JDWP.Command.ReferenceType.FieldsWithGeneric;
+
+ static final String COMMAND_READY = "ready";
+ static final String COMMAND_QUIT = "quit";
+
+ static final String[][] fields = {
+ {"_fldwithgeneric001St",
+ "Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001;",
+ "NULL"},
+
+ {"_fldwithgeneric001b",
+ "Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001b;",
+ "Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001b<Ljava/lang/String;>;"},
+ {"_fldwithgeneric001bSt",
+ "Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001b;",
+ "Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001b<Ljava/lang/String;>;"},
+
+ {"_fldwithgeneric001c",
+ "Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001c;",
+ "Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001c<Ljava/lang/Boolean;Ljava/lang/Integer;>;"},
+ {"_fldwithgeneric001cSt",
+ "Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001c;",
+ "Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001c<Ljava/lang/Boolean;Ljava/lang/Integer;>;"},
+
+ {"_fldwithgeneric001e",
+ "Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001e;",
+ "NULL"},
+ {"_fldwithgeneric001eSt",
+ "Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001e;",
+ "NULL"},
+
+ {"_fldwithgeneric001if",
+ "Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001if;",
+ "Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001if<Ljava/lang/Object;>;"},
+ {"_fldwithgeneric001ifSt",
+ "Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001if;",
+ "Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001if<Ljava/lang/Object;>;"},
+
+ {"_fldwithgeneric001g",
+ "Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001g;",
+ "Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001g<Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001f;>;"},
+ {"_fldwithgeneric001gSt",
+ "Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001g;",
+ "Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001g<Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001f;>;"},
+
+ {"_fldwithgeneric001gArr",
+ "[Lnsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001g;",
+ "NULL"}
+ };
+
+ static final int FLDS_NUM = fields.length;
+
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + Consts.JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new fldwithgeneric001().runThis(argv, out);
+ }
+
+ public int runThis(String argv[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+ boolean result = true;
+
+ try {
+ Binder binder = new Binder(argumentHandler, log);
+
+ log.display("Starting debuggee VM ...");
+ Debugee debuggee = binder.bindToDebugee(DEBUGGEE_CLASS);
+
+ Transport transport = debuggee.getTransport();
+ IOPipe pipe = debuggee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event ...");
+ debuggee.waitForVMInit();
+
+ log.display("Querying for IDSizes ...");
+ debuggee.queryForIDSizes();
+
+ log.display("Resuming debuggee VM ...");
+ debuggee.resume();
+
+ log.display("Waiting for command: " + COMMAND_READY
+ + " ...");
+ String cmd = pipe.readln();
+ log.display(" ... Received command: " + cmd);
+
+ try {
+ long typeID = debuggee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+
+ /////// begin test of JDWP command
+ log.display("\nCreate command " + JDWP_COMMAND_NAME
+ + " with ReferenceTypeID: " + typeID);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addReferenceTypeID(typeID);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("\nWaiting for reply packet ...");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display(" ... Reply packet received:\n" + reply);
+
+ log.display("\nChecking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+/* parsing of reply data:
+ int declared - Number of declared fields
+
+ ---- Repeated 'declared' times:
+ fieldID fieldID - Field ID
+ string nam - The name of the field
+ string signature - The JNI signature of the field.
+ string genericSignature - The generic signature of the field,
+ or an empty string if there is none.
+ int modBits - The modifier bit flags (also known as access flags)
+ ----
+*/
+ log.display("\nParsing reply packet:");
+ reply.resetPosition();
+
+ long declared = reply.getInt();
+ log.display("\tdeclared: " + declared);
+
+ if (declared != FLDS_NUM) {
+ log.complain("TEST FAILED: Unexpected number of declared fields in the reply packet:"
+ + "\n\tGot: " + declared
+ + "\n\tExpected: " + FLDS_NUM + "\n");
+ result = false;
+ }
+
+ for (int i=0; i<declared; i++) {
+ log.display("\t>>> field #" + i);
+
+ long fieldID = reply.getFieldID();
+ log.display("\t\tfieldID: " + fieldID);
+
+ String name = reply.getString();
+ log.display("\t\tname: " + name);
+ if (!name.equals(fields[i][0])) {
+ log.complain("TEST FAILED: Unexpected name of field #" + i
+ + " in the reply packet:"
+ + "\n\tGot: " + name
+ + "\n\tExpected: " + fields[i][0] + "\n");
+ result = false;
+ }
+
+ String signature = reply.getString();
+ log.display("\t\tsignature: " + signature);
+ if (!signature.equals(fields[i][1])) {
+ log.complain("TEST FAILED: Unexpected type signature of field #" + i
+ + " in the reply packet:"
+ + "\n\tGot: " + signature
+ + "\n\tExpected: " + fields[i][1] + "\n");
+ result = false;
+ }
+
+ String genSignature = reply.getString();
+ log.display("\t\tgeneric signature: " + genSignature);
+ if (genSignature.length() == 0) // a non-generic field
+ genSignature = "NULL";
+ if (!genSignature.equals(fields[i][2])) {
+ log.complain("TEST FAILED: Unexpected generic signature of field #" + i
+ + " in the reply packet:"
+ + "\n\tGot: " + genSignature
+ + "\n\tExpected: " + fields[i][2] + "\n");
+ result = false;
+ }
+
+ int modBits = reply.getInt();
+ String modBitsString = "0x" + Packet.toHexString(modBits, 8);
+ log.display("\t\tmodBits: " + modBitsString);
+ }
+
+ if (!reply.isParsed()) {
+ log.complain("TEST FAILED: Extra trailing bytes found in reply packet at: "
+ + reply.currentPosition());
+ result = false;
+ } else
+ log.display("\nReply packet parsed");
+ /////// end test of JDWP command
+
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught exception while testing JDWP command: "
+ + e);
+ result = false;
+ } finally {
+ log.display("Sending command: " + COMMAND_QUIT + " ...");
+ pipe.println(COMMAND_QUIT);
+
+ log.display("Waiting for debuggee exits ...");
+ int code = debuggee.waitFor();
+ if (code == Consts.JCK_STATUS_BASE + Consts.TEST_PASSED) {
+ log.display(" ... Debuggee PASSED with the exit code: "
+ + code);
+ } else {
+ log.complain(" ... Debuggee FAILED with the exit code: "
+ + code);
+ result = false;
+ }
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while communicating with debugee: "
+ + e);
+ result = false;
+ }
+
+ if (!result)
+ return Consts.TEST_FAILED;
+
+ return Consts.TEST_PASSED;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * JDWP command set: ReferenceType
+ * JDWP command: FieldsWithGeneric
+ * It checks that the command returns generic signature information
+ * properly.
+ * Debuggee part of the test contains several tested fields. Some of them
+ * are generic including the inherited fields. Debugger part obtains
+ * information for each field in a reference type of a tested class.
+ * Proper generic signature should be returned for the generic fields, or
+ * NULL for non-generic ones. Information for the inherited fields should
+ * not be returned.
+ * COMMENTS
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ReferenceType.FieldsWithGeneric.fldwithgeneric001
+ * nsk.jdwp.ReferenceType.FieldsWithGeneric.fldwithgeneric001t
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ReferenceType.FieldsWithGeneric.fldwithgeneric001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/FieldsWithGeneric/fldwithgeneric001t.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2003, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.FieldsWithGeneric;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class fldwithgeneric001t {
+ public static void main(String args[]) {
+ ArgumentHandler argHandler = new ArgumentHandler(args);
+ Log log = new Log(System.err, argHandler);
+ IOPipe pipe = argHandler.createDebugeeIOPipe(log);
+
+ // load a tested class
+ fldwithgeneric001a _fldwithgeneric001a =
+ new fldwithgeneric001a();
+
+ log.display("Debuggee VM started\nSending command: "
+ + fldwithgeneric001.COMMAND_READY);
+ pipe.println(fldwithgeneric001.COMMAND_READY);
+
+ log.display("Waiting for command: "
+ + fldwithgeneric001.COMMAND_QUIT + " ...");
+ String cmd = pipe.readln();
+ log.display(" ... Received command: " + cmd
+ + "\nDebuggee is exiting ...");
+
+ System.exit(Consts.JCK_STATUS_BASE + Consts.TEST_PASSED);
+ }
+}
+
+/*
+ * Dummy classes used only for verifying generic signature information
+ * in a debugger.
+ */
+
+class fldwithgeneric001b<L extends String> {}
+
+class fldwithgeneric001c<A, B extends Integer> {}
+
+interface fldwithgeneric001if<I> {}
+
+class fldwithgeneric001d<T> implements fldwithgeneric001if<T> {}
+
+class fldwithgeneric001e {}
+
+class fldwithgeneric001f extends fldwithgeneric001e implements fldwithgeneric001if {}
+
+class fldwithgeneric001g<E extends fldwithgeneric001e & fldwithgeneric001if> {}
+
+class fldwithgeneric001h {
+ // dummy fields to be inherited. They must not be included into
+ // information for reference type fields.
+ public fldwithgeneric001 _fldwithgeneric001h =
+ new fldwithgeneric001();
+ public fldwithgeneric001b<String> _fldwithgeneric001bh =
+ new fldwithgeneric001b<String>();
+}
+
+class fldwithgeneric001a extends fldwithgeneric001h {
+ // dummy fields used for testing
+ public static fldwithgeneric001 _fldwithgeneric001St =
+ new fldwithgeneric001();
+ fldwithgeneric001b<String> _fldwithgeneric001b =
+ new fldwithgeneric001b<String>();
+ static fldwithgeneric001b<String> _fldwithgeneric001bSt =
+ new fldwithgeneric001b<String>();
+ fldwithgeneric001c<Boolean, Integer> _fldwithgeneric001c =
+ new fldwithgeneric001c<Boolean, Integer>();
+ static fldwithgeneric001c<Boolean, Integer> _fldwithgeneric001cSt =
+ new fldwithgeneric001c<Boolean, Integer>();
+ fldwithgeneric001e _fldwithgeneric001e =
+ new fldwithgeneric001e();
+ static fldwithgeneric001e _fldwithgeneric001eSt =
+ new fldwithgeneric001e();
+ fldwithgeneric001if<Object> _fldwithgeneric001if =
+ new fldwithgeneric001d<Object>();
+ static fldwithgeneric001if<Object> _fldwithgeneric001ifSt =
+ new fldwithgeneric001d<Object>();
+ fldwithgeneric001g<fldwithgeneric001f> _fldwithgeneric001g =
+ new fldwithgeneric001g<fldwithgeneric001f>();
+ static fldwithgeneric001g<fldwithgeneric001f> _fldwithgeneric001gSt =
+ new fldwithgeneric001g<fldwithgeneric001f>();
+ fldwithgeneric001g[] _fldwithgeneric001gArr =
+ new fldwithgeneric001g[]{};
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/GetValues/getvalues001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,402 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.GetValues;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ReferenceType.GetValues.
+ *
+ * See getvalues001.README for description of test execution.
+ *
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class getvalues001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ReferenceType.GetValues";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "getvalues001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ReferenceType.GetValues";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ReferenceType.GetValues;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // nested classes names and signatures array
+ static final Object fields [][] = {
+ { "booleanValue", "boolean", new Boolean(true), "own"},
+ { "byteValue", "byte", new Byte((byte)0x0F), "own"},
+ { "charValue", "char", new Character('Z'), "own"},
+ { "intValue", "int", new Integer(100), "own"},
+ { "shortValue", "short", new Short((short)10), "own"},
+ { "longValue", "long", new Long((long)1000000), "own"},
+ { "floatValue", "float", new Float((float)3.14), "own"},
+ { "doubleValue", "double", new Double((double)2.8e-12), "own"},
+ { "objectValue", "objectID", new Long((long)0), "own"},
+
+ };
+ static final int FIELDS_COUNT = fields.length;
+
+ // field ID's for tested class static fields
+ static final long[] fieldIDs = new long[FIELDS_COUNT];
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new getvalues001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debugee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debugee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debugee for TypeID of tested class
+ log.display("Getting ReferenceTypeID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long typeID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got TypeID: " + typeID);
+
+ // query debugee for fieldIDs of tested class static fields
+ log.display("Getting fieldIDs for static fields of the tested class");
+ queryClassFieldIDs(typeID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(typeID);
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ e.printStackTrace(out);
+ success = false;
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception:\n" + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received form debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debugee for TypeIDs for nested classes from nested_classes array
+ * and put them into nested_classesIDs array.
+ */
+ void queryClassFieldIDs(long typeID) {
+ for (int i = 0; i < FIELDS_COUNT; i++) {
+ fieldIDs[i] = 0;
+ }
+
+ int count = 0;
+ try {
+ CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.Fields);
+ command.addReferenceTypeID(typeID);
+ command.setLength();
+
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+ reply.resetPosition();
+
+ long declared = reply.getInt();
+ log.display(" declared: " + declared);
+
+ for (int i = 0; i < declared; i++ ) {
+ long fieldID = reply.getFieldID();
+ String name = reply.getString();
+ String signature = reply.getString();
+ int modBits = reply.getInt();
+
+ boolean found = false;
+ for (int j = 0; j < FIELDS_COUNT; j++) {
+ if (fields[j][0].equals(name)) {
+ if (fieldIDs[j] != 0) {
+ throw new Failure("Duplicated field name of the tested class returned: " + name);
+ }
+ fieldIDs[j] = fieldID;
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ throw new Failure("Unexpected field of the tested class returned: " + name);
+ }
+ }
+
+ if (declared < FIELDS_COUNT) {
+ throw new Failure("Too few fields of the tested class returned: " + declared
+ + " (expected: " + FIELDS_COUNT + ")");
+ }
+
+ if (declared > FIELDS_COUNT) {
+ throw new Failure("Too many fields of the tested class returned: " + declared
+ + " (expected: " + FIELDS_COUNT + ")");
+ }
+
+ if (!reply.isParsed()) {
+ throw new Failure("Extra trailing bytes found in the reply packet at: "
+ + reply.currentPosition());
+ }
+
+ } catch (BoundException e) {
+ throw new Failure("Unable to extract field IDs from the reply packet:\n"
+ + e.getMessage());
+ }
+ }
+
+ /**
+ * Extract and check i-th value from the reply packet.
+ */
+ void checkValue(int i, JDWP.Value value) {
+ if (!fields[i][2].equals(value.getValue())) {
+ log.complain("Unexpected value for " + i + " field in reply packet: " + value
+ + " (expected value: " + fields[i][2] + ")");
+ success = false;
+ }
+ }
+
+ /**
+ * Perform testing JDWP command for specified TypeID.
+ */
+ void testCommand(long typeID) {
+ // create command packet
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+
+ // add out data to the command packet
+ log.display(" refType: " + typeID);
+ command.addReferenceTypeID(typeID);
+ log.display(" fields: " + FIELDS_COUNT);
+ command.addInt(FIELDS_COUNT);
+ for (int i = 0; i < FIELDS_COUNT; i++) {
+ log.display(" #" + i +": fieldID: " + fieldIDs[i]);
+ command.addFieldID(fieldIDs[i]);
+ }
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet: " + e.getMessage());
+ success = false;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract and check number of values
+ int values = 0;
+ try {
+ values = reply.getInt();
+ log.display(" values: " + values);
+
+ if (values != FIELDS_COUNT) {
+ log.complain("Unexpected number of values in the reply packet:" + values
+ + " (expected: " + FIELDS_COUNT + ")");
+ success = false;
+ }
+ } catch (BoundException e) {
+ log.complain("Unable to extract number of values form reply packet:\n" + e.getMessage());
+ success = false;
+ }
+
+ // extract and check TypeID for each nested class
+ for (int i = 0; i < values; i++ ) {
+ log.display(" value #" + i + " (field: " + fields[i][0] + ")");
+
+ // extract TypeTag byte
+ JDWP.Value value = null;
+ try {
+ value = reply.getValue();
+ log.display(" value: " + value);
+ } catch (BoundException e) {
+ log.complain("Unable to extract type tag of " + i + " value:\n" + e.getMessage());
+ success = false;
+ break;
+ }
+
+ // extract and check value by known type tag
+ checkValue(i, value);
+ }
+
+ // check for extra data in reply packet
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + "0x" + reply.toHexString(reply.currentDataPosition(), 4));
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/GetValues/getvalues001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ReferenceType/GetValues/getvalues001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ReferenceType
+ * command: GetValues
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * the returned values of requested fields are equal to
+ * the expected ones.
+ * Test consists of two compoments:
+ * debugger: getvalues001
+ * debuggee: getvalues001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization messages.
+ * Next, debugger obtains ReferenceTypeIDs for the tested class from
+ * debugee, and obtains also fieldIDs for all tested fields of this class.
+ * Then, debugger creates command packet for GetValues command with the
+ * found referenceTypeID and list of fieldIDs as arguments, writes packet
+ * to the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts values of the requested fields. Also test checks
+ * that extracted values are equal to the expected ones.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ReferenceType.GetValues.getvalues001
+ * nsk.jdwp.ReferenceType.GetValues.getvalues001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ReferenceType.GetValues.getvalues001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/GetValues/getvalues001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.GetValues;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class getvalues001a {
+
+ public static void main(String args[]) {
+ getvalues001a _getvalues001a = new getvalues001a();
+ System.exit(getvalues001.JCK_STATUS_BASE + _getvalues001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // meke communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // ensure tested class loaded
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + getvalues001.READY);
+ pipe.println(getvalues001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + getvalues001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (! signal.equals(getvalues001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + getvalues001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return getvalues001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return getvalues001.PASSED;
+ }
+
+ // tested class with own static fields values
+ public static class TestedClass {
+ private static boolean booleanValue = true;
+ private static final byte byteValue = (byte)0x0F;
+ protected static char charValue = 'Z';
+ protected static final int intValue = 100;
+ public static short shortValue = (short)10;
+ public static final long longValue = (long)1000000;
+ static float floatValue = (float)3.14;
+ static final double doubleValue = (double)2.8e-12;
+ static TestedClass objectValue = null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Instances/instances001/instances001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2007, 2018, 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 converted from VM Testbase nsk/jdwp/ReferenceType/Instances/instances001.
+ * VM Testbase keywords: [quick, jpda, jdwp, feature_jdk6_jpda, vm6, monitoring]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ReferenceType
+ * command: Instances
+ * Test checks that debuggee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: instances001
+ * debuggee: instances001a
+ * Debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with execution commands.
+ * For maxInstances in [1, 0, Interger.MAX_VALUE]
+ * do
+ * Debugger obtains referenceTypeID for 'nsk.share.jdwp.ReferenceType.instances.instances001.TestClass'.
+ * Then, debugger creates command packet for Instances command with the
+ * found referenceTypeID and maxInstances as an arguments, writes packet to the transport
+ * channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts number of instances and instance's ids.
+ * Debugger checks that received number of instances is correct:
+ * - if maxInstances=1 only 1 instance should be returned
+ * - if maxInstances=0 or maxInstances=Integer.MAX_VALUE all instances should be returned
+ * done
+ * Also, test performs checks for cases when incorrect data is sent in command.
+ * Following cases are tested:
+ * - create command with maxInstances < 0, expect ILLEGAL_ARGUMENT error
+ * - create command with typeID = -1, expect INVALID_OBJECT error
+ * - create command with threadID instead of referenceTypeID, expect INVALID_CLASS error
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ReferenceType.Instances.instances001.instances001
+ * @run main/othervm/native PropertyResolvingWrapper
+ * nsk.jdwp.ReferenceType.Instances.instances001.instances001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="-Xmx128M ${test.vm.opts} ${test.java.opts}"
+ */
+
+package nsk.jdwp.ReferenceType.Instances.instances001;
+
+import java.io.*;
+import nsk.share.Consts;
+import nsk.share.jdwp.*;
+import nsk.share.jpda.AbstractDebuggeeTest;
+
+public class instances001 extends TestDebuggerType1 {
+ protected String getDebugeeClassName() {
+ return nsk.jdwp.ReferenceType.Instances.instances001.instances001a.class.getName();
+ }
+
+ public static void main(String argv[]) {
+ System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new instances001().runIt(argv, out);
+ }
+
+ private void testClass(long typeID, int maxInstances, int expectedInstances, boolean expectError, int errorCode) {
+ try {
+ int JDWP_COMMAND_ID = JDWP.Command.ReferenceType.Instances;
+
+ log.display("Create command: " + JDWP.commandNames.get(JDWP_COMMAND_ID));
+ log.display("referenceType = " + typeID);
+ log.display("maxInstances = " + maxInstances);
+
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addReferenceTypeID(typeID);
+ command.addInt(maxInstances);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ ReplyPacket reply;
+
+ reply = getReply(command, expectError, errorCode);
+
+ if (expectError)
+ return;
+
+ int instances = reply.getInt();
+ log.display("instances = " + instances);
+
+ // check that correct value of 'instances' was received
+ if (instances != expectedInstances) {
+ setSuccess(false);
+ log.complain("Unexpected 'instances' value: " + instances + ", expected is " + expectedInstances);
+ }
+
+ for (int i = 0; i < instances; i++) {
+ JDWP.Value value = reply.getValue();
+ log.display("tagged-ObjectID = " + value);
+ }
+
+ if (!reply.isParsed()) {
+ setSuccess(false);
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ }
+ } catch (Exception e) {
+ setSuccess(false);
+ log.complain("Caught exception while testing JDWP command: " + e);
+ e.printStackTrace(log.getOutStream());
+ }
+ }
+
+ public void doTest() {
+ // force GC in debuggee VM to avoid collection of weak references during test execution
+ forceGC();
+ pipe.println(instances001a.COMMAND_CREATE_TEST_INSTANCES);
+
+ if (!isDebuggeeReady())
+ return;
+
+ int expectedInstances = instances001a.expectedCount;
+
+ String testClassName = nsk.jdwp.ReferenceType.Instances.instances001.TestClass.class.getName();
+
+ long typeID = debuggee.getReferenceTypeID(createTypeSignature(testClassName));
+
+
+ // create command with maxInstances=1, only 1 instance should be returned
+ testClass(typeID, 1, 1, false, 0);
+ // create command with maxInstances=0, all instances should be returned
+ testClass(typeID, 0, expectedInstances, false, 0);
+ // create command with maxInstances=Integer.MAX_VALUE, all instances should be returned
+ testClass(typeID, Integer.MAX_VALUE, expectedInstances, false, 0);
+
+ // create command with maxInstances < 0, expect ILLEGAL_ARGUMENT error
+ testClass(typeID, -1, expectedInstances, true, JDWP.Error.ILLEGAL_ARGUMENT);
+
+ // create command with typeID = 1, expect INVALID_OBJECT error
+ testClass(-1, Integer.MAX_VALUE, expectedInstances, true, JDWP.Error.INVALID_OBJECT);
+
+ // create command with threadID instead of referenceTypeID, expect INVALID_CLASS error
+ testClass(debuggee.getThreadID("main"), Integer.MAX_VALUE, expectedInstances, true, JDWP.Error.INVALID_CLASS);
+
+ // if GC occurs during test the results should be ignored
+ resetStatusIfGC();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Instances/instances001/instances001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 2018, 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.
+ */
+package nsk.jdwp.ReferenceType.Instances.instances001;
+
+import java.util.ArrayList;
+import nsk.share.ReferringObjectSet;
+import nsk.share.jdi.HeapwalkingDebuggee;
+import nsk.share.jdwp.AbstractJDWPDebuggee;
+
+class TestClass {
+
+}
+
+public class instances001a extends AbstractJDWPDebuggee {
+ public static final int expectedCount = HeapwalkingDebuggee.includedIntoInstancesCountTypes.size();
+
+ private ArrayList<ReferringObjectSet> referrers = new ArrayList<ReferringObjectSet>();
+
+ public static final String COMMAND_CREATE_TEST_INSTANCES = "COMMAND_CREATE_TEST_INSTANCES";
+
+ public boolean parseCommand(String command) {
+ if (super.parseCommand(command))
+ return true;
+
+ if (command.equals(COMMAND_CREATE_TEST_INSTANCES)) {
+ // create object instances reachable via references with types which should be supported by command ReferenceType.Instances
+ for (String referenceType : HeapwalkingDebuggee.includedIntoInstancesCountTypes) {
+ referrers.add(new ReferringObjectSet(new TestClass(), 1, referenceType));
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public static void main(String args[]) {
+ new instances001a().doTest(args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Instances/instances002/instances002.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2007, 2018, 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 converted from VM Testbase nsk/jdwp/ReferenceType/Instances/instances002.
+ * VM Testbase keywords: [quick, jpda, jdwp, feature_jdk6_jpda, vm6, monitoring]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ReferenceType
+ * command: Instances
+ * Test checks that debuggee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: instances002
+ * debuggee: instances002a
+ * Debuggee contains 5 static fields with names instance1, ..., instance5 initialized with
+ * different instances of 'nsk.jdwp.ReferenceType.Instances.instances002.TestClass' and
+ * there are no more instances of 'nsk.jdwp.ReferenceType.Instances.instances002.TestClass' in debugee VM.
+ * Debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with execution commands.
+ * Debugger obtains referenceTypeID for 'nsk.jdwp.ReferenceType.Instances.instances002.TestClass'.
+ * Then, debugger creates command packet for Instances command with the
+ * found referenceTypeID and maxInstances as an arguments, writes packet to the transport
+ * channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts number of instances and instance's ids.
+ * Debugger checks that received number of instances is correct.
+ * Debugger obtains objectIDs for object instances stored in debuggee's fields instance1, ..., instance5
+ * and checks that this values and instances ids received via JDWP command are identical.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ReferenceType.Instances.instances002.instances002
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ReferenceType.Instances.instances002.instances002
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
+package nsk.jdwp.ReferenceType.Instances.instances002;
+
+import java.io.*;
+import nsk.share.Consts;
+import nsk.share.jdwp.*;
+
+public class instances002 extends TestDebuggerType1 {
+ protected String getDebugeeClassName() {
+ return nsk.jdwp.ReferenceType.Instances.instances002.instances002a.class.getName();
+ }
+
+ public static void main(String argv[]) {
+ System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new instances002().runIt(argv, out);
+ }
+
+ private void testClass(String className, int maxInstances, int expectedInstances) {
+ try {
+ int JDWP_COMMAND_ID = JDWP.Command.ReferenceType.Instances;
+
+ long typeID = debuggee.getReferenceTypeID(className);
+
+ log.display("Create command: " + JDWP.commandNames.get(JDWP_COMMAND_ID));
+ log.display("referenceType = " + typeID);
+ log.display("maxInstances = " + maxInstances);
+
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addReferenceTypeID(typeID);
+ command.addInt(maxInstances);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ ReplyPacket reply;
+
+ reply = getReply(command);
+
+ int instances = reply.getInt();
+ log.display("instances = " + instances);
+
+ // check that correct value of 'instances' was received
+ if (instances != expectedInstances) {
+ setSuccess(false);
+ log.complain("Unexpected 'instances' value: " + instances + ", expected is " + expectedInstances);
+ }
+
+ long expectedInstancesID[] = new long[expectedInstances];
+
+ // initialize expected IDs of instances
+ for (int i = 0; i < expectedInstances; i++) {
+ expectedInstancesID[i] = queryObjectID(debuggee.getReferenceTypeID(createTypeSignature(getDebugeeClassName())), "instance" + (i + 1),
+ JDWP.Tag.OBJECT);
+ }
+
+ long receivedInstancesID[] = new long[instances];
+
+ for (int i = 0; i < instances; i++) {
+ JDWP.Value value = reply.getValue();
+ log.display("tagged-ObjectID = " + value);
+
+ receivedInstancesID[i] = ((Long) value.getValue()).longValue();
+ }
+
+ // check that correct IDs of instances was received
+ for (int i = 0; i < instances; i++) {
+ boolean isIDExpected = false;
+
+ for (int j = 0; j < expectedInstancesID.length; j++) {
+ if (receivedInstancesID[i] == expectedInstancesID[j]) {
+ isIDExpected = true;
+ break;
+ }
+ }
+
+ if (!isIDExpected) {
+ setSuccess(false);
+ log.complain("Unexpected 'instance' value: " + receivedInstancesID[i]);
+ }
+ }
+
+ if (!getSuccess()) {
+ log.complain("Expected IDs:");
+ for (int i = 0; i < expectedInstancesID.length; i++)
+ log.complain("" + expectedInstancesID[i]);
+ }
+
+ if (!reply.isParsed()) {
+ setSuccess(false);
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ }
+ } catch (Exception e) {
+ setSuccess(false);
+ log.complain("Caught exception while testing JDWP command: " + e);
+ e.printStackTrace(log.getOutStream());
+ }
+ }
+
+ public void doTest() {
+ int expectedInstances = instances002a.expectedInstanceCount;
+
+ String testClassName = nsk.jdwp.ReferenceType.Instances.instances002.TestClass.class.getName();
+ testClass(createTypeSignature(testClassName), 0, expectedInstances);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Instances/instances002/instances002a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2007, 2018, 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.
+ */
+package nsk.jdwp.ReferenceType.Instances.instances002;
+
+import nsk.share.jdwp.*;
+
+class TestClass {
+
+}
+
+public class instances002a extends AbstractJDWPDebuggee {
+ public static final int expectedInstanceCount = 5;
+
+ public static TestClass instance1 = new TestClass();
+
+ public static TestClass instance2 = new TestClass();
+
+ public static TestClass instance3 = new TestClass();
+
+ public static TestClass instance4 = new TestClass();
+
+ public static TestClass instance5 = new TestClass();
+
+ public static void main(String args[]) {
+ new instances002a().doTest(args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Interfaces/interfaces001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.Interfaces;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class interfaces001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.ReferenceType.Interfaces";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "interfaces001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "ReferenceType.Interfaces";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ReferenceType.Interfaces;
+
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ static final String class_interfaces [][] = {
+ { DEBUGEE_CLASS_NAME + "$" + "TestedClassInterface1", "" },
+ { DEBUGEE_CLASS_NAME + "$" + "TestedClassInterface2", "" }
+ };
+ static final int DECLARED_INTERFACES = class_interfaces.length;
+ static final long interfaceIDs[] = new long[DECLARED_INTERFACES];
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new interfaces001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ try {
+
+ log.display("Getting ReferenceTypeID for class signature: " + TESTED_CLASS_SIGNATURE);
+ long typeID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+
+ for (int i = 0; i < DECLARED_INTERFACES; i++) {
+ class_interfaces[i][1] = "L" + class_interfaces[i][0].replace('.', '/') + ";";
+ log.display("Getting ReferenceTypeID for interface signature: " + class_interfaces[i][1]);
+ interfaceIDs[i] = debugee.getReferenceTypeID(class_interfaces[i][1]);
+ }
+
+ // begin test of JDWP command
+
+ log.display("Create command " + JDWP_COMMAND_NAME
+ + " with ReferenceTypeID: " + typeID);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addReferenceTypeID(typeID);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ int interfaces = reply.getInt();
+ log.display(" interfaces: " + interfaces);
+
+ if (interfaces != DECLARED_INTERFACES) {
+ log.complain("Unexpected number of declared interfaces in the reply packet:" + interfaces
+ + " (expected: " + DECLARED_INTERFACES + ")");
+ success = false;
+ }
+
+ for (int i = 0; i < interfaces; i++ ) {
+
+ log.display(" interface #" + i);
+
+ long interfaceID = reply.getReferenceTypeID();
+ log.display(" interfaceID: " + interfaceID);
+
+ if (interfaceID != interfaceIDs[i]) {
+ log.complain("Unexpected interface ID for interface #" + i + " in the reply packet: " + interfaceID
+ + " (expected: " + interfaceIDs[i] + ")");
+ success = false;
+ }
+
+ }
+
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ success = false;
+ } else {
+ log.display("Reply packet parsed successfully");
+ }
+
+ // end test of JDWP command
+
+ } catch (Exception e) {
+ log.complain("Caught exception while testing JDWP command: " + e);
+ success = false;
+ } finally {
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception while communicating with debugee: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Caught unexpected exception while starting the test: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Interfaces/interfaces001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ReferenceType/Interfaces/interfaces001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ReferenceType
+ * command: Interfaces
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test check that
+ * returned InterfaceIDs are equal to the ReferenceTypeIDs
+ * queried for these interfaces.
+ * Test consists of two compoments:
+ * debugger: interfaces001
+ * debuggee: interfaces001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with execution commands.
+ * Next, debugger obtains ReferenceTypeID for tested class, which
+ * will be used to test JDWP command. Also it obtains ReferenceTypeIDs
+ * for all interfaces of that class.
+ * Then, debugger creates command packet for Interfaces command with the
+ * found referenceTypeID as an argument, writes packet to the transport
+ * channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts interfaces IDs. Also it checks that extracted InterfaceIDs
+ * are equal to expected ReferenceTypeIDs.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ReferenceType.Interfaces.interfaces001
+ * nsk.jdwp.ReferenceType.Interfaces.interfaces001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ReferenceType.Interfaces.interfaces001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Interfaces/interfaces001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.Interfaces;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class interfaces001a {
+
+ public static void main(String args[]) {
+ interfaces001a _interfaces001a = new interfaces001a();
+ System.exit(interfaces001.JCK_STATUS_BASE + _interfaces001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return interfaces001.PASSED;
+ }
+
+ static public interface TestedClassInterface1 {
+ public int methodOfInterface1(int x);
+ }
+
+ static public interface TestedClassInterface2 {
+ public byte methodOfInterface2(byte b);
+ }
+
+ static class TestedClass implements TestedClassInterface1, TestedClassInterface2 {
+// static class TestedClass implements TestedClassInterface1 {
+ int foo = 0;
+ public int methodOfInterface1(int x) { return x; }
+ public byte methodOfInterface2(byte b) { return b; }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Methods/methods001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.Methods;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class methods001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.ReferenceType.Methods";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "methods001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "ReferenceType.Methods";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ReferenceType.Methods;
+
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ static final String[][] methods = {
+ {"<init>", "()V"},
+ {"byteMethod", "(B)B"},
+ {"booleanMethod", "()Z"},
+ {"charMethod", "(B)C"},
+ {"shortMethod", "(SS)S"},
+ {"intMethod", "(IS)I"},
+ {"longMethod", "(I)J"},
+ {"floatMethod", "(D)F"},
+ {"doubleMethod", "()D"},
+ {"stringMethod", "(Ljava/lang/String;C)Ljava/lang/String;"},
+ {"objectMethod", "()" + TESTED_CLASS_SIGNATURE},
+ {"intArrayMethod", "(I)[I"},
+ {"<init>", "(Z)V"}
+ };
+ static final int DECLARED_METHODS = methods.length;
+ static final int METHOD_MODIFIER_FLAGS = JDWP.ModifierFlag.PUBLIC;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new methods001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ try {
+
+ long typeID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+
+ // begin test of JDWP command
+
+ log.display("Create command " + JDWP_COMMAND_NAME
+ + " with ReferenceTypeID: " + typeID);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addReferenceTypeID(typeID);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ long declared = reply.getInt();
+ log.display(" declared: " + declared);
+
+ if (declared != DECLARED_METHODS) {
+ log.complain("Unexpected number of declared methods in the reply packet" + declared
+ + " (expected: " + DECLARED_METHODS + ")");
+ success = false;
+ }
+
+ for (int i = 0; i < declared; i++ ) {
+
+ log.display(" method #" + i);
+
+ long methodID = reply.getMethodID();
+ log.display(" methodID: " + methodID);
+
+ String name = reply.getString();
+ log.display(" name: " + name);
+ if (! name.equals(methods[i][0])) {
+ log.complain("Unexpected name of method #" + i + " in the reply packet: " + name
+ + " (expected: " + methods[i][0] + ")");
+ success = false;
+ }
+
+ String signature = reply.getString();
+ log.display(" signature: " + signature);
+ if (! signature.equals(methods[i][1])) {
+ log.complain("Unexpected signature of method #" + i + " in the reply packet: " + signature
+ + " (expected: " + methods[i][1] + ")");
+ success = false;
+ }
+
+ int modBits = reply.getInt();
+ String modBitsString = "0x" + Packet.toHexString(modBits, 8);
+ log.display(" modBits: " + modBitsString);
+ modBits &= JDWP.ModifierFlag.METHOD_MASK;
+ if (modBits != METHOD_MODIFIER_FLAGS) {
+ String expectedModBitsString = "0x" + Packet.toHexString(METHOD_MODIFIER_FLAGS, 8);
+ log.complain("Unexpected modifier flags of method #" + i + " in the reply packet: " + modBitsString
+ + " (expected: " + expectedModBitsString + ")");
+ success = false;
+ }
+
+ }
+
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ success = false;
+ } else {
+ log.display("Reply packet parsed successfully");
+ }
+
+ // end test of JDWP command
+
+ } catch (Exception e) {
+ log.complain("Caught exception while testing JDWP command: " + e);
+ success = false;
+ } finally {
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception while communicating with debugee: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Caught unexpected exception while starting the test: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Methods/methods001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ReferenceType/Methods/methods001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ReferenceType
+ * command: Methods
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * reply contains expected set of fields.
+ * Test consists of two compoments:
+ * debugger: methods001
+ * debuggee: methods001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with execution commands.
+ * Next, debugger obtains referenceTypeID for debuggee class, which
+ * will be used to test JDWP command.
+ * Then, debugger creates command packet for Methods command with the
+ * found referenceTypeID as an argument, writes packet to the transport
+ * channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts fields info. Test checks that all fields are equal to
+ * expected.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ReferenceType.Methods.methods001
+ * nsk.jdwp.ReferenceType.Methods.methods001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ReferenceType.Methods.methods001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Methods/methods001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.Methods;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class methods001a {
+
+ public static void main(String args[]) {
+ methods001a _methods001a = new methods001a();
+ System.exit(methods001.JCK_STATUS_BASE + _methods001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return methods001.PASSED;
+ }
+
+ static class TestedClass {
+ public TestedClass() {}
+ public byte byteMethod(byte b) { return b; }
+ public boolean booleanMethod() { return true; }
+ public char charMethod(byte b) { return (char) b; }
+ public short shortMethod(short x, short y) { return (short) (x - y); }
+ public int intMethod(int x, short y) { return x - y; }
+ public long longMethod(int x) { return (long) x; }
+ public float floatMethod(double x) { return (float) x; }
+ public double doubleMethod() { return 2.48e-10; }
+ public String stringMethod(String s, char ch) { return s + ch; };
+ public TestedClass objectMethod() { return this; }
+ public int[] intArrayMethod(int n) { return new int[n]; };
+ public TestedClass(boolean b) {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2003, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.MethodsWithGeneric;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * This test checks that the JDWP command <code>MethodsWithGeneric</code>
+ * from the <code>ReferenceType</code> command set returns generic signature
+ * information properly.<br>
+ * Debuggee part of the test creates instances of several tested classes with
+ * methods to be checked. Some of the classes are generic and accordingly
+ * contain generic methods. Debugger part obtains information for each method
+ * in a reference type of a tested class. Proper generic signature should be
+ * returned for the generic methods, or an empty string for non-generic ones.
+ */
+public class methwithgeneric001 {
+ static final String DEBUGGEE_CLASS =
+ "nsk.jdwp.ReferenceType.MethodsWithGeneric.methwithgeneric001t";
+
+ static final String JDWP_COMMAND_NAME = "ReferenceType.MethodsWithGeneric";
+ static final int JDWP_COMMAND_ID =
+ JDWP.Command.ReferenceType.MethodsWithGeneric;
+
+ static final String COMMAND_READY = "ready";
+ static final String COMMAND_QUIT = "quit";
+
+ static final String[][][] methods = {
+ {{"<init>",
+ "()V",
+ "NULL"},
+ {"methwithgeneric001bMeth",
+ "(Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001b;)Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001b;",
+ "<L:Ljava/lang/String;>(Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001b<TL;>;)Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001b<Ljava/lang/String;>;"},
+ {"methwithgeneric001bMethSt",
+ "(Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001b;)Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001b;",
+ "<T:Ljava/lang/String;>(Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001b<TT;>;)Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001b<Ljava/lang/String;>;"}},
+
+ {{"<init>",
+ "()V",
+ "NULL"},
+ {"methwithgeneric001cMeth",
+ "(Ljava/lang/Class;)Ljava/lang/Object;",
+ "<U:Ljava/lang/Object;>(Ljava/lang/Class<TU;>;)TU;"},
+ {"methwithgeneric001cMethSt",
+ "(Ljava/lang/Class;)Ljava/lang/Object;",
+ "<U:Ljava/lang/Object;>(Ljava/lang/Class<TU;>;)TU;"}},
+
+ {{"<init>",
+ "()V",
+ "NULL"},
+ {"methwithgeneric001eMeth",
+ "(Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001e;)V",
+ "NULL"},
+ {"methwithgeneric001eMethSt",
+ "(Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001e;)V",
+ "NULL"}},
+
+ {{"methwithgeneric001ifMeth",
+ "()I",
+ "NULL"},
+ {"methwithgeneric001ifMeth2",
+ "(Ljava/lang/Object;)I",
+ "<I:Ljava/lang/Object;>(TI;)I"}},
+
+ {{"<init>",
+ "()V",
+ "NULL"},
+ {"methwithgeneric001gMeth",
+ "(Ljava/lang/Byte;Ljava/lang/Double;[Ljava/lang/Class;)V",
+ "<A:Ljava/lang/Byte;B:Ljava/lang/Double;>(TA;TB;[Ljava/lang/Class<*>;)V"},
+ {"methwithgeneric001gMethSt",
+ "(Ljava/lang/Byte;Ljava/lang/Double;)V",
+ "<A:Ljava/lang/Byte;B:Ljava/lang/Double;>(TA;TB;)V"}}
+ };
+
+ static final String[][] classes = {
+ {"Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001b;", "3"},
+ {"Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001c;", "3"},
+ {"Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001e;", "3"},
+ {"Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001if;", "2"},
+ {"Lnsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001g;", "3"}
+ };
+
+ static final int CLS_NUM = classes.length;
+
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + Consts.JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new methwithgeneric001().runThis(argv, out);
+ }
+
+ public int runThis(String argv[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+ boolean result = true;
+
+ try {
+ Binder binder = new Binder(argumentHandler, log);
+
+ log.display("Starting debuggee VM ...");
+ Debugee debuggee = binder.bindToDebugee(DEBUGGEE_CLASS);
+
+ Transport transport = debuggee.getTransport();
+ IOPipe pipe = debuggee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event ...");
+ debuggee.waitForVMInit();
+
+ log.display("Querying for IDSizes ...");
+ debuggee.queryForIDSizes();
+
+ log.display("Resuming debuggee VM ...");
+ debuggee.resume();
+
+ log.display("Waiting for command: " + COMMAND_READY
+ + " ...");
+ String cmd = pipe.readln();
+ log.display(" ... Received command: " + cmd);
+
+ try {
+ for (int i=0; i<CLS_NUM; i++) {
+ long typeID = debuggee.getReferenceTypeID(classes[i][0]);
+
+ /////// begin test of JDWP command
+ log.display("\n>>>>>> Create command " + JDWP_COMMAND_NAME
+ + "\n\twith ReferenceTypeID: " + typeID
+ + "\n\tof the class: " + classes[i][0]);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addReferenceTypeID(typeID);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("\nWaiting for reply packet ...");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display(" ... Reply packet received:\n" + reply);
+
+ log.display("\nChecking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ /* parsing of reply data:
+ int declared - Number of declared methods
+
+ ---- Repeated 'declared' times:
+ methodID methodID - Method ID
+ string nam - The name of the field
+ string signature - The JNI signature of the field.
+ string genericSignature - The generic signature of the field,
+ or an empty string if there is none.
+ int modBits - The modifier bit flags (also known as access flags)
+ ----
+ */
+ log.display("\nParsing reply packet:");
+ reply.resetPosition();
+
+ long declared = reply.getInt();
+ log.display("\tdeclared: " + declared);
+ int meth_num = Integer.parseInt(classes[i][1]);
+ if (declared != meth_num) {
+ log.complain("TEST FAILED: Unexpected number of declared methods in the reply packet:"
+ + "\n\tGot: " + declared
+ + "\n\tExpected: " + meth_num + "\n");
+ result = false;
+ }
+
+ for (int j=0; j<declared; j++) {
+ log.display("\t--> method #" + j);
+
+ long methodID = reply.getMethodID();
+ log.display("\t\tmethodID: " + methodID);
+
+ String name = reply.getString();
+ log.display("\t\tname: " + name);
+ if (!name.equals(methods[i][j][0])) {
+ log.complain("TEST FAILED: Unexpected name of method #" + i
+ + " in the reply packet:"
+ + "\n\tGot: " + name
+ + "\n\tExpected: " + methods[i][j][0] + "\n");
+ result = false;
+ }
+
+ String signature = reply.getString();
+ log.display("\t\tsignature: " + signature);
+ if (!signature.equals(methods[i][j][1])) {
+ log.complain("TEST FAILED: Unexpected type signature of field #" + i
+ + " in the reply packet:"
+ + "\n\tGot: " + signature
+ + "\n\tExpected: " + methods[i][j][1] + "\n");
+ result = false;
+ }
+
+ String genSignature = reply.getString();
+ log.display("\t\tgeneric signature: " + genSignature);
+ if (genSignature.length() == 0) // a non-generic field
+ genSignature = "NULL";
+ if (!genSignature.equals(methods[i][j][2])) {
+ log.complain("TEST FAILED: Unexpected generic signature of field #" + i
+ + " in the reply packet:"
+ + "\n\tGot: " + genSignature
+ + "\n\tExpected: " + methods[i][j][2] + "\n");
+ result = false;
+ }
+
+ int modBits = reply.getInt();
+ String modBitsString = "0x" + Packet.toHexString(modBits, 8);
+ log.display("\t\tmodBits: " + modBitsString);
+ }
+
+ if (!reply.isParsed()) {
+ log.complain("TEST FAILED: Extra trailing bytes found in reply packet at: "
+ + reply.currentPosition());
+ result = false;
+ } else
+ log.display("\n<<<<<< Reply packet parsed");
+ /////// end test of JDWP command
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught exception while testing JDWP command: "
+ + e);
+ result = false;
+ } finally {
+ log.display("Sending command: " + COMMAND_QUIT + " ...");
+ pipe.println(COMMAND_QUIT);
+
+ log.display("Waiting for debuggee exits ...");
+ int code = debuggee.waitFor();
+ if (code == Consts.JCK_STATUS_BASE + Consts.TEST_PASSED) {
+ log.display(" ... Debuggee PASSED with the exit code: "
+ + code);
+ } else {
+ log.complain(" ... Debuggee FAILED with the exit code: "
+ + code);
+ result = false;
+ }
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while communicating with debugee: "
+ + e);
+ result = false;
+ }
+
+ if (!result)
+ return Consts.TEST_FAILED;
+
+ return Consts.TEST_PASSED;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * JDWP command set: ReferenceType
+ * JDWP command: MethodsWithGeneric
+ * It checks that the command returns generic signature information
+ * properly.
+ * Debuggee part of the test creates instances of several tested classes
+ * with methods to be checked. Some of the classes are generic and
+ * accordingly contain generic methods. Debugger part obtains information
+ * for each method in a reference type of a tested class. Proper generic
+ * signature should be returned for the generic methods, or an empty string
+ * for non-generic ones.
+ * COMMENTS
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ReferenceType.MethodsWithGeneric.methwithgeneric001
+ * nsk.jdwp.ReferenceType.MethodsWithGeneric.methwithgeneric001t
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ReferenceType.MethodsWithGeneric.methwithgeneric001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/MethodsWithGeneric/methwithgeneric001t.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2003, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.MethodsWithGeneric;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class methwithgeneric001t {
+ public static void main(String args[]) {
+ ArgumentHandler argHandler = new ArgumentHandler(args);
+ Log log = new Log(System.err, argHandler);
+ IOPipe pipe = argHandler.createDebugeeIOPipe(log);
+
+ // load tested classes
+ methwithgeneric001b<String> _methwithgeneric001b =
+ new methwithgeneric001b<String>();
+ methwithgeneric001c<Boolean, Integer> _methwithgeneric001c =
+ new methwithgeneric001c<Boolean, Integer>();
+ methwithgeneric001e _methwithgeneric001e =
+ new methwithgeneric001e();
+ methwithgeneric001if<Object> _methwithgeneric001if =
+ new methwithgeneric001d<Object>();
+ methwithgeneric001g<methwithgeneric001f> _methwithgeneric001g =
+ new methwithgeneric001g<methwithgeneric001f>();
+
+ log.display("Debuggee VM started\nSending command: "
+ + methwithgeneric001.COMMAND_READY);
+ pipe.println(methwithgeneric001.COMMAND_READY);
+
+ log.display("Waiting for command: "
+ + methwithgeneric001.COMMAND_QUIT + " ...");
+ String cmd = pipe.readln();
+ log.display(" ... Received command: " + cmd
+ + "\nDebuggee is exiting ...");
+
+ System.exit(Consts.JCK_STATUS_BASE + Consts.TEST_PASSED);
+ }
+}
+
+/*
+ * Dummy classes used only for verifying generic signature information
+ * in a debugger.
+ */
+
+class methwithgeneric001b<L extends String> {
+ <L extends String> methwithgeneric001b<String> methwithgeneric001bMeth(methwithgeneric001b<L> m) {
+ return new methwithgeneric001b<String>();
+ }
+
+ static <T extends String> methwithgeneric001b<String> methwithgeneric001bMethSt(methwithgeneric001b<T> m) {
+ return new methwithgeneric001b<String>();
+ }
+}
+
+class methwithgeneric001c<A, B extends Integer> {
+ public <U> U methwithgeneric001cMeth(Class<U> klass) throws Exception {
+ return klass.newInstance();
+ }
+
+ static public <U> U methwithgeneric001cMethSt(Class<U> klass) throws Exception {
+ return klass.newInstance();
+ }
+}
+
+interface methwithgeneric001if<I> {
+ int methwithgeneric001ifMeth();
+
+ <I> int methwithgeneric001ifMeth2(I v);
+}
+
+class methwithgeneric001d<T> implements methwithgeneric001if<T> {
+ public int methwithgeneric001ifMeth() {
+ return 1;
+ }
+
+ public <T> int methwithgeneric001ifMeth2(T v) {
+ return 2;
+ }
+}
+
+class methwithgeneric001e {
+ void methwithgeneric001eMeth(methwithgeneric001e e) {}
+ static void methwithgeneric001eMethSt(methwithgeneric001e e) {}
+}
+
+class methwithgeneric001f extends methwithgeneric001e implements methwithgeneric001if {
+ public int methwithgeneric001ifMeth() {
+ return 3;
+ }
+
+ public int methwithgeneric001ifMeth2(Object v) {
+ return 4;
+ }
+}
+
+class methwithgeneric001g<E extends methwithgeneric001e & methwithgeneric001if> {
+ <A extends Byte, B extends Double> void methwithgeneric001gMeth(A a, B b, Class<?>[] c) {}
+
+ static <A extends Byte, B extends Double> void methwithgeneric001gMethSt(A a, B b) {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Modifiers/modifiers001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.Modifiers;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class modifiers001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.ReferenceType.Modifiers";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "modifiers001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "ReferenceType.Modifiers";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ReferenceType.Modifiers;
+
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ static final int TESTED_CLASS_MODIFIER_FLAGS = JDWP.ModifierFlag.PUBLIC
+ | JDWP.ModifierFlag.FINAL;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new modifiers001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ try {
+
+ long typeID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+
+ // begin test of JDWP command
+
+ log.display("Create command " + JDWP_COMMAND_NAME
+ + " with ReferenceTypeID: " + typeID);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addReferenceTypeID(typeID);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ int modBits = reply.getInt();
+ String modBitsString = "0x" + Packet.toHexString(modBits, 8);
+ log.display(" modBits: " + modBitsString);
+
+// modBits &= JDWP.ModifierFlag.CLASS_MASK;
+
+ if ((JDWP.ModifierFlag.PUBLIC & modBits) == 0) {
+ log.complain("No expected PUBLIC modifier found into class modifier flags in the reply packet: " + modBitsString
+ + " (expected: " + Packet.toHexString(JDWP.ModifierFlag.PUBLIC,8) + ")");
+ success = false;
+ }
+
+ if ((JDWP.ModifierFlag.FINAL & modBits) == 0) {
+ log.complain("No expected FINAL modifier found into class modifier flags in the reply packet: " + modBitsString
+ + " (expected: " + Packet.toHexString(JDWP.ModifierFlag.FINAL,8) + ")");
+ success = false;
+ }
+
+ if ((JDWP.ModifierFlag.INTERFACE & modBits) != 0) {
+ log.complain("Unexpected INTERFACE modifier found into class modifier flags in the reply packet: " + modBitsString
+ + " (not expected: " + Packet.toHexString(JDWP.ModifierFlag.INTERFACE,8) + ")");
+ success = false;
+ }
+
+ if ((JDWP.ModifierFlag.ABSTRACT & modBits) != 0) {
+ log.complain("Unexpected ABSTRACT modifier found into class modifier flags in the reply packet: " + modBitsString
+ + " (not expected: " + Packet.toHexString(JDWP.ModifierFlag.ABSTRACT,8) + ")");
+ success = false;
+ }
+
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ success = false;
+ } else {
+ log.display("Reply packet parsed successfully");
+ }
+
+ // end test of JDWP command
+
+ } catch (Exception e) {
+ log.complain("Caught exception while testing JDWP command: " + e);
+ success = false;
+ } finally {
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception while communicating with debugee: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Caught unexpected exception while starting the test: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Modifiers/modifiers001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ReferenceType/Modifiers/modifiers001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ReferenceType
+ * command: Modifiers
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * reply contains expected set of class modifiers.
+ * Test consists of two compoments:
+ * debugger: modifiers001
+ * debuggee: modifiers001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with execution commands.
+ * Next, debugger obtains referenceTypeID for debuggee class, which
+ * will be used to test JDWP command.
+ * Then, debugger creates command packet for Modifiers command with the
+ * found referenceTypeID as an argument, writes packet to the transport
+ * channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts fields info. Test checks that the received set of class
+ * modifiers contains expected flags and does not contain unexpected ones.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ReferenceType.Modifiers.modifiers001
+ * nsk.jdwp.ReferenceType.Modifiers.modifiers001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ReferenceType.Modifiers.modifiers001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Modifiers/modifiers001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.Modifiers;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class modifiers001a {
+
+ public static void main(String args[]) {
+ modifiers001a _modifiers001a = new modifiers001a();
+ System.exit(modifiers001.JCK_STATUS_BASE + _modifiers001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return modifiers001.PASSED;
+ }
+
+ static final public class TestedClass {
+ int foo = 0;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/NestedTypes/nestedtypes001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.NestedTypes;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ReferenceType.NestedTypes.
+ *
+ * See nestedtypes001.README for description of test execution.
+ *
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class nestedtypes001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ReferenceType.NestedTypes";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "nestedtypes001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ReferenceType.NestedTypes";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ReferenceType.NestedTypes;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // nested classes names and signatures array
+ static final String nested_classes [][] = {
+ { TESTED_CLASS_NAME + "$" + "NestedInterface", "" },
+ { TESTED_CLASS_NAME + "$" + "StaticNestedClass", "" },
+ { TESTED_CLASS_NAME + "$" + "InnerNestedClass", "" }
+ };
+ static final int NESTED_CLASSES = nested_classes.length;
+
+ // nested classes IDs array
+ static final long nested_classesIDs[] = new long[NESTED_CLASSES];
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new nestedtypes001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debugee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debugee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debugee for TypeID of tested class
+ log.display("Getting ReferenceTypeID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long typeID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got TypeID: " + typeID);
+
+ // query debugee for TypeIDs of classes been nested
+ log.display("Getting ReferenceTypeIDs for nested classes");
+ queryNestedClassesTypeIDs();
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(typeID);
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debugee for TypeIDs for nested classes from nested_classes array
+ * and put them into nested_classesIDs array.
+ */
+ void queryNestedClassesTypeIDs() {
+ for (int i = 0; i < NESTED_CLASSES; i++) {
+ nested_classes[i][1] = "L" + nested_classes[i][0].replace('.', '/') + ";";
+ log.display("Getting ReferenceTypeID by signature:\n"
+ + " " + nested_classes[i][1]);
+ nested_classesIDs[i] = debugee.getReferenceTypeID(nested_classes[i][1]);
+ log.display(" got TypeID: " + nested_classesIDs[i]);
+ }
+ }
+
+ /**
+ * Perform testing JDWP command for specified TypeID.
+ */
+ void testCommand(long typeID) {
+
+ // count nested classes found in the reply packet
+ int found_classes[] = new int[NESTED_CLASSES];
+ for (int i = 0; i < NESTED_CLASSES; i++) {
+ found_classes[i] = 0;
+ }
+
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ log.display(" ReferenceTypeID: " + typeID);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addReferenceTypeID(typeID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract and check number of nested classes
+ int classes = 0;
+ try {
+ classes = reply.getInt();
+ log.display(" classes: " + classes);
+
+ if (classes != NESTED_CLASSES) {
+ log.complain("Unexpected number of nested classes in the reply packet:"
+ + classes + " (expected: " + NESTED_CLASSES + ")");
+ success = false;
+ }
+ } catch (BoundException e) {
+ log.complain("Unable to extract number of nested classes from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ }
+
+ // extract and check TypeID for each nested class
+ for (int i = 0; i < classes; i++ ) {
+ log.display(" nested class #" + i);
+
+ // extract TypeTag byte
+ try {
+ byte refTypeTag = reply.getByte();
+ log.display(" refTypeTag: " + refTypeTag);
+ } catch (BoundException e) {
+ log.complain("Unable to extract refTypetag of " + i + " nested class from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ break;
+ }
+
+ // extract and check TypeID
+ long referenceTypeID;
+ try {
+ referenceTypeID = reply.getReferenceTypeID();
+ log.display(" referenceTypeID: " + referenceTypeID);
+
+ } catch (BoundException e) {
+ log.complain("Unable to extract TypeID of " + i
+ + " nested class from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ break;
+ }
+
+ if (referenceTypeID == 0) {
+ log.complain("Unexpected null ReferenceTypeID for nested class #" + i
+ + " in the reply packet: " + referenceTypeID);
+ success = false;
+ } else {
+ boolean found = false;;
+ for (int j = 0; j < NESTED_CLASSES; j++) {
+ if (referenceTypeID == nested_classesIDs[j]) {
+ log.display("! Found expected nested class #" + j + ": "
+ + nested_classes[j][0]);
+ found = true;
+ found_classes[j]++;
+ break;
+ }
+ }
+ if (!found) {
+ log.complain("Unexpected TypeID of nested class found in reply packet: "
+ + referenceTypeID);
+ success = false;
+ }
+ }
+ }
+
+ // check for extra data in reply packet
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.offsetString());
+ success = false;
+ }
+
+ // check if all expected nested classes are found
+ for (int j = 0; j < NESTED_CLASSES; j++) {
+ if (found_classes[j] <= 0) {
+ log.complain("No TypeID for expected nested class found in reply packet: "
+ + nested_classesIDs[j] + " (" + nested_classes[j][0] + ")");
+ success = false;
+ } else if (found_classes[j] > 1) {
+ log.complain("Duplicated " + found_classes[j] + " TypeIDs for expected nested class found in reply packet: "
+ + nested_classesIDs[j] + " (" + nested_classes[j][0] + ")");
+ success = false;
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/NestedTypes/nestedtypes001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ReferenceType/NestedTypes/nestedtypes001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ReferenceType
+ * command: NestedTypes
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * returned ReferenceTypeIDs for nested types are equal to
+ * thye expected ones.
+ * Test consists of two compoments:
+ * debugger: nestedtypes001
+ * debuggee: nestedtypes001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains ReferenceTypeIDs for the tested class
+ * from debugee, and for all classes been nested for this class.
+ * Then, debugger creates command packet for NestedTypes command with the
+ * found referenceTypeID as an argument, writes packet to the transport
+ * channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts ReferenceTypeIDs of the nested types. Also test checks
+ * that the extreacted ReferenceTypeIDs for nested types are equal
+ * to the expected ones.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ * COMMENTS
+ * Test fixed due to test bug:
+ * 4908513 TEST_BUG: nsk/jdwp/ReferenceType/NestedTypes/nestedtypes001 assumes order
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ReferenceType.NestedTypes.nestedtypes001
+ * nsk.jdwp.ReferenceType.NestedTypes.nestedtypes001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ReferenceType.NestedTypes.nestedtypes001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/NestedTypes/nestedtypes001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.NestedTypes;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class nestedtypes001a {
+
+ public static void main(String args[]) {
+ nestedtypes001a _nestedtypes001a = new nestedtypes001a();
+ System.exit(nestedtypes001.JCK_STATUS_BASE + _nestedtypes001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // ensure tested class loaded
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + nestedtypes001.READY);
+ pipe.println(nestedtypes001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + nestedtypes001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (! signal.equals(nestedtypes001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + nestedtypes001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return nestedtypes001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return nestedtypes001.PASSED;
+ }
+
+ // tested class with nested classes
+ public static class TestedClass {
+
+ public interface NestedInterface {
+ public int methodFoo();
+ }
+
+ public static class StaticNestedClass implements NestedInterface {
+ int foo = 0;
+ public int methodFoo() { return foo; }
+ }
+
+ public class InnerNestedClass extends StaticNestedClass {
+ public int methodFoo() { return foo + foo; }
+ }
+
+ public TestedClass() {
+ // ensure all nested classes are loaded
+ InnerNestedClass foo = new InnerNestedClass();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Signature/signature001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.Signature;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class signature001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.ReferenceType.Signature";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "signature001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "ReferenceType.Signature";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ReferenceType.Signature;
+
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new signature001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ try {
+ long typeID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+
+ // begin test of JDWP command
+
+ log.display("Create command " + JDWP_COMMAND_NAME
+ + " with ReferenceTypeID: " + typeID);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addReferenceTypeID(typeID);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ String signature = reply.getString();
+ log.display(" signature: " + signature);
+
+ if (! signature.equals(TESTED_CLASS_SIGNATURE)) {
+ log.complain("Unexpected class signature found in the reply packet: " + signature
+ + " (expected: " + TESTED_CLASS_SIGNATURE + ")");
+ success = false;
+ }
+
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ success = false;
+ } else {
+ log.display("Reply packet parsed successfully");
+ }
+
+ // end test of JDWP command
+
+ } catch (Exception e) {
+ log.complain("Caught exception while testing JDWP command: " + e);
+ success = false;
+ } finally {
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception while communicating with debugee: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Caught unexpected exception while starting the test: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Signature/signature001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ReferenceType/Signature/signature001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ReferenceType
+ * command: Signature
+ * Test checks that debugee accept command and replies
+ * with correct reply packet. Also test checks that
+ * returned signature of the requested class is equal
+ * to the expected one.
+ * First, test launches debuggee VM using support classes
+ * and connects to it.
+ * Then test queries debugee VM for ReferenceTypeID for
+ * debugee class.
+ * Then test sends Signature command with received ReferenceTypeID
+ * as an command argument and waits for a reply packet.
+ * Then test checks if the received reply packet has proper
+ * structure and extracted signature string is equal to
+ * the expected signature of debugee class.
+ * After JDWP command has been tested, test sends debugee VM
+ * signal to quit, waits for debugee exits and exits too
+ * with a proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ReferenceType.Signature.signature001
+ * nsk.jdwp.ReferenceType.Signature.signature001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ReferenceType.Signature.signature001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Signature/signature001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.Signature;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class signature001a {
+
+ public static void main(String args[]) {
+ signature001a _signature001a = new signature001a();
+ System.exit(signature001.JCK_STATUS_BASE + _signature001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return signature001.PASSED;
+ }
+
+ static public class TestedClass {
+ int foo = 0;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2003, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.SignatureWithGeneric;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * This test checks that the JDWP command <code>SignatureWithGeneric</code>
+ * from the <code>ReferenceType</code> command set returns generic signature
+ * information properly.<br>
+ * Debuggee part of the test creates instances of several tested classes. Some
+ * of the classes are generic. Debugger part obtains signature information for
+ * reference types of the each tested class. Proper generic signature should
+ * be returned for the generic classes, or an empty string for non-generic ones.
+ */
+public class sigwithgeneric001 {
+ static final String DEBUGGEE_CLASS =
+ "nsk.jdwp.ReferenceType.SignatureWithGeneric.sigwithgeneric001t";
+
+ static final String JDWP_COMMAND_NAME = "ReferenceType.SignatureWithGeneric";
+ static final int JDWP_COMMAND_ID =
+ JDWP.Command.ReferenceType.SignatureWithGeneric;
+
+ static final String COMMAND_READY = "ready";
+ static final String COMMAND_QUIT = "quit";
+
+ static final String[][] classes = {
+ {"Lnsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001t;",
+ "NULL"},
+
+ {"Lnsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001b;",
+ "<L:Ljava/lang/String;>Ljava/lang/Object;"},
+
+ {"Lnsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001c;",
+ "<A:Ljava/lang/Object;B:Ljava/lang/Integer;>Ljava/lang/Object;"},
+
+ {"Lnsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001d;",
+ "<T:Ljava/lang/Object;>Ljava/lang/Object;Lnsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001if<TT;>;"},
+
+ {"Lnsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001e;",
+ "NULL"},
+
+ {"Lnsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001if;",
+ "<I:Ljava/lang/Object;>Ljava/lang/Object;"},
+
+ {"Lnsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001f;",
+ "NULL"},
+
+ {"Lnsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001g;",
+ "<E:Lnsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001e;:Lnsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001if;>Ljava/lang/Object;"},
+
+ {"Lnsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001h;",
+ "<A1:Ljava/lang/Object;B1:Ljava/lang/Object;C1:Ljava/lang/Object;>Lnsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001d<TA1;>;Lnsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001if2<TA1;TB1;TC1;>;"}
+ };
+
+ static final int CLS_NUM = classes.length;
+
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + Consts.JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new sigwithgeneric001().runThis(argv, out);
+ }
+
+ public int runThis(String argv[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+ boolean result = true;
+
+ try {
+ Binder binder = new Binder(argumentHandler, log);
+
+ log.display("Starting debuggee VM ...");
+ Debugee debuggee = binder.bindToDebugee(DEBUGGEE_CLASS);
+
+ Transport transport = debuggee.getTransport();
+ IOPipe pipe = debuggee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event ...");
+ debuggee.waitForVMInit();
+
+ log.display("Querying for IDSizes ...");
+ debuggee.queryForIDSizes();
+
+ log.display("Resuming debuggee VM ...");
+ debuggee.resume();
+
+ log.display("Waiting for command: " + COMMAND_READY
+ + " ...");
+ String cmd = pipe.readln();
+ log.display(" ... Received command: " + cmd);
+
+ try {
+ for (int i=0; i<CLS_NUM; i++) {
+ long typeID = debuggee.getReferenceTypeID(classes[i][0]);
+
+ /////// begin test of JDWP command
+ log.display("\n>>>>>> Create command " + JDWP_COMMAND_NAME
+ + "\n\twith ReferenceTypeID: " + typeID
+ + "\n\tof the class: " + classes[i][0]);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addReferenceTypeID(typeID);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("\nWaiting for reply packet ...");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display(" ... Reply packet received:\n" + reply);
+
+ log.display("\nChecking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ /* parsing of reply data:
+ string signature - The JNI signature for the reference type.
+ string genericSignature - The generic signature for the reference type
+ or an empty string if there is none.
+ */
+ log.display("\nParsing reply packet:");
+ reply.resetPosition();
+
+ String signature = reply.getString();
+ if (!signature.equals(classes[i][0])) {
+ log.complain("TEST FAILED: Unexpected signature of tested class #"
+ + (i+1) + " (" + classes[i][0] + ")"
+ + " in the reply packet:"
+ + "\n\tGot: " + signature
+ + "\n\tExpected: " + classes[i][0] + "\n");
+ result = false;
+ }
+ else
+ log.display("\t\tsignature: " + signature);
+
+ String genSignature = reply.getString();
+ if (genSignature.length() == 0) // a non-generic class
+ genSignature = "NULL";
+ if (!genSignature.equals(classes[i][1])) {
+ log.complain("TEST FAILED: Unexpected generic signature of tested class #"
+ + (i+1) + " (" + classes[i][0] + ")"
+ + " in the reply packet:"
+ + "\n\tGot: " + genSignature
+ + "\n\tExpected: " + classes[i][1] + "\n");
+ result = false;
+ }
+ else
+ log.display("\t\tgeneric signature: " + genSignature);
+
+ if (!reply.isParsed()) {
+ log.complain("TEST FAILED: Extra trailing bytes found in reply packet at: "
+ + reply.currentPosition());
+ result = false;
+ } else
+ log.display("\n<<<<<< Reply packet parsed");
+ /////// end test of JDWP command
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught exception while testing JDWP command: "
+ + e);
+ result = false;
+ } finally {
+ log.display("Sending command: " + COMMAND_QUIT + " ...");
+ pipe.println(COMMAND_QUIT);
+
+ log.display("Waiting for debuggee exits ...");
+ int code = debuggee.waitFor();
+ if (code == Consts.JCK_STATUS_BASE + Consts.TEST_PASSED) {
+ log.display(" ... Debuggee PASSED with the exit code: "
+ + code);
+ } else {
+ log.complain(" ... Debuggee FAILED with the exit code: "
+ + code);
+ result = false;
+ }
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while communicating with debugee: "
+ + e);
+ result = false;
+ }
+
+ if (!result)
+ return Consts.TEST_FAILED;
+
+ return Consts.TEST_PASSED;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * JDWP command set: ReferenceType
+ * JDWP command: SignatureWithGeneric
+ * It checks that the command returns generic signature information
+ * properly.
+ * Debuggee part of the test creates instances of several tested classes.
+ * Some of the classes are generic. Debugger part obtains signature
+ * information for reference types of the each tested class. Proper
+ * generic signature should be returned for the generic classes, or
+ * an empty string for non-generic ones.
+ * COMMENTS
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ReferenceType.SignatureWithGeneric.sigwithgeneric001
+ * nsk.jdwp.ReferenceType.SignatureWithGeneric.sigwithgeneric001t
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ReferenceType.SignatureWithGeneric.sigwithgeneric001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SignatureWithGeneric/sigwithgeneric001t.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2003, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.SignatureWithGeneric;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class sigwithgeneric001t {
+ public static void main(String args[]) {
+ ArgumentHandler argHandler = new ArgumentHandler(args);
+ Log log = new Log(System.err, argHandler);
+ IOPipe pipe = argHandler.createDebugeeIOPipe(log);
+
+ // load tested classes
+ sigwithgeneric001b<String> _sigwithgeneric001b =
+ new sigwithgeneric001b<String>();
+ sigwithgeneric001c<Boolean, Integer> _sigwithgeneric001c =
+ new sigwithgeneric001c<Boolean, Integer>();
+ sigwithgeneric001e _sigwithgeneric001e =
+ new sigwithgeneric001e();
+ sigwithgeneric001if<Object> _sigwithgeneric001if =
+ new sigwithgeneric001d<Object>();
+ sigwithgeneric001f _sigwithgeneric001f =
+ new sigwithgeneric001f();
+ sigwithgeneric001g<sigwithgeneric001f> _sigwithgeneric001g =
+ new sigwithgeneric001g<sigwithgeneric001f>();
+ sigwithgeneric001h<Byte, Double, Float> _sigwithgeneric001h =
+ new sigwithgeneric001h<Byte, Double, Float>();
+
+ log.display("Debuggee VM started\nSending command: "
+ + sigwithgeneric001.COMMAND_READY);
+ pipe.println(sigwithgeneric001.COMMAND_READY);
+
+ log.display("Waiting for command: "
+ + sigwithgeneric001.COMMAND_QUIT + " ...");
+ String cmd = pipe.readln();
+ log.display(" ... Received command: " + cmd
+ + "\nDebuggee is exiting ...");
+
+ System.exit(Consts.JCK_STATUS_BASE + Consts.TEST_PASSED);
+ }
+}
+
+/*
+ * Dummy classes used only for verifying generic signature information
+ * in a debugger.
+ */
+
+class sigwithgeneric001b<L extends String> {}
+
+class sigwithgeneric001c<A, B extends Integer> {}
+
+interface sigwithgeneric001if<I> {
+ int sigwithgeneric001ifMeth();
+
+ <I> int sigwithgeneric001ifMeth2(I v);
+}
+
+class sigwithgeneric001d<T> implements sigwithgeneric001if<T> {
+ public int sigwithgeneric001ifMeth() {
+ return 1;
+ }
+
+ public <T> int sigwithgeneric001ifMeth2(T v) {
+ return 2;
+ }
+}
+
+class sigwithgeneric001e {}
+
+class sigwithgeneric001f extends sigwithgeneric001e implements sigwithgeneric001if {
+ public int sigwithgeneric001ifMeth() {
+ return 3;
+ }
+
+ public int sigwithgeneric001ifMeth2(Object v) {
+ return 4;
+ }
+}
+
+class sigwithgeneric001g<E extends sigwithgeneric001e & sigwithgeneric001if> {}
+
+interface sigwithgeneric001if2<A, B, C> {}
+
+class sigwithgeneric001h<A1, B1, C1>
+ extends sigwithgeneric001d<A1>
+ implements sigwithgeneric001if2<A1, B1, C1> {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceDebugExtension/srcdebugext001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.SourceDebugExtension;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * The test checks that the <code>SourceDebugExtension class file
+ * attribute</code> can be obtained at the JDWP level of JDPA via
+ * the <code>SourceDebugExtension</code> command in the
+ * <code>ReferenceType</code> command set. The command is sent
+ * by a debugger. Received reply data should contain the debug
+ * extension string or the JDWP error <code>ABSENT_INFORMATION</code>.
+ */
+public class srcdebugext001 {
+ public static final int JCK_STATUS_BASE = 95;
+ public static final int PASSED = 0;
+ public static final int FAILED = 2;
+ static final String DEBUGGEE_CLASS =
+ "nsk.jdwp.ReferenceType.SourceDebugExtension.srcdebugext001t";
+ static final String COMMAND_READY = "ready";
+ static final String COMMAND_QUIT = "quit";
+
+ static final String JDWP_COMMAND_NAME = "ReferenceType.SourceDebugExtension";
+ static final int JDWP_COMMAND_ID =
+ JDWP.Command.ReferenceType.SourceDebugExtension;
+
+ private Log log;
+ private IOPipe pipe;
+ private Debugee debuggee;
+ private Transport transport;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new srcdebugext001().runIt(argv, out);
+ }
+
+ private int runIt(String args[], PrintStream out) {
+ ArgumentHandler argHandler = new ArgumentHandler(args);
+ CommandPacket cmdPack = new CommandPacket(JDWP_COMMAND_ID);
+ ReplyPacket replyPack = new ReplyPacket();
+
+ log = new Log(out, argHandler);
+ Binder binder = new Binder(argHandler, log);
+ try {
+ debuggee = binder.bindToDebugee(DEBUGGEE_CLASS);
+ debuggee.waitForVMInit();
+ pipe = debuggee.createIOPipe();
+ debuggee.resume();
+ } catch(Exception e) {
+ log.complain("FAILURE: caught: " + e);
+ e.printStackTrace();
+ return FAILED;
+ }
+ String cmd = pipe.readln();
+ if (!cmd.equals(COMMAND_READY)) {
+ log.complain("TEST BUG: unknown debuggee's command: "
+ + cmd);
+ return quitDebuggee(FAILED);
+ }
+
+// send a command packet
+ transport = debuggee.getTransport();
+ long rTypeID = getRefTypeID(DEBUGGEE_CLASS);
+ cmdPack.addReferenceTypeID(rTypeID);
+ cmdPack.setLength();
+ try {
+ log.display("Sending a command: " + JDWP_COMMAND_NAME);
+ transport.write(cmdPack);
+ log.display("Waiting for reply");
+ transport.read(replyPack);
+ log.display("Reply received:\n" + replyPack);
+
+// check received reply packet
+ if (checkReplyPacket(replyPack,cmdPack) != PASSED)
+ return quitDebuggee(FAILED);
+ switch(replyPack.getErrorCode()) {
+ case JDWP.Error.NONE:
+ replyPack.resetPosition();
+ log.display("TEST PASSED: received reply does not contain errors.\n\t"
+ + "The debug extension string is: "
+ + replyPack.getString());
+ break;
+ case JDWP.Error.ABSENT_INFORMATION:
+ log.display("TEST PASSED: received reply contains a valid error: ABSENT_INFORMATION");
+ break;
+ default:
+ log.complain("Unexpected error code "
+ + replyPack.getErrorCode() + " in reply:\n"
+ + replyPack);
+ return quitDebuggee(FAILED);
+ }
+ } catch(Exception e) {
+ log.complain("FAILURE: caught: " + e);
+ e.printStackTrace();
+ return quitDebuggee(FAILED);
+ }
+ return quitDebuggee(PASSED);
+ }
+
+ private long getRefTypeID(String cls) {
+ ReplyPacket reply = new ReplyPacket();
+ long typeID = 0;
+ String clsSig = "L" + cls.replace('.', '/') + ";";
+
+ log.display("\ngetRefTypeID: getting a RefetenceType ID for the signature:\n\t"
+ + clsSig);
+ CommandPacket cmd =
+ new CommandPacket(JDWP.Command.VirtualMachine.ClassesBySignature);
+ cmd.addString(clsSig);
+ cmd.setLength();
+ try {
+ log.display("\ngetRefTypeID: sending a command VirtualMachine.ClassesBySignature:\n"
+ + cmd);
+ transport.write(cmd);
+ log.display("getRefTypeID: Waiting for reply");
+ transport.read(reply);
+ log.display("getRefTypeID: Reply received:\n" + reply);
+ if (checkReplyPacket(reply,cmd) != PASSED)
+ throw new Failure("TEST FAILED");
+// reply = debuggee.receiveReplyFor(cmd);
+// log.display("getRefTypeID: reply received:\n" + reply);
+ log.display("getRefTypeID: extracting ReferenceTypeID from the reply packet");
+ reply.resetPosition();
+
+/* parsing of reply data:
+ int classes - number of reference types that follow
+ ---- Repeated 'classes' times:
+ byte refTypeTag - kind of following reference type
+ referenceTypeID - typeID matching loaded reference type
+ int status - the current class status
+ ---- */
+ int cls_num = reply.getInt();
+ if (cls_num != 1) {
+ throw new Failure("TEST FAILED: Illegal number of returned classes: "
+ + cls_num + ", expected: 1");
+ }
+ else
+ log.display("getRefTypeID: reply data:\n\tnumber of returned classes: "
+ + cls_num);
+ byte refTypeTag = reply.getByte();
+ typeID = reply.getReferenceTypeID();
+ log.display("\treferenceTypeID: " + typeID);
+ int status = reply.getInt();
+ log.display("\tstatus: " + status + "\n");
+ } catch(Exception e) {
+ quitDebuggee(FAILED);
+ if (e instanceof Failure)
+ throw new Failure(e);
+ else {
+ e.printStackTrace();
+ throw new Failure("TEST FAILED: " + e.toString());
+ }
+ }
+
+ if (!reply.isParsed()) {
+ quitDebuggee(FAILED);
+ throw new Failure("TEST FAILED: Extra bytes in reply packet at: "
+ + reply.currentPosition());
+ }
+
+ return typeID;
+ }
+
+ private int checkReplyPacket(ReplyPacket reply, CommandPacket cmd) {
+ int ret = PASSED;
+
+ if (reply.getFlags() != JDWP.Flag.REPLY_PACKET) {
+ log.complain("TEST FAILED: Unexpected flags in reply packet:\n\tgot=0x"
+ + Packet.toHexString(reply.getFlags(), 2)
+ + " should be: 0x"
+ + Integer.toHexString(JDWP.Flag.REPLY_PACKET));
+ ret = FAILED;
+ }
+ if (reply.getPacketID() != cmd.getPacketID()) {
+ log.complain("TEST FAILED: Unexpected id field in reply packet:\n\tgot=0x"
+ + Packet.toHexString(reply.getPacketID(), 8)
+ + " should be: 0x" + Packet.toHexString(cmd.getPacketID(), 8));
+ ret = FAILED;
+ }
+ return ret;
+ }
+
+ private int quitDebuggee(int stat) {
+ pipe.println(COMMAND_QUIT);
+ debuggee.waitFor();
+ return stat;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceDebugExtension/srcdebugext001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ReferenceType/SourceDebugExtension/srcdebugext001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test checks that the SourceDebugExtension class file
+ * attribute can be obtained at the JDWP level of JPDA via
+ * the SourceDebugExtension command in the ReferenceType command
+ * set. The command is sent by a debugger. Received reply data
+ * should contain the debug extension string or the JDWP error
+ * ABSENT_INFORMATION.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ReferenceType.SourceDebugExtension.srcdebugext001
+ * nsk.jdwp.ReferenceType.SourceDebugExtension.srcdebugext001t
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ReferenceType.SourceDebugExtension.srcdebugext001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceDebugExtension/srcdebugext001t.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.SourceDebugExtension;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * This is a debuggee class.
+ */
+public class srcdebugext001t {
+ public static void main(String args[]) {
+ ArgumentHandler argHandler = new ArgumentHandler(args);
+ IOPipe pipe = argHandler.createDebugeeIOPipe();
+ Log log = new Log(System.out, argHandler);
+
+ pipe.println(srcdebugext001.COMMAND_READY);
+ String cmd = pipe.readln();
+ if (!cmd.equals(srcdebugext001.COMMAND_QUIT)) {
+ log.complain("TEST BUG: unknown debugger command: "
+ + cmd);
+ System.exit(srcdebugext001.JCK_STATUS_BASE +
+ srcdebugext001.FAILED);
+ }
+ log.display("Received command: " + cmd
+ + "\nDebuggee is exiting...");
+ System.exit(srcdebugext001.JCK_STATUS_BASE +
+ srcdebugext001.PASSED);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceFile/srcfile001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.SourceFile;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class srcfile001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.ReferenceType.SourceFile";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "srcfile001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "ReferenceType.SourceFile";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ReferenceType.SourceFile;
+
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+ static final String TESTED_CLASS_SRCFILENAME = "srcfile001a.java";
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new srcfile001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ try {
+ long typeID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+
+ // begin test of JDWP command
+
+ log.display("Create command " + JDWP_COMMAND_NAME
+ + " with ReferenceTypeID: " + typeID);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addReferenceTypeID(typeID);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ String sourceFile = reply.getString();
+ log.display(" sourceFile: " + sourceFile);
+
+ if (! sourceFile.equals(TESTED_CLASS_SRCFILENAME)) {
+ log.complain("Unexpected class source file name found in the reply packet: " + sourceFile
+ + " (expected: " + TESTED_CLASS_SRCFILENAME + ")");
+ success = false;
+ }
+
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ success = false;
+ } else {
+ log.display("Reply packet parsed successfully");
+ }
+
+ // end test of JDWP command
+
+ } catch (Exception e) {
+ log.complain("Caught exception while testing JDWP command: " + e);
+ success = false;
+ } finally {
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception while communicating with debugee: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Caught unexpected exception while starting the test: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceFile/srcfile001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ReferenceType/SourceFile/srcfile001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ReferenceType
+ * command: SourceFile
+ * Test checks that debugee accept command and replies
+ * with correct reply packet. Also test checks that
+ * returned source file name for the requested class
+ * is equal to the expected one.
+ * First, test launches debuggee VM using support classes
+ * and connects to it.
+ * Then test queries debugee VM for ReferenceTypeID for
+ * debugee class.
+ * Then test sends SourceFile command with received ReferenceTypeID
+ * as an command argument and waits for a reply packet.
+ * Then test checks if the received reply packet has proper
+ * structure and extracted source file name is equal to
+ * the expected name of the file with debugee class.
+ * After JDWP command has been tested, test sends debugee VM
+ * signal to quit, waits for debugee VM exits and exits too
+ * with a proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ReferenceType.SourceFile.srcfile001
+ * nsk.jdwp.ReferenceType.SourceFile.srcfile001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ReferenceType.SourceFile.srcfile001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/SourceFile/srcfile001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.SourceFile;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class srcfile001a {
+
+ public static void main(String args[]) {
+ srcfile001a _srcfile001a = new srcfile001a();
+ System.exit(srcfile001.JCK_STATUS_BASE + _srcfile001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return srcfile001.PASSED;
+ }
+
+ static public class TestedClass {
+ int foo = 0;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Status/status001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.Status;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class status001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.ReferenceType.Status";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "status001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "ReferenceType.Status";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ReferenceType.Status;
+
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+ static final int TESTED_CLASS_STATUS = JDWP.ClassStatus.VERIFIED
+ | JDWP.ClassStatus.PREPARED
+ | JDWP.ClassStatus.INITIALIZED;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new status001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ try {
+ long typeID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+
+ // begin test of JDWP command
+
+ log.display("Create command " + JDWP_COMMAND_NAME
+ + " with ReferenceTypeID: " + typeID);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addReferenceTypeID(typeID);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ int status = reply.getInt();
+ String statusString = "0x" + Packet.toHexString(status, 4);
+ log.display(" status: " + statusString);
+
+ if (status != TESTED_CLASS_STATUS) {
+ log.complain("Unexpected class status extracted from reply packet: " + statusString
+ + " (expected: " + "0x" + Packet.toHexString(TESTED_CLASS_STATUS, 4) + ")");
+ success = false;
+ }
+
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ success = false;
+ } else {
+ log.display("Reply packet parsed successfully");
+ }
+
+ // end test of JDWP command
+
+ } catch (Exception e) {
+
+ log.complain("Caught exception while testing JDWP command: " + e);
+ success = false;
+
+ } finally {
+
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception while connecting to debugee: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Caught unexpected exception while starting the test: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Status/status001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ReferenceType/Status/status001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ReferenceType
+ * command: Status
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: status001
+ * debuggee: status001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with execution commands.
+ * Next, debugger obtains referenceTypeID for debuggee class, which
+ * will be used to test JDWP command.
+ * Then, debugger creates command packet for Status command with the
+ * found referenceTypeID as an argument, writes packet to the transport
+ * channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts classObjectID.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ReferenceType.Status.status001
+ * nsk.jdwp.ReferenceType.Status.status001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ReferenceType.Status.status001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Status/status001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ReferenceType.Status;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class status001a {
+
+ public static void main(String args[]) {
+ status001a _status001a = new status001a();
+ System.exit(status001.JCK_STATUS_BASE + _status001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return status001.PASSED;
+ }
+
+ static public class TestedClass {
+ int foo = 0;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/GetValues/getvalues001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,476 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.StackFrame.GetValues;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: StackFrame.GetValues.
+ *
+ * See getvalues001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class getvalues001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String ERROR = "error";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.StackFrame.GetValues";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "getvalues001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "StackFrame.GetValues";
+ static final int JDWP_COMMAND_ID = JDWP.Command.StackFrame.GetValues;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + getvalues001a.OBJECT_CLASS_NAME;
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // names of the static fields with the tested thread and object values
+ static final String TESTED_THREAD_FIELD_NAME = getvalues001a.THREAD_FIELD_NAME;
+ static final String TESTED_OBJECT_FIELD_NAME = getvalues001a.OBJECT_FIELD_NAME;
+ static final String TESTED_OBJECT_METHOD_NAME = getvalues001a.OBJECT_METHOD_NAME;
+
+ // list of tested variables names and values
+ static final Object variables[][] = {
+ { "booleanValue", "boolean", new Boolean(true), new Byte(JDWP.Tag.BOOLEAN)},
+ { "byteValue", "byte", new Byte((byte)0x0F), new Byte(JDWP.Tag.BYTE) },
+ { "charValue", "char", new Character('Z'), new Byte(JDWP.Tag.CHAR) },
+ { "intValue", "int", new Integer(100), new Byte(JDWP.Tag.INT) },
+ { "shortValue", "short", new Short((short)10), new Byte(JDWP.Tag.SHORT) },
+ { "longValue", "long", new Long((long)1000000), new Byte(JDWP.Tag.LONG) },
+ { "floatValue", "float", new Float((float)3.14), new Byte(JDWP.Tag.FLOAT) },
+ { "doubleValue", "double", new Double((double)2.8e-12), new Byte(JDWP.Tag.DOUBLE) },
+ { "objectValue", "objectID", new Long((long)0), new Byte(JDWP.Tag.OBJECT) }
+ };
+ static final int VARIABLES_COUNT = variables.length;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new getvalues001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ long threadID = 0;
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting tested classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for tested methodID
+ log.display("Getting tested methodID by name: " + TESTED_OBJECT_METHOD_NAME);
+ long methodID = debugee.getMethodID(classID, TESTED_OBJECT_METHOD_NAME, true);
+ log.display(" got methodID: " + methodID);
+
+ // query debugee for indexes of the method local variables
+ log.display("Getting indexes of the tested local variables for methodID: " + methodID);
+ int indexes[] = queryVariableIndexes(classID, methodID);
+ log.display(" got indexes: " + indexes.length);
+
+ // query debuggee for tested objectID value from static field
+ log.display("Getting tested objectID value from static field: "
+ + TESTED_OBJECT_FIELD_NAME);
+ long objectID = queryObjectID(classID, TESTED_OBJECT_FIELD_NAME, JDWP.Tag.OBJECT);
+ log.display(" got objectID: " + objectID);
+
+ // query debuggee for tested threadID value from static field
+ log.display("Getting tested threadID value from static field: "
+ + TESTED_THREAD_FIELD_NAME);
+ threadID = queryObjectID(classID, TESTED_THREAD_FIELD_NAME, JDWP.Tag.THREAD);
+ log.display(" got threadID: " + threadID);
+
+ // suspend tested thread into debuggee
+ log.display("Suspending thread into debuggee for threadID: " + threadID);
+ debugee.suspendThread(threadID);
+ log.display(" thread suspended");
+
+ // query debuggee for current frameID of the tested thread
+ log.display("Getting current frameID for the threadID: "
+ + threadID);
+ long frameID = debugee.getCurrentFrameID(threadID);
+ log.display(" got frameID: " + frameID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(frameID, threadID, indexes);
+
+ } finally {
+ log.display("\n>>> Finishing test \n");
+
+ // resume suspended thread
+ if (threadID != 0) {
+ log.display("Resuming suspended thread");
+ debugee.resumeThread(threadID);
+ }
+
+ // quit debugee
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ } else if (signal.equals(ERROR)) {
+ throw new TestBug("Debugee was not able to start tested thread"
+ + " (received signal: " + signal + ")");
+ } else if (!signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for objectID value of static field of the class.
+ */
+ long queryObjectID(long classID, String fieldName, byte tag) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has expected tag
+ if (value.getTag() != tag) {
+ throw new Failure("Unexpected tag for object value returned: "
+ + value.getTag() + " (expected: " + tag + ")");
+ }
+
+ // extract objectID from the value
+ long objectID = ((Long)value.getValue()).longValue();
+ return objectID;
+ }
+
+ /**
+ * Query debugee for indexes of the local method variables.
+ */
+ int[] queryVariableIndexes(long classID, long methodID) {
+ // create array for expected indexes
+ int indexes[] = new int[VARIABLES_COUNT];
+ for (int i = 0; i < VARIABLES_COUNT; i++) {
+ indexes[i] = 0;
+ }
+
+ // obtain variable indexes from debuggee
+ int count = 0;
+ try {
+ CommandPacket command = new CommandPacket(JDWP.Command.Method.VariableTable);
+ command.addReferenceTypeID(classID);
+ command.addMethodID(methodID);
+ command.setLength();
+
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+ reply.resetPosition();
+
+ int argCount = reply.getInt();
+ long slots = reply.getInt();
+ if (slots < VARIABLES_COUNT) {
+ throw new Failure("Too few method local variables returned: " + slots
+ + " (expected: at least " + VARIABLES_COUNT + ")");
+ }
+
+ for (int i = 0; i < slots; i++ ) {
+ long codeindex = reply.getLong();
+ String name = reply.getString();
+ String signature = reply.getString();
+ int length = reply.getInt();
+ int slot = reply.getInt();
+
+ for (int j = 0; j < VARIABLES_COUNT; j++) {
+ if (variables[j][0].equals(name)) {
+ indexes[j] = slot;
+ break;
+ }
+ }
+ }
+
+ } catch (BoundException e) {
+ log.complain("Unable to extract local variable indexes from the reply packet:\n\t"
+ + e.getMessage());
+ throw new Failure("Error occured while getting local variable indexes for methodID:"
+ + methodID);
+ }
+
+ return indexes;
+ }
+
+ /**
+ * Check i-th value from the reply packet.
+ */
+ void checkValue(int i, JDWP.Value value) {
+ if (!variables[i][2].equals(value.getValue())) {
+ log.complain("Unexpected value for " + i + " variable ("
+ + variables[i][0] + ") received: " + value
+ + " (expected: " + variables[i][2] + ")");
+ success = false;
+ }
+ }
+
+ /**
+ * Perform testing JDWP command for specified frameID.
+ */
+ void testCommand(long frameID, long threadID, int indexes[]) {
+ int slots = indexes.length;
+
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" threadID: " + threadID);
+ command.addObjectID(threadID);
+ log.display(" frameID: " + frameID);
+ command.addFrameID(frameID);
+ log.display(" slots: " + slots);
+ command.addInt(slots);
+
+ // add code indexes of the requested variables
+ for (int i = 0; i < slots; i++) {
+ log.display(" slot #" + i + ":");
+ log.display(" slot: " + indexes[i]);
+ command.addInt(indexes[i]);
+ byte tag = ((Byte)variables[i][3]).byteValue();
+ log.display(" sigbyte: " + tag);
+ command.addByte(tag);
+ }
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract and check number of values
+ int values = 0;
+ try {
+ values = reply.getInt();
+ log.display(" values: " + values);
+
+ } catch (BoundException e) {
+ log.complain("Unable to extract number of values form reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check if number of values are as expected
+ if (values < 0) {
+ log.complain("Negative number of values received:" + values
+ + " (expected: " + slots + ")");
+ success = false;
+ } else if (values != slots) {
+ log.complain("Unexpected number of values received:" + values
+ + " (expected: " + slots + ")");
+ success = false;
+ }
+
+ // extract and check each value
+ for (int i = 0; i < values; i++ ) {
+ log.display(" value #" + i + " (variable: " + variables[i][0] + ")");
+
+ // extract value
+ JDWP.Value value = null;
+ try {
+ value = reply.getValue();
+ log.display(" slotValue: " + value);
+ } catch (BoundException e) {
+ log.complain("Unable to extract " + i + " slot value:\n\t"
+ + e.getMessage());
+ success = false;
+ break;
+ }
+
+ // extract and check value by known type tag
+ checkValue(i, value);
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/GetValues/getvalues001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/StackFrame/GetValues/getvalues001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: StackFrame
+ * command: GetValues
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * returned values for requested local variables is the same
+ * as expected.
+ * Test consists of two compoments:
+ * debugger: getvalues001
+ * debuggee: getvalues001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains from debuggee classID for tested class
+ * and object ID and threadID as values of the class static fields.
+ * Also debugger suspends the thread and gets frameID for the
+ * current thread frameID and indexes of its local variables.
+ * Thread is suspended on the invokation of method for the tested object.
+ * Then, debugger creates command packet for StackFrame.GetValues
+ * command with the found threadID, frameID and indexes of local variables
+ * as arguments, writes packet to the transport channel, and waits
+ * for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts variables values. Also test checks that returned values
+ * are equals to the expected ones.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.StackFrame.GetValues.getvalues001
+ * nsk.jdwp.StackFrame.GetValues.getvalues001a
+ * @comment debuggee should be compiled w/ debug info
+ * @clean nsk.jdwp.StackFrame.GetValues.getvalues001a
+ * @compile -g:lines,source,vars ../getvalues001a.java
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.StackFrame.GetValues.getvalues001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/GetValues/getvalues001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.StackFrame.GetValues;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class getvalues001a {
+
+ // name of the tested object and thread classes
+ public static final String OBJECT_CLASS_NAME = "TestedObjectClass";
+ public static final String THREAD_CLASS_NAME = "TestedThreadClass";
+ public static final String THREAD_NAME = "TestedThreadName";
+
+ // name of the static fields with the tested object values
+ public static final String THREAD_FIELD_NAME = "thread";
+ public static final String OBJECT_FIELD_NAME = "object";
+ public static final String OBJECT_METHOD_NAME = "testedMethod";
+
+ // notification object to notify debuggee that thread is ready
+ private static Object threadReady = new Object();
+ // lock object to prevent thread from exit
+ private static Object threadLock = new Object();
+
+ // scaffold objects
+ private static volatile ArgumentHandler argumentHandler = null;
+ private static volatile Log log = null;
+
+ public static void main(String args[]) {
+ getvalues001a _getvalues001a = new getvalues001a();
+ System.exit(getvalues001.JCK_STATUS_BASE + _getvalues001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // lock the object to prevent thread from exit
+ synchronized (threadLock) {
+
+ // load tested class and create tested thread and object
+ log.display("Creating object of tested class");
+ TestedObjectClass.object = new TestedObjectClass();
+ log.display("Creating tested thread");
+ TestedObjectClass.thread = new TestedThreadClass(THREAD_NAME);
+
+ // start the thread and wait for notification from it
+ synchronized (threadReady) {
+ TestedObjectClass.thread.start();
+ try {
+ threadReady.wait();
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + getvalues001.READY);
+ pipe.println(getvalues001.READY);
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for thread started: " + e);
+ pipe.println(getvalues001.ERROR);
+ }
+ }
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + getvalues001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(getvalues001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + getvalues001.QUIT + ")");
+ log.complain("Debugee FAILED");
+ return getvalues001.FAILED;
+ }
+
+ // allow started thread to finish
+ }
+
+ // wait for tested thread finished
+ try {
+ log.display("Waiting for tested thread finished");
+ TestedObjectClass.thread.join();
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for tested thread finished:\n\t"
+ + e);
+ log.complain("Debugee FAILED");
+ return getvalues001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return getvalues001.PASSED;
+ }
+
+ // tested thread class
+ public static class TestedThreadClass extends Thread {
+
+ TestedThreadClass(String name) {
+ super(name);
+ }
+
+ public void run() {
+ log.display("Tested thread started");
+
+ // invoke tested method for the tested object from the tested thread
+ TestedObjectClass.object.testedMethod();
+
+ log.display("Tested thread finished");
+ }
+
+ }
+
+ // tested object class
+ public static class TestedObjectClass {
+
+ // field with the tested thread and object values
+ public static volatile TestedThreadClass thread = null;
+ public static volatile TestedObjectClass object = null;
+
+ public void testedMethod() {
+ // local variables
+ boolean booleanValue = true;
+ byte byteValue = (byte)0x0F;
+ char charValue = 'Z';
+ int intValue = 100;
+ short shortValue = (short)10;
+ long longValue = (long)1000000;
+ float floatValue = (float)3.14;
+ double doubleValue = (double)2.8e-12;
+ Object objectValue = null;
+
+ log.display("Tested frame entered");
+
+ // notify debuggee that tested thread ready for testing
+ synchronized (threadReady) {
+ threadReady.notifyAll();
+ }
+
+ // wait for lock object released
+ synchronized (threadLock) {
+ log.display("Tested frame dropped");
+ }
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/PopFrames/popframes001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,457 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.StackFrame.PopFrames;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: StackFrame.PopFrames.
+ *
+ * See popframes001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class popframes001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // VM capability constatnts
+ static final int VM_CAPABILITY_NUMBER = JDWP.Capability.CAN_POP_FRAMES;
+ static final String VM_CAPABILITY_NAME = "canPopFrames";
+
+ // package and classes names
+ static final String PACKAGE_NAME = "nsk.jdwp.StackFrame.PopFrames";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "popframes001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command
+ static final String JDWP_COMMAND_NAME = "StackFrame.PopFrames";
+ static final int JDWP_COMMAND_ID = JDWP.Command.StackFrame.PopFrames;
+
+ // tested class name and signature
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedThreadClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // field and method names
+ static final String TESTED_METHOD_NAME = "testedMethod";
+ static final int BREAKPOINT_LINE_NUMBER = popframes001a.BREAKPOINT_LINE_NUMBER;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // data obtained from debuggee
+ long testedClassID = 0;
+ long testedThreadID = 0;
+ long testedMethodID = 0;
+ long testedFrameID = 0;
+ int breakpointRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new popframes001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime(); // minutes
+ timeout = waitTime * 60 * 1000; // milliseconds
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee VM");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debuggee launched");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for VM_INIT event
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // check for VM capability
+ log.display("\n>>> Checking VM capability \n");
+ log.display("Getting new VM capability: " + VM_CAPABILITY_NAME);
+ boolean capable = debugee.getNewCapability(VM_CAPABILITY_NUMBER, VM_CAPABILITY_NAME);
+ log.display(" ... got VM capability: " + capable);
+
+ // exit as PASSED if this capability is not supported
+ if (!capable) {
+ out.println("TEST PASSED: unsupported VM capability: "
+ + VM_CAPABILITY_NAME);
+ return PASSED;
+ }
+
+ // prepare debuggee for testing and obtain required data
+ log.display("\n>>> Getting prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP command
+ log.display("\n>> Testing JDWP command \n");
+ testCommand();
+
+ // check command results
+ if (success) {
+ log.display("\n>>> Checking result of tested command \n");
+ checkResult();
+ }
+
+ // finish debuggee
+ log.display("\n>> Finishing debuggee \n");
+
+ // clear BREAKPOIN event request
+ log.display("Clearing BREAKPOINT event requestID: " + breakpointRequestID);
+ debugee.clearEventRequest(JDWP.EventKind.BREAKPOINT, breakpointRequestID);
+ log.display(" ... request cleared");
+
+ // resume debuggee after testing command
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for VM_DEATH event
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ log.display(" ... VM_DEATH event received");
+ dead = true;
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ log.display("\n>>> Finishing test \n");
+
+ // disconnect debugee and wait for its exit
+ if (debugee != null) {
+ quitDebugee();
+ }
+ }
+
+ // check result
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+ out.println("TEST PASSED");
+ return PASSED;
+ }
+
+ /**
+ * Get debuggee prepared for testing and obtain required data.
+ */
+ void prepareForTest() {
+ // wait for tested class loaded on debuggee startup and obtain its classID
+ log.display("Waiting for class loaded:\n\t" + TESTED_CLASS_NAME);
+ testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... class loaded with classID: " + testedClassID);
+
+ // query debuggee for tested methodID
+ log.display("Getting tested methodID by name: " + TESTED_METHOD_NAME);
+ testedMethodID = debugee.getMethodID(testedClassID, TESTED_METHOD_NAME, true);
+ log.display(" ... got methodID: " + testedMethodID);
+ log.display("");
+
+ // make BREAKPOINT event request
+ log.display("Creating breakpoint requests at: "
+ + TESTED_METHOD_NAME + ":" + BREAKPOINT_LINE_NUMBER);
+ breakpointRequestID =
+ debugee.requestBreakpointEvent(JDWP.TypeTag.CLASS,
+ testedClassID, testedMethodID,
+ BREAKPOINT_LINE_NUMBER,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... got breakpoint requestID: " + breakpointRequestID);
+
+ // resume debuggee after testing command
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+ log.display("");
+
+ // wait for BREAKPOINT event
+ log.display("Waiting for BREAKPOINT event for requestID: " + breakpointRequestID);
+ testedThreadID = waitForBreakpointEvent(breakpointRequestID, "first");
+ log.display(" ... breakpoint reached with threadID: " + testedThreadID);
+
+ // query debuggee for top frameID
+ log.display("Getting top frameID for threadID: " + testedThreadID);
+ testedFrameID = queryTopFrameID(testedThreadID);
+ log.display(" ... got frameID: " + testedFrameID);
+ log.display("");
+
+ // tested thread is suspended by an event
+ log.display("Tested thread is suspended by BREAKPOINT event before pop frameID: "
+ + testedFrameID);
+ }
+
+ /**
+ * Perform testing JDWP command.
+ */
+ void testCommand() {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" threadID: " + testedThreadID);
+ command.addObjectID(testedThreadID);
+ log.display(" frameID: " + testedFrameID);
+ command.addFrameID(testedFrameID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // receive reply packet from debugee
+ ReplyPacket reply = new ReplyPacket();
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet for tested command:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Wrong header of reply packet for tested command:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet data:");
+ reply.resetPosition();
+
+ // no reply data to parse
+ log.display(" no reply data");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... packed data parsed");
+ }
+
+ /**
+ * Check result of the tested JDWP command.
+ */
+ void checkResult() {
+ // resume debuggee after sending command
+ log.display("Resuming debuggee after command");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for BREAKPOINT event
+ log.display("Waiting for second BREAKPOINT event for requestID: " + breakpointRequestID);
+ long threadID = waitForBreakpointEvent(breakpointRequestID, "second");
+ log.display(" ... breakpoint secondly reached with threadID: " + threadID);
+
+ log.display("Tested method was invoked two times as expected");
+ }
+
+ /**
+ * Query debuggee for top frameID value for given threadID.
+ */
+ long queryTopFrameID(long threadID) {
+ String error = "Error occured while getting top frameID for threadID: " + threadID;
+
+ CommandPacket command = new CommandPacket(JDWP.Command.ThreadReference.Frames);
+ command.addObjectID(threadID);
+ command.addInt(0); // top frame index
+ command.addInt(1); // number of frames
+
+ ReplyPacket reply = debugee.receiveReplyFor(command, "ThreadReference.Frames");
+ reply.resetPosition();
+
+ try {
+ int frames = reply.getInt();
+ if (frames != 1) {
+ log.complain("Wrong number of frames returned in reply packet: " + frames
+ + " (expected: " + 1 + ")");
+ throw new Failure(error);
+ }
+ long frameID = reply.getFrameID();
+ return frameID;
+ } catch (BoundException e) {
+ log.complain("Unable to extract data from reply packet:\n\t"
+ + e.getMessage());
+ throw new Failure(error);
+ }
+ }
+
+ /**
+ * Wait for BREAKPOINT event made by the given request and return threadID.
+ * Debuggee will be left suspended by the BREAKPOINT event.
+ */
+ public long waitForBreakpointEvent(int requestID, String kind) {
+ String error = "Error occured while waiting for " + kind + " BREAKPOINT event";
+
+ for(;;) {
+ EventPacket event = debugee.receiveEvent();
+ byte eventSuspendPolicy = 0;
+ long eventThreadID = 0;
+ try {
+ eventSuspendPolicy = event.getByte();
+ int events = event.getInt();
+ for (int i = 0; i < events; i++) {
+ // check event kind
+ byte eventKind = event.getByte();
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ log.complain("Unexpected VM_DEATH event received: " + eventKind
+ + " (expected: " + JDWP.EventKind.BREAKPOINT +")");
+ dead = true;
+ throw new Failure(error);
+ } else if (eventKind != JDWP.EventKind.BREAKPOINT) {
+ log.complain("Unexpected event kind received: " + eventKind
+ + " (expected: " + JDWP.EventKind.BREAKPOINT +")");
+ throw new Failure(error);
+ }
+
+ // extract specific BREAKPOINT event data
+ int eventRequestID = event.getInt();
+ eventThreadID = event.getObjectID();
+ JDWP.Location eventLocation = event.getLocation();
+
+ if (eventRequestID == requestID) {
+ return eventThreadID;
+ } else {
+ log.complain("Unexpected BREAKPOINT event received with requestID: "
+ + eventRequestID + " (expected: " + requestID + ")");
+ }
+ }
+ } catch (BoundException e) {
+ log.complain("Unable to extract data from event packet while waiting for BREAKPOINT event:\n\t"
+ + e.getMessage() + "\n" + event);
+ throw new Failure(error);
+ }
+
+ // resume debuggee after unhandled event set
+ debugee.resumeEvent(eventSuspendPolicy, eventThreadID);
+ }
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/PopFrames/popframes001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/StackFrame/PopFrames/popframes001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: StackFrame
+ * command: PopFrames
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * after current frame is popped the tested method is invoked
+ * second time.
+ * Test consists of two compoments:
+ * debugger: popframes001
+ * debuggee: popframes001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded, requests methodID
+ * for tested method, sets breakpoint and wait for breakpoint reached.
+ * After breakpoint event is received with a thread, debugger gets top
+ * stack frame for this thread.
+ * Then, debugger creates command packet for StackFrame.PopFrames
+ * command with the found threadID and frameID, writes this packet
+ * to the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and checks if no reply data returned in the packet.
+ * Then, checks if the tested method will be invoked second time.
+ * To do so, it resumes debuggee and waits for BREAKPOINT event
+ * will be received again. If expected BREAKPOINT event is not received,
+ * debugger complains an error.
+ * Finally, debugger disconnects debuggee, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.StackFrame.PopFrames.popframes001
+ * nsk.jdwp.StackFrame.PopFrames.popframes001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.StackFrame.PopFrames.popframes001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/PopFrames/popframes001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.StackFrame.PopFrames;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class popframes001a {
+
+ // name of the tested thread
+ public static final String THREAD_NAME = "testedThread";
+
+ // line nunber for breakpoint
+ public static final int BREAKPOINT_LINE_NUMBER = 113;
+
+ // scaffold objects
+ private static volatile ArgumentHandler argumentHandler = null;
+ private static volatile Log log = null;
+
+ public static void main(String args[]) {
+ popframes001a _popframes001a = new popframes001a();
+ System.exit(popframes001.JCK_STATUS_BASE + _popframes001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // create tested thread
+ log.display("Creating testing thread");
+ TestedThreadClass thread = new TestedThreadClass(THREAD_NAME);
+ log.display(" ... thread created");
+
+ // start tested thread
+ log.display("Starting tested thread");
+ thread.start();
+ log.display(" ... thread started");
+
+ // wait for tested thread finished
+ try {
+ log.display("Waiting for tested thread finished");
+ thread.join();
+ log.display(" ... thread finished");
+ } catch(InterruptedException e) {
+ log.complain("Interruption while waiting for tested thread finished:\n\t" + e);
+ log.display("Debugee FAILED");
+ return popframes001.FAILED;
+ }
+
+ log.display("Debugee PASSED");
+ return popframes001.PASSED;
+ }
+
+ // tested thread class
+ public static class TestedThreadClass extends Thread {
+
+ // number of invokations of tested method
+ public static volatile int invokations = 0;
+
+ public TestedThreadClass(String name) {
+ super(name);
+ }
+
+ // invoke tested method
+ public void run() {
+ log.display("Tested thread: started");
+
+ // invoke tested method
+ int foo = 100;
+ foo = testedMethod(foo);
+
+ log.display("Tested thread: finished");
+ }
+
+ // tested method to pop frames
+ public int testedMethod(int arg) {
+ invokations++;
+ log.display("Tested method invoked " + invokations + " time");
+ int boo = 0;
+
+ log.display("Breakpoint line reached");
+ // next line is for breakpoint
+ boo = arg * 2; // BREAKPOINT_LINE_NUMBER
+ log.display("Breakpoint line passed");
+
+ return boo;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/SetValues/setvalues001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,599 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.StackFrame.SetValues;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: StackFrame.SetValues.
+ *
+ * See setvalues001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class setvalues001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String RUN = "run";
+ static final String DONE = "done";
+ static final String ERROR = "error";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.StackFrame.SetValues";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "setvalues001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "StackFrame.SetValues";
+ static final int JDWP_COMMAND_ID = JDWP.Command.StackFrame.SetValues;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + setvalues001a.OBJECT_CLASS_NAME;
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // target values class name and signature constants
+ static final String TARGET_VALUES_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TargetValuesClass";
+ static final String TARGET_VALUES_CLASS_SIGNATURE = "L" + TARGET_VALUES_CLASS_NAME.replace('.', '/') + ";";
+
+ // names of the static fields with the tested thread and object values
+ static final String TESTED_THREAD_FIELD_NAME = setvalues001a.THREAD_FIELD_NAME;
+ static final String TESTED_OBJECT_FIELD_NAME = setvalues001a.OBJECT_FIELD_NAME;
+ static final String TESTED_OBJECT_METHOD_NAME = setvalues001a.OBJECT_METHOD_NAME;
+
+ // list of tested variables names and values
+ static final Object variables[] = {
+ "booleanValue",
+ "byteValue",
+ "charValue",
+ "intValue",
+ "shortValue",
+ "longValue",
+ "floatValue",
+ "doubleValue",
+ "stringValue",
+ "objectValue"
+ };
+ static final int VARIABLES_COUNT = variables.length;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new setvalues001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ long threadID = 0;
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // get target values from static fields
+
+ // query debugee for classID for the class with target values
+ log.display("Getting classID for class with target values by signature:\n"
+ + " " + TARGET_VALUES_CLASS_SIGNATURE);
+ long targetValuesClassID =
+ debugee.getReferenceTypeID(TARGET_VALUES_CLASS_SIGNATURE);
+ log.display(" got classID: " + targetValuesClassID);
+
+ // query debugee for fieldIDs of the class static fields
+ log.display("Getting fieldIDs for static fields of the class");
+ long fieldIDs[] = queryClassFieldIDs(targetValuesClassID);
+ log.display(" got fields: " + fieldIDs.length);
+
+ // query debugee for values of the fields
+ log.display("Getting values of the static fields");
+ JDWP.Value values[] =
+ queryClassFieldValues(targetValuesClassID, fieldIDs);
+ log.display(" got values: " + values.length);
+
+ // get indexes of local variables
+
+ // query debugee for classID of the tested class
+ log.display("Getting tested classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long testedClassID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + testedClassID);
+
+ // query debuggee for tested methodID
+ log.display("Getting tested methodID by name: " + TESTED_OBJECT_METHOD_NAME);
+ long methodID = debugee.getMethodID(testedClassID, TESTED_OBJECT_METHOD_NAME, true);
+ log.display(" got methodID: " + methodID);
+
+ // query debugee for indexes of the method local variables
+ log.display("Getting indexes of the tested local variables for methodID: " + methodID);
+ int indexes[] = queryVariableIndexes(testedClassID, methodID);
+ log.display(" got indexes: " + indexes.length);
+
+ // get tested objectID and threadID from static fields
+
+ // query debuggee for tested objectID value from static field
+ log.display("Getting tested objectID value from static field: "
+ + TESTED_OBJECT_FIELD_NAME);
+ long objectID = queryObjectID(testedClassID, TESTED_OBJECT_FIELD_NAME, JDWP.Tag.OBJECT);
+ log.display(" got objectID: " + objectID);
+
+ // query debuggee for tested threadID value from static field
+ log.display("Getting tested threadID value from static field: "
+ + TESTED_THREAD_FIELD_NAME);
+ threadID = queryObjectID(testedClassID, TESTED_THREAD_FIELD_NAME, JDWP.Tag.THREAD);
+ log.display(" got threadID: " + threadID);
+
+ // suspend tested thread into debuggee
+ log.display("Suspending thread into debuggee for threadID: " + threadID);
+ debugee.suspendThread(threadID);
+ log.display(" thread suspended");
+
+ // get current frameID and test JDWP command
+
+ // query debuggee for current frameID of the tested thread
+ log.display("Getting current frameID for the threadID: "
+ + threadID);
+ long frameID = debugee.getCurrentFrameID(threadID);
+ log.display(" got frameID: " + frameID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(frameID, threadID, indexes, values);
+
+ // check confirmation from debuggee that values have been set correctly
+ log.display("\n>>> Checking that the values have been set correctly \n");
+
+ log.display("Resuming suspended thread");
+ debugee.resumeThread(threadID);
+
+ checkValuesChanged();
+
+ } finally {
+ log.display("\n>>> Finishing test \n");
+
+ // resume suspended thread
+ if (threadID != 0) {
+ log.display("Finally resuming potentially suspended thread");
+ debugee.resumeThread(threadID);
+ }
+
+ // quit debugee
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ } else if (signal.equals(ERROR)) {
+ throw new TestBug("Debugee was not able to start tested thread"
+ + " (received signal: " + signal + ")");
+ } else if (!signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for objectID value of static field of the class.
+ */
+ long queryObjectID(long classID, String fieldName, byte tag) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has expected tag
+ if (value.getTag() != tag) {
+ throw new Failure("Unexpected tag for object value returned: "
+ + value.getTag() + " (expected: " + tag + ")");
+ }
+
+ // extract objectID from the value
+ long objectID = ((Long)value.getValue()).longValue();
+ return objectID;
+ }
+
+ /**
+ * Query debugee for indexes of the local method variables.
+ */
+ int[] queryVariableIndexes(long classID, long methodID) {
+ // create array for expected indexes
+ int indexes[] = new int[VARIABLES_COUNT];
+ for (int i = 0; i < VARIABLES_COUNT; i++) {
+ indexes[i] = 0;
+ }
+
+ // obtain variable indexes from debuggee
+ int count = 0;
+ try {
+ CommandPacket command = new CommandPacket(JDWP.Command.Method.VariableTable);
+ command.addReferenceTypeID(classID);
+ command.addMethodID(methodID);
+ command.setLength();
+
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+ reply.resetPosition();
+
+ int argCount = reply.getInt();
+ long slots = reply.getInt();
+
+ for (int i = 0; i < slots; i++ ) {
+ long codeindex = reply.getLong();
+ String name = reply.getString();
+ String signature = reply.getString();
+ int length = reply.getInt();
+ int slot = reply.getInt();
+
+ for (int j = 0; j < VARIABLES_COUNT; j++) {
+ if (variables[j].equals(name)) {
+ indexes[j] = slot;
+ break;
+ }
+ }
+ }
+
+ } catch (BoundException e) {
+ log.complain("Unable to extract local variable indexes from the reply packet:\n\t"
+ + e.getMessage());
+ throw new Failure("Error occured while getting local variable indexes for methodID:"
+ + methodID);
+ }
+
+ // check that all expected fieldIDs received
+ int notfound = 0;
+ for (int i = 0; i < VARIABLES_COUNT; i++) {
+ if(indexes[i] == 0) {
+ log.complain("Not found index for local variable: " + variables[i]);
+ notfound++;
+ }
+ }
+ if (notfound > 0) {
+ throw new Failure("Unable to get indexes for " + notfound +
+ " local variables for methodID: " + methodID);
+ }
+ return indexes;
+ }
+
+ /**
+ * Query debugee for fieldID's of the class static fields.
+ */
+ long[] queryClassFieldIDs(long classID) {
+
+ // create array of fieldID's corresponding to tested variables
+ long[] fieldIDs = new long[VARIABLES_COUNT];
+ for (int i = 0; i < VARIABLES_COUNT; i++) {
+ fieldIDs[i] = 0;
+ }
+
+ // compose ReferenceType.Fields command packet
+ CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.Fields);
+ command.addReferenceTypeID(classID);
+ command.setLength();
+
+ // send the command and receive reply
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+
+ // extract fieldIDs from the reply packet
+ try {
+ reply.resetPosition();
+
+ int declared = reply.getInt();
+
+ for (int i = 0; i < declared; i++ ) {
+ long fieldID = reply.getFieldID();
+ String name = reply.getString();
+ String signature = reply.getString();
+ int modBits = reply.getInt();
+
+ // find variable with the same name
+ for (int j = 0; j < VARIABLES_COUNT; j++) {
+ if (variables[j].equals(name)) {
+ fieldIDs[j] = fieldID;
+ }
+ }
+ }
+ } catch (BoundException e) {
+ log.complain("Unable to parse reply packet for ReferenceType.Fields command:\n\t"
+ + e);
+ log.complain("Received reply packet:\n"
+ + reply);
+ throw new Failure("Error occured while getting static fieldIDs for classID: " + classID);
+ }
+
+ // check that all expected fieldIDs received
+ int notfound = 0;
+ for (int i = 0; i < VARIABLES_COUNT; i++) {
+ if(fieldIDs[i] == 0) {
+ log.complain("Not found fieldID for static field: " + variables[i]);
+ notfound++;
+ }
+ }
+ if (notfound > 0) {
+ throw new Failure("Unable to get fiedIDs for " + notfound +
+ " static fields for classID: " + classID);
+ }
+ return fieldIDs;
+ }
+
+ /**
+ * Query debugee for values of the class fields.
+ */
+ JDWP.Value[] queryClassFieldValues(long classID, long fieldIDs[]) {
+ // compose ReferenceType.Fields command packet
+ int count = fieldIDs.length;
+ CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.GetValues);
+ command.addReferenceTypeID(classID);
+ command.addInt(count);
+ for (int i = 0; i < count; i++) {
+ command.addFieldID(fieldIDs[i]);
+ }
+ command.setLength();
+
+ // send the command and receive reply
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+
+ // extract values from the reply packet
+ try {
+ reply.resetPosition();
+
+ int valuesCount = reply.getInt();
+ if (valuesCount != count) {
+ throw new Failure("Unexpected number of values of static fields returned: "
+ + valuesCount + " (expected: " + count + ")");
+ }
+
+ JDWP.Value values[] = new JDWP.Value[valuesCount];
+ for (int i = 0; i < valuesCount; i++ ) {
+ JDWP.Value value = reply.getValue();
+ values[i] = value;
+ }
+ return values;
+ } catch (BoundException e) {
+ log.complain("Unable to parse reply packet for ReferenceType.SetValues command:\n\t"
+ + e);
+ log.complain("Received reply packet:\n"
+ + reply);
+ throw new Failure("Error occured while getting static fields values for classID: " + classID);
+ }
+ }
+
+ /**
+ * Perform testing JDWP command for specified frameID.
+ */
+ void testCommand(long frameID, long threadID, int indexes[], JDWP.Value values[]) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" threadID: " + threadID);
+ command.addObjectID(threadID);
+ log.display(" frameID: " + frameID);
+ command.addFrameID(frameID);
+ log.display(" slotValues: " + VARIABLES_COUNT);
+ command.addInt(VARIABLES_COUNT);
+
+ // add indexes and new values of the tested variables
+ for (int i = 0; i < VARIABLES_COUNT; i++) {
+ log.display(" slot #" + i + ":");
+ log.display(" slot: " + indexes[i]);
+ command.addInt(indexes[i]);
+ log.display(" slotvalue: " + values[i]);
+ command.addValue(values[i]);
+ }
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // no data in the reply packet
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ }
+
+ /**
+ * Check confiramtion from debuggee that values are changed.
+ */
+ void checkValuesChanged() {
+ // send debugee signal RUN
+ log.display("Sending signal to debugee: " + RUN);
+ pipe.println(RUN);
+
+ // wait for DONE signal from debugee
+ log.display("Waiting for signal from debugee: " + DONE);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+
+ // check received signal
+ if (signal == null) {
+ throw new TestBug("<null> signal received from debugee: " + signal
+ + " (expected: " + DONE + ")");
+ } else if (signal.equals(DONE)) {
+ log.display("All varaible values have been correctly set into debuggee VM");
+ } else if (signal.equals(ERROR)) {
+ log.complain("Not all variables values have been correctly set into debuggee VM");
+ success = false;
+ } else {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + DONE + ")");
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/SetValues/setvalues001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/StackFrame/SetValues/setvalues001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: StackFrame
+ * command: SetValues
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * new values of the method local variables is the same
+ * as expected.
+ * Test consists of two compoments:
+ * debugger: setvalues001
+ * debuggee: setvalues001a
+ * To set values to the method local variables for the current
+ * thread frame and check that they are set correctly, test defines
+ * following classes into debuggee VM:
+ * OriginalValuesClass - class with original values of static fields
+ * TargetValuesClass - class with target values of static fields
+ * TestedObjectClass - tested class with tested method with local variables
+ * TestedThreadClass - thread class with tested frame
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains from debuggee classID for tested class
+ * and object ID and threadID as values of the class static fields.
+ * Also debugger obtains values of static fields of the class TargetValuesClass
+ * to use them as new values for local variables from the tested frame.
+ * Debugger suspends the thread and gets frameID for the current thread
+ * frameID and indexes of its local variables. Thread is suspended on the
+ * invokation of the tested method with local variables.
+ * Then, debugger creates command packet for StackFrame.SetValues
+ * command with the found threadID, frameID and new values for local
+ * variables as arguments, writes packet to the transport channel,
+ * and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts variables values. Debugger checks that no data returmed
+ * with the reply packet. Also debugger sends debuggee signal RUN to
+ * to check new values of the local variables. If all values are set
+ * correctly debuggee replies with the signal DONE.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.StackFrame.SetValues.setvalues001
+ * nsk.jdwp.StackFrame.SetValues.setvalues001a
+ * @comment debuggee should be compiled w/ debug info
+ * @clean nsk.jdwp.StackFrame.SetValues.setvalues001a
+ * @compile -g:lines,source,vars ../setvalues001a.java
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.StackFrame.SetValues.setvalues001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/SetValues/setvalues001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,414 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.StackFrame.SetValues;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class setvalues001a {
+
+ // name of the tested object and thread classes
+ public static final String OBJECT_CLASS_NAME = "TestedObjectClass";
+ public static final String THREAD_CLASS_NAME = "TestedThreadClass";
+ public static final String THREAD_NAME = "TestedThreadName";
+
+ // name of the static fields with the tested object values
+ public static final String THREAD_FIELD_NAME = "thread";
+ public static final String OBJECT_FIELD_NAME = "object";
+ public static final String OBJECT_METHOD_NAME = "testedMethod";
+
+ // notification object to notify debuggee that thread is ready
+ private static Object threadReady = new Object();
+ // lock object to prevent thread from exit
+ private static Object threadLock = new Object();
+
+ // scaffold objects
+ private static volatile ArgumentHandler argumentHandler = null;
+ private static volatile Log log = null;
+
+ public static void main(String args[]) {
+ setvalues001a _setvalues001a = new setvalues001a();
+ System.exit(setvalues001.JCK_STATUS_BASE + _setvalues001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // lock the object to prevent thread from running further
+ synchronized (threadLock) {
+
+ // load tested class and create tested thread and object
+ log.display("Creating object of tested class");
+ TestedObjectClass.object = new TestedObjectClass();
+ log.display("Creating tested thread");
+ TestedObjectClass.thread = new TestedThreadClass(THREAD_NAME);
+
+ OriginalValuesClass original = new OriginalValuesClass();
+ TargetValuesClass target = new TargetValuesClass();
+
+ // start the thread and wait for notification from it
+ synchronized (threadReady) {
+ TestedObjectClass.thread.start();
+ try {
+ threadReady.wait();
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + setvalues001.READY);
+ pipe.println(setvalues001.READY);
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for thread started: " + e);
+ pipe.println(setvalues001.ERROR);
+ // exit debuggee
+ log.complain("Debugee FAILED");
+ return setvalues001.FAILED;
+ }
+ }
+
+ // wait for signal RUN from debugeer
+ log.display("Waiting for signal from debugger: " + setvalues001.RUN);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(setvalues001.RUN)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + setvalues001.RUN + ")");
+ // skip checking for new values
+ TestedObjectClass.object.checking = false;
+ // exit debuggee
+ log.complain("Debugee FAILED");
+ return setvalues001.FAILED;
+ }
+
+ // allow started thread to run and finish
+ }
+
+ // wait for tested thread finished
+ try {
+ log.display("Waiting for tested thread finished");
+ TestedObjectClass.thread.join();
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for tested thread finished:\n\t"
+ + e);
+ // exit debuggee
+ log.complain("Debugee FAILED");
+ return setvalues001.FAILED;
+ }
+
+ // confirm that new values of local variables are correct
+ if (TestedObjectClass.object.different == 0) {
+ log.display("Sending signal to debugger: " + setvalues001.DONE);
+ pipe.println(setvalues001.DONE);
+ } else {
+ log.complain("Values of " + TestedObjectClass.object.different +
+ " local variables have not been set correctly");
+ log.display("Sending signal to debugger: " + setvalues001.ERROR);
+ pipe.println(setvalues001.ERROR);
+ }
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + setvalues001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(setvalues001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + setvalues001.QUIT + ")");
+ // exit debuggee
+ log.complain("Debugee FAILED");
+ return setvalues001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return setvalues001.PASSED;
+ }
+
+ // tested thread class
+ public static class TestedThreadClass extends Thread {
+
+ public TestedThreadClass(String name) {
+ super(name);
+ }
+
+ public void run() {
+ log.display("Tested thread started");
+
+ // invoke tested method for the tested object from the tested thread
+ TestedObjectClass.object.testedMethod();
+
+ log.display("Tested thread finished");
+ }
+
+ }
+
+ // tested object class
+ public static class TestedObjectClass {
+
+ // field with the tested thread and object values
+ public static volatile TestedThreadClass thread = null;
+ public static volatile TestedObjectClass object = null;
+
+ // allow to check new values of local variables
+ public volatile boolean checking = true;
+ // number of variables with unexpected new values
+ public volatile int different = 0;
+
+ // tested method with local variables
+ public void testedMethod() {
+
+ // local variables
+ boolean booleanValue = OriginalValuesClass.booleanValue;
+ byte byteValue = OriginalValuesClass.byteValue;
+ char charValue = OriginalValuesClass.charValue;
+ int intValue = OriginalValuesClass.intValue;
+ short shortValue = OriginalValuesClass.shortValue;
+ long longValue = OriginalValuesClass.longValue;
+ float floatValue = OriginalValuesClass.floatValue;
+ double doubleValue = OriginalValuesClass.doubleValue;
+ String stringValue = OriginalValuesClass.stringValue;
+ Object objectValue = OriginalValuesClass.objectValue;
+
+ log.display("Tested frame entered");
+
+ // notify debuggee that tested thread ready for testing
+ synchronized (threadReady) {
+ threadReady.notifyAll();
+ }
+
+ // wait for lock object released
+ synchronized (threadLock) {
+ log.display("Checking that values have been set correctly:");
+ }
+
+ // check new values of local variables
+ if (checking) {
+
+ // check value of the variable
+ if (booleanValue != TargetValuesClass.booleanValue) {
+ different++;
+ log.complain(" booleanValue = " + booleanValue + "\n"
+ + " setting: " + OriginalValuesClass.booleanValue
+ + " -> " + TargetValuesClass.booleanValue);
+ if (booleanValue == OriginalValuesClass.booleanValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" booleanValue: " + OriginalValuesClass.booleanValue
+ + " -> " + TargetValuesClass.booleanValue);
+ }
+
+ // check value of the variable
+ if (byteValue != TargetValuesClass.byteValue) {
+ different++;
+ log.complain(" byteValue = " + byteValue + "\n"
+ + " setting: " + OriginalValuesClass.byteValue
+ + " -> " + TargetValuesClass.byteValue);
+ if (byteValue == OriginalValuesClass.byteValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" byteValue: " + OriginalValuesClass.byteValue
+ + " -> " + TargetValuesClass.byteValue);
+ }
+
+ // check value of the variable
+ if (charValue != TargetValuesClass.charValue) {
+ different++;
+ log.complain(" charValue = " + charValue + "\n"
+ + " setting: " + OriginalValuesClass.charValue
+ + " -> " + TargetValuesClass.charValue);
+ if (charValue == OriginalValuesClass.charValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" charValue: " + OriginalValuesClass.charValue
+ + " -> " + TargetValuesClass.charValue);
+ }
+
+ // check value of the variable
+ if (intValue != TargetValuesClass.intValue) {
+ different++;
+ log.complain(" intValue = " + intValue + "\n"
+ + " setting: " + OriginalValuesClass.intValue
+ + " -> " + TargetValuesClass.intValue);
+ if (intValue == OriginalValuesClass.intValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" intValue: " + OriginalValuesClass.intValue
+ + " -> " + TargetValuesClass.intValue);
+ }
+
+ // check value of the variable
+ if (shortValue != TargetValuesClass.shortValue) {
+ different++;
+ log.complain(" shortValue = " + shortValue + "\n"
+ + " setting: " + OriginalValuesClass.shortValue
+ + " -> " + TargetValuesClass.shortValue);
+ if (shortValue == OriginalValuesClass.shortValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" shortValue: " + OriginalValuesClass.shortValue
+ + " -> " + TargetValuesClass.shortValue);
+ }
+
+ // check value of the variable
+ if (longValue != TargetValuesClass.longValue) {
+ different++;
+ log.complain(" longValue = " + longValue + "\n"
+ + " setting: " + OriginalValuesClass.longValue
+ + " -> " + TargetValuesClass.longValue);
+ if (longValue == OriginalValuesClass.longValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" longValue: " + OriginalValuesClass.longValue
+ + " -> " + TargetValuesClass.longValue);
+ }
+
+ // check value of the variable
+ if (floatValue != TargetValuesClass.floatValue) {
+ different++;
+ log.complain(" floatValue = " + floatValue + "\n"
+ + " setting: " + OriginalValuesClass.floatValue
+ + " -> " + TargetValuesClass.floatValue);
+ if (floatValue == OriginalValuesClass.floatValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" floatValue: " + OriginalValuesClass.floatValue
+ + " -> " + TargetValuesClass.floatValue);
+ }
+
+ // check value of the variable
+ if (doubleValue != TargetValuesClass.doubleValue) {
+ different++;
+ log.complain(" doubleValue = " + doubleValue + "\n"
+ + " setting: " + OriginalValuesClass.doubleValue
+ + " -> " + TargetValuesClass.doubleValue);
+ if (doubleValue == OriginalValuesClass.doubleValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" doubleValue: " + OriginalValuesClass.doubleValue
+ + " -> " + TargetValuesClass.doubleValue);
+ }
+
+ // check value of the variable
+ if (stringValue != TargetValuesClass.stringValue) {
+ different++;
+ log.complain(" stringValue = " + stringValue + "\n"
+ + " setting: " + OriginalValuesClass.stringValue
+ + " -> " + TargetValuesClass.stringValue);
+ if (stringValue == OriginalValuesClass.stringValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" stringValue: " + OriginalValuesClass.stringValue
+ + " -> " + TargetValuesClass.stringValue);
+ }
+
+ // check value of the variable
+ if (objectValue != TargetValuesClass.objectValue) {
+ different++;
+ log.complain(" objectValue = " + objectValue + "\n"
+ + " setting: " + OriginalValuesClass.objectValue
+ + " -> " + TargetValuesClass.objectValue);
+ if (objectValue == OriginalValuesClass.objectValue) {
+ log.complain(" not changed!");
+ } else {
+ log.complain(" changed incorrectly!");
+ }
+ } else {
+ log.display(" objectValue: " + OriginalValuesClass.objectValue
+ + " -> " + TargetValuesClass.objectValue);
+ }
+ }
+
+ log.display("Tested frame dropped");
+ }
+
+ }
+
+ // class with the original values of static fields
+ public static class OriginalValuesClass {
+ static final boolean booleanValue = true;
+ static final byte byteValue = (byte)0x01;
+ static final char charValue = 'Z';
+ static final int intValue = 100;
+ static final short shortValue = (short)10;
+ static final long longValue = (long)1000000;
+ static final float floatValue = (float)3.14;
+ static final double doubleValue = (double)2.8e-12;
+ static final String stringValue = "text";
+ static final Object objectValue = new OriginalValuesClass();
+ }
+
+ // class with the original values of static fields
+ public static class TargetValuesClass {
+ static final boolean booleanValue = false;
+ static final byte byteValue = (byte)0x0F;
+ static final char charValue = 'A';
+ static final int intValue = 999;
+ static final short shortValue = (short)88;
+ static final long longValue = (long)11111111;
+ static final float floatValue = (float)7.19;
+ static final double doubleValue = (double)4.6e24;
+ static final String stringValue = "new text";
+ static final Object objectValue = new TargetValuesClass();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/ThisObject/thisobject001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,369 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.StackFrame.ThisObject;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: StackFrame.ThisObject.
+ *
+ * See thisobject001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class thisobject001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String ERROR = "error";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.StackFrame.ThisObject";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "thisobject001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "StackFrame.ThisObject";
+ static final int JDWP_COMMAND_ID = JDWP.Command.StackFrame.ThisObject;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + thisobject001a.OBJECT_CLASS_NAME;
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // names of the static fields with the tested thread and object values
+ static final String TESTED_OBJECT_FIELD_NAME = thisobject001a.OBJECT_FIELD_NAME;
+ static final String TESTED_THREAD_FIELD_NAME = thisobject001a.THREAD_FIELD_NAME;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new thisobject001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ long threadID = 0;
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for objectID value from static field
+ log.display("Getting objectID value from static field: "
+ + TESTED_OBJECT_FIELD_NAME);
+ long objectID = queryObjectID(classID, TESTED_OBJECT_FIELD_NAME, JDWP.Tag.OBJECT);
+ log.display(" got objectID: " + objectID);
+
+ // query debuggee for threadID value from static field
+ log.display("Getting threadID value from static field: "
+ + TESTED_THREAD_FIELD_NAME);
+ threadID = queryObjectID(classID, TESTED_THREAD_FIELD_NAME, JDWP.Tag.THREAD);
+ log.display(" got threadID: " + threadID);
+
+ // suspend tested thread into debuggee
+ log.display("Suspending thread into debuggee for threadID: " + threadID);
+ debugee.suspendThread(threadID);
+
+ // query debuggee for current frameID of the tested thread
+ log.display("Getting current frameID for the threadID: "
+ + threadID);
+ long frameID = debugee.getCurrentFrameID(threadID);
+ log.display(" got frameID: " + frameID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(frameID, threadID, objectID);
+
+ } finally {
+ log.display("\n>>> Finishing test \n");
+
+ // resume suspended thread
+ if (threadID != 0) {
+ log.display("Resuming suspended thread");
+ debugee.resumeThread(threadID);
+ }
+
+ // quit debugee
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ } else if (signal.equals(ERROR)) {
+ throw new TestBug("Debugee was not able to start tested thread"
+ + " (received signal: " + signal + ")");
+ } else if (!signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for objectID value of static field of the class.
+ */
+ long queryObjectID(long classID, String fieldName, byte tag) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has expected tag
+ if (value.getTag() != tag) {
+ throw new Failure("Unexpected tag for object value returned: "
+ + value.getTag() + " (expected: " + tag + ")");
+ }
+
+ // extract objectID from the value
+ long objectID = ((Long)value.getValue()).longValue();
+ return objectID;
+ }
+
+ /**
+ * Perform testing JDWP command for specified frameID.
+ */
+ void testCommand(long frameID, long threadID, long expectedObjectID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" threadID: " + threadID);
+ command.addObjectID(threadID);
+ log.display(" frameID: " + frameID);
+ command.addFrameID(frameID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract tag of object value
+ byte tag = (byte)0;
+ try {
+ tag = reply.getByte();
+ log.display(" tag: " + tag);
+ } catch (BoundException e) {
+ log.complain("Unable to extract object tag from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // extract objectID of object value
+ long objectID = 0;
+ try {
+ objectID = reply.getObjectID();
+ log.display(" objectID: " + objectID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract objectID from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ // check that object tag is as expected
+ if (tag != JDWP.Tag.OBJECT) {
+ log.complain("Unexpected object tag returned: "
+ + tag + " (expected: " + JDWP.Tag.OBJECT + ")");
+ success = false;
+ }
+
+ // check that objectID is as expected
+ if (objectID < 0) {
+ log.complain("Negative value of objectID retured: "
+ + objectID + " (expected: " + expectedObjectID + ")");
+ success = false;
+ } else if (objectID != expectedObjectID) {
+ log.complain(" Unexpected objectID retured: "
+ + objectID + " (expected: " + expectedObjectID + ")");
+ success = false;
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/ThisObject/thisobject001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/StackFrame/ThisObject/thisobject001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: StackFrame
+ * command: ThisObject
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * returned objectID for current test frame is the same as expected.
+ * Test consists of two compoments:
+ * debugger: thisobject001
+ * debuggee: thisobject001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains from debuggee classID for tested class
+ * and object ID and threadID as values of the class static fields.
+ * Also debugger suspends the thread and gets frameID for the
+ * current thread frameID. Thread is suspended on the invokation
+ * of method of the tested object.
+ * Then, debugger creates command packet for StackFrame.ThisObject
+ * command with the found threadID and frameID as arguments, writes
+ * packet to the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts requested objectID. Also test checks that returned objectID
+ * has the expected tag and value.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.StackFrame.ThisObject.thisobject001
+ * nsk.jdwp.StackFrame.ThisObject.thisobject001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.StackFrame.ThisObject.thisobject001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/ThisObject/thisobject001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.StackFrame.ThisObject;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class thisobject001a {
+
+ // name of the tested object and thread classes
+ public static final String OBJECT_CLASS_NAME = "TestedObjectClass";
+ public static final String THREAD_CLASS_NAME = "TestedThreadClass";
+ public static final String THREAD_NAME = "TestedThreadName";
+
+ // name of the static fields with the tested object values
+ public static final String THREAD_FIELD_NAME = "thread";
+ public static final String OBJECT_FIELD_NAME = "object";
+
+ // notification object to notify debuggee that thread is ready
+ private static Object threadReady = new Object();
+ // lock object to prevent thread from exit
+ private static Object threadLock = new Object();
+
+ // scaffold objects
+ private static volatile ArgumentHandler argumentHandler = null;
+ private static volatile Log log = null;
+
+ public static void main(String args[]) {
+ thisobject001a _thisobject001a = new thisobject001a();
+ System.exit(thisobject001.JCK_STATUS_BASE + _thisobject001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // lock the object to prevent thread from exit
+ synchronized (threadLock) {
+
+ // load tested class and create tested thread and object
+ log.display("Creating object of tested class");
+ TestedObjectClass.object = new TestedObjectClass();
+ log.display("Creating tested thread");
+ TestedObjectClass.thread = new TestedThreadClass(THREAD_NAME);
+
+ // start the thread and wait for notification from it
+ synchronized (threadReady) {
+ TestedObjectClass.thread.start();
+ try {
+ threadReady.wait();
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + thisobject001.READY);
+ pipe.println(thisobject001.READY);
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for thread started: " + e);
+ pipe.println(thisobject001.ERROR);
+ }
+ }
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + thisobject001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(thisobject001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + thisobject001.QUIT + ")");
+ log.complain("Debugee FAILED");
+ return thisobject001.FAILED;
+ }
+
+ // allow started thread to finish
+ }
+
+ // wait for tested thread finished
+ try {
+ log.display("Waiting for tested thread finished");
+ TestedObjectClass.thread.join();
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for tested thread finished:\n\t"
+ + e);
+ log.complain("Debugee FAILED");
+ return thisobject001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return thisobject001.PASSED;
+ }
+
+ // tested thread class
+ public static class TestedThreadClass extends Thread {
+
+ TestedThreadClass(String name) {
+ super(name);
+ }
+
+ public void run() {
+ log.display("Tested thread started");
+
+ // invoke tested method for the tested object from the tested thread
+ int foo = 100;
+ TestedObjectClass.object.testedMethod(foo);
+
+ log.display("Tested thread finished");
+ }
+
+ }
+
+ // tested object class
+ public static class TestedObjectClass {
+
+ // field with the tested thread and object values
+ public static volatile TestedThreadClass thread = null;
+ public static volatile TestedObjectClass object = null;
+
+ public void testedMethod(int foo) {
+ log.display("Tested frame entered");
+
+ // local variables
+ int boo = foo;
+
+ // notify debuggee that tested thread ready for testing
+ synchronized (threadReady) {
+ threadReady.notifyAll();
+ }
+
+ // wait for lock object released
+ synchronized (threadLock) {
+ log.display("Tested frame dropped");
+ }
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StringReference/Value/value001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.StringReference.Value;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+import java.util.*;
+
+public class value001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.StringReference.Value";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "value001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "StringReference.Value";
+ static final int JDWP_COMMAND_ID = JDWP.Command.StringReference.Value;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new value001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ try {
+
+ // create string in debugee
+
+ String originalStringValue = "Testing string value";
+ long stringID = 0;
+
+ {
+ // Suspend debuggee to avoid GC
+ log.display("Suspending debuggee");
+ debugee.suspend();
+ log.display("Debuggee suspended");
+
+ log.display("Create command packet" + "CreateString"
+ + " with string value: " + originalStringValue);
+ CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.CreateString);
+ command.addString(originalStringValue);
+ command.setLength();
+
+ log.display("Waiting for reply to command");
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+ log.display("Valid reply packet received");
+
+ log.display("Parsing reply packet");
+ reply.resetPosition();
+
+ stringID = reply.getObjectID();
+ log.display(" stringID: " + stringID);
+
+ // Disable garbage collection of the String
+ log.display("Disabling collection of String object");
+ command = new CommandPacket(JDWP.Command.ObjectReference.DisableCollection);
+ command.addObjectID(stringID);
+ command.setLength();
+ reply = debugee.receiveReplyFor(command);
+ reply.resetPosition();
+ log.display("Collection disabled");
+
+ // Resume debugee now that we have disabled collection of the String
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display("Debuggee resumed");
+ }
+
+ // begint test of JDWP command
+
+ log.display("Create command packet" + JDWP_COMMAND_NAME
+ + "with stringID: " + stringID);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addObjectID(stringID);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ String stringValue = reply.getString();
+ log.display(" stringValue: " + stringValue);
+
+ if (! stringValue.equals(originalStringValue)) {
+ log.complain("Received value does not equals original value:"
+ + originalStringValue);
+ success = false;
+ }
+
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ success = false;
+ } else {
+ log.display("Reply packet parsed successfully");
+ }
+
+ // end test of JDWP command
+
+ // Re-enable garbage collection of the String
+ log.display("Enabling collection of String object");
+ command = new CommandPacket(JDWP.Command.ObjectReference.EnableCollection);
+ command.addObjectID(stringID);
+ command.setLength();
+ reply = debugee.receiveReplyFor(command);
+ reply.resetPosition();
+ log.display("Collection enabled");
+
+ } catch (Exception e) {
+ log.complain("Caught exception while testing JDWP command: " + e);
+ success = false;
+ } finally {
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception while communicating with debugee: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Caught unexpected exception while starting the test: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StringReference/Value/value001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/StringReference/Value/value001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: StringReference
+ * command: Value
+ * Test checks that debugee accept command and replies
+ * with correct reply packet. Also test checks that
+ * returned value of the requested string is equal
+ * to the expected one.
+ * First, test launches debuggee VM using support classes
+ * and connects to it.
+ * Then test queries debugee VM to create string with given vaule
+ * and saves stringID of created string.
+ * Then test sends Value command with saved stringID
+ * as an command argument and waits for a reply packet.
+ * Then test checks if the received reply packet has proper
+ * structure and extracted string value is equal to
+ * the expected string.
+ * After JDWP command has been tested, test sends debugee VM
+ * signal to quit, waits for debugee exits and exits too
+ * with a proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.StringReference.Value.value001
+ * nsk.jdwp.StringReference.Value.value001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.StringReference.Value.value001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StringReference/Value/value001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.StringReference.Value;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class value001a {
+
+ public static void main(String args[]) {
+ value001a _value001a = new value001a();
+ System.exit(value001.JCK_STATUS_BASE + _value001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return value001.PASSED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Children/children001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadGroupReference.Children;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class children001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.ThreadGroupReference.Children";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "children001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "ThreadGroupReference.Children";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ThreadGroupReference.Children;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new children001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+
+ try {
+
+ // get top level thread groups
+
+ log.display("Getting IDs for top level thread groups");
+
+ long[] threadGroupIDs = null;
+ int groups = 0;
+
+ {
+ log.display("Create command packet " + "TopLevelThreadGroups");
+ CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.TopLevelThreadGroups);
+
+ log.display("Waiting for reply to command");
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+ log.display("Valid reply packet received");
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ groups = reply.getInt();
+ log.display(" groups: " + groups);
+
+ threadGroupIDs = new long[groups];
+
+ for (int i = 0; i < groups; i++) {
+ long threadGroupID = reply.getObjectID();
+ log.display(" " + i + " threadGroupID: " + threadGroupID);
+ threadGroupIDs[i] = threadGroupID;
+ }
+
+ if (groups < 0) {
+ log.complain("Negative number of thread groups returned while getting top level thread groups IDs: " + groups);
+ success = false;
+ }
+
+ if (groups == 0) {
+ log.complain("No thread groups IDs returned while getting top level thread groups IDs: " + groups);
+ success = false;
+ }
+
+ }
+
+ // begin test of JDWP command
+
+ for (int i = 0; i < groups; i++) {
+
+ long threadGroupID = threadGroupIDs[i];
+
+ log.display("Getting name for " + i + " group ID: "
+ + threadGroupID);
+
+ log.display("Create command " + JDWP_COMMAND_NAME
+ + " with thread group ID: " + threadGroupID);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addObjectID(threadGroupID);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ int childThreads = reply.getInt();
+ log.display(" childThreads: " + childThreads);
+
+ for (int j = 0; j < childThreads; j++) {
+ long childThread = reply.getObjectID();
+ log.display(" " + j + " childThread: " + childThread);
+ }
+
+ int childGroups = reply.getInt();
+ log.display(" childGroups: " + childGroups);
+
+ for (int j = 0; j < childGroups; j++) {
+ long childGroup = reply.getObjectID();
+ log.display(" " + j + " childGroup: " + childGroup);
+ }
+
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ success = false;
+ } else {
+ log.display("Reply packet parsed successfully");
+ }
+ }
+
+ // end test of JDWP command
+
+ } catch (Exception e) {
+ log.complain("Caught exception while testing JDWP command: " + e);
+ success = false;
+ } finally {
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception while communicating with debugee: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Caught unexpected exception while starting the test: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Children/children001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ThreadGroupReference/Children/children001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ThreadGroupReference
+ * command: Children
+ * Test checks that debugee accepts command and replies
+ * with correct reply packet.
+ * First, test launches debuggee VM using support classes
+ * and connects to it.
+ * Then test queries debugee VM for ThreadGroupReferenceIDs
+ * of all top level thread groups.
+ * Then test sends Children command for each ThreadGroupReferenceID
+ * and waits for a reply packet.
+ * Test checks if the each received reply packet has proper
+ * structure and extract childs info of the queried thread group.
+ * After JDWP command has been tested, test sends debugee VM
+ * signal to quit, waits for debugee exits and exits too
+ * with a proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ThreadGroupReference.Children.children001
+ * nsk.jdwp.ThreadGroupReference.Children.children001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ThreadGroupReference.Children.children001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Children/children001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadGroupReference.Children;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class children001a {
+
+ public static void main(String args[]) {
+ children001a _children001a = new children001a();
+ System.exit(children001.JCK_STATUS_BASE + _children001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return children001.PASSED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Name/name001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadGroupReference.Name;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class name001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.ThreadGroupReference.Name";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "name001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "ThreadGroupReference.Name";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ThreadGroupReference.Name;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new name001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+
+ try {
+
+ // get top level thread groups
+
+ log.display("Getting IDs for top level thread groups");
+
+ long[] threadGroupIDs = null;
+ int groups = 0;
+
+ {
+ log.display("Create command packet " + "TopLevelThreadGroups");
+ CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.TopLevelThreadGroups);
+
+ log.display("Waiting for reply to command");
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+ log.display("Valid reply packet received");
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ groups = reply.getInt();
+ log.display(" groups: " + groups);
+
+ threadGroupIDs = new long[groups];
+
+ for (int i = 0; i < groups; i++) {
+ long threadGroupID = reply.getObjectID();
+ log.display(" " + i + " threadGroupID: " + threadGroupID);
+ threadGroupIDs[i] = threadGroupID;
+ }
+
+ if (groups < 0) {
+ log.complain("Negative number of thread groups returned while getting top level thread groups IDs: " + groups);
+ success = false;
+ }
+
+ if (groups == 0) {
+ log.complain("No thread groups IDs returned while getting top level thread groups IDs: " + groups);
+ success = false;
+ }
+
+ }
+
+ // begin test of JDWP command
+
+ for (int i = 0; i < groups; i++) {
+
+ long threadGroupID = threadGroupIDs[i];
+
+ log.display("Getting name for " + i + " group ID: "
+ + threadGroupID);
+
+ log.display("Create command " + JDWP_COMMAND_NAME
+ + " with thread group ID: " + threadGroupID);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addObjectID(threadGroupID);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ String groupName = reply.getString();
+ log.display(" groupName: " + groupName);
+
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ success = false;
+ } else {
+ log.display("Reply packet parsed successfully");
+ }
+ }
+
+ // end test of JDWP command
+
+ } catch (Exception e) {
+ log.complain("Caught exception while testing JDWP command: " + e);
+ success = false;
+ } finally {
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception while communicating with debugee: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Caught unexpected exception while starting the test: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Name/name001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ThreadGroupReference/Name/name001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ThreadGroupReference
+ * command: Name
+ * Test checks that debugee accepts command and replies
+ * with correct reply packet.
+ * First, test launches debuggee VM using support classes
+ * and connects to it.
+ * Then test queries debugee VM for ThreadGroupReferenceIDs
+ * of all top level thread groups.
+ * Then test sends Name command for each ThreadGroupReferenceID
+ * and waits for a reply packet.
+ * Test checks if the each received reply packet has proper
+ * structure and extract name of the queried thread group.
+ * After JDWP command has been tested, test sends debugee VM
+ * signal to quit, waits for debugee exits and exits too
+ * with a proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ThreadGroupReference.Name.name001
+ * nsk.jdwp.ThreadGroupReference.Name.name001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ThreadGroupReference.Name.name001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Name/name001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadGroupReference.Name;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class name001a {
+
+ public static void main(String args[]) {
+ name001a _name001a = new name001a();
+ System.exit(name001.JCK_STATUS_BASE + _name001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return name001.PASSED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Parent/parent001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadGroupReference.Parent;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class parent001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.ThreadGroupReference.Parent";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "parent001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "ThreadGroupReference.Parent";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ThreadGroupReference.Parent;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new parent001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+
+ try {
+
+ // get top level thread groups
+
+ log.display("Getting IDs for top level thread groups");
+
+ long[] threadGroupIDs = null;
+ int groups = 0;
+
+ {
+ log.display("Create command packet " + "TopLevelThreadGroups");
+ CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.TopLevelThreadGroups);
+
+ log.display("Waiting for reply to command");
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+ log.display("Valid reply packet received");
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ groups = reply.getInt();
+ log.display(" groups: " + groups);
+
+ threadGroupIDs = new long[groups];
+
+ for (int i = 0; i < groups; i++) {
+ long threadGroupID = reply.getObjectID();
+ log.display(" " + i + " threadGroupID: " + threadGroupID);
+ threadGroupIDs[i] = threadGroupID;
+ }
+
+ if (groups < 0) {
+ log.complain("Negative number of thread groups returned while getting top level thread groups IDs: " + groups);
+ success = false;
+ }
+
+ if (groups == 0) {
+ log.complain("No thread groups IDs returned while getting top level thread groups IDs: " + groups);
+ success = false;
+ }
+
+ }
+
+ // begin test of JDWP command
+
+ for (int i = 0; i < groups; i++) {
+
+ long threadGroupID = threadGroupIDs[i];
+
+ log.display("Getting name for " + i + " group ID: "
+ + threadGroupID);
+
+ log.display("Create command " + JDWP_COMMAND_NAME
+ + " with thread group ID: " + threadGroupID);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addObjectID(threadGroupID);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ long parentGroup = reply.getObjectID();
+ log.display(" parentGroup: " + parentGroup);
+
+ if (parentGroup != 0) {
+ log.complain("Nonzero ThreadGroupID of parent thread group returned for top-level thread group");
+ success = false;
+ }
+
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ success = false;
+ } else {
+ log.display("Reply packet parsed successfully");
+ }
+ }
+
+ // end test of JDWP command
+
+ } catch (Exception e) {
+ log.complain("Caught exception while testing JDWP command: " + e);
+ success = false;
+ } finally {
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception while communicating with debugee: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Caught unexpected exception while starting the test: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Parent/parent001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ThreadGroupReference/Parent/parent001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ThreadGroupReference
+ * command: Parent
+ * Test checks that debugee accepts command and replies
+ * with correct reply packet. Also test check that returned
+ * parent ThreadGroupID for top-level group is equal to zero.
+ * First, test launches debuggee VM using support classes
+ * and connects to it.
+ * Then test queries debugee VM for ThreadGroupReferenceIDs
+ * of all top level thread groups.
+ * Then test sends Parent command for each ThreadGroupReferenceID
+ * and waits for a reply packet.
+ * Test checks if the each received reply packet has proper
+ * structure and extract childs info of the queried thread group.
+ * Also test check that extracted parent ThreadGroupID for
+ * top-level group is equal to zero.
+ * After JDWP command has been tested, test sends debugee VM
+ * signal to quit, waits for debugee exits and exits too
+ * with a proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ThreadGroupReference.Parent.parent001
+ * nsk.jdwp.ThreadGroupReference.Parent.parent001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ThreadGroupReference.Parent.parent001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadGroupReference/Parent/parent001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadGroupReference.Parent;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class parent001a {
+
+ public static void main(String args[]) {
+ parent001a _parent001a = new parent001a();
+ System.exit(parent001.JCK_STATUS_BASE + _parent001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return parent001.PASSED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/CurrentContendedMonitor/curcontmonitor001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.CurrentContendedMonitor;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ThreadReference.CurrentContendedMonitor.
+ *
+ * See curcontmonitor001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class curcontmonitor001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String ERROR = "error";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ThreadReference.CurrentContendedMonitor";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "curcontmonitor001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // VM capability constatnts
+ static final int VM_CAPABILITY_NUMBER = JDWP.Capability.CAN_GET_CURRENT_CONTENDED_MONITOR;
+ static final String VM_CAPABILITY_NAME = "canGetCurrentContendedMonitor";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ThreadReference.CurrentContendedMonitor";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ThreadReference.CurrentContendedMonitor;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the tested thread and statioc field with thread value
+ static final String TESTED_THREAD_NAME = curcontmonitor001a.THREAD_NAME;
+ static final String THREAD_FIELD_NAME = curcontmonitor001a.THREAD_FIELD_NAME;
+ static final String MONITOR_FIELD_NAME = curcontmonitor001a.MONITOR_FIELD_NAME;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new curcontmonitor001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ long threadID = 0;
+ try {
+ log.display("\n>>> Checking VM capability \n");
+
+ // check for VM capability
+ log.display("Checking VM capability: " + VM_CAPABILITY_NAME);
+ if (!debugee.getCapability(VM_CAPABILITY_NUMBER, VM_CAPABILITY_NAME)) {
+ out.println("TEST PASSED: unsupported VM capability: "
+ + VM_CAPABILITY_NAME);
+ return PASSED;
+ }
+
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for threadID value from a static field
+ log.display("Getting threadID value from static field: "
+ + THREAD_FIELD_NAME);
+ threadID = queryObjectID(classID, THREAD_FIELD_NAME, JDWP.Tag.THREAD);
+ log.display(" got threadID: " + threadID);
+
+ // query debuggee for objectID value for owned monitor from a static field
+ log.display("Getting objectID value for owned monitor from static field: "
+ + MONITOR_FIELD_NAME);
+ long monitorID = queryObjectID(classID,
+ MONITOR_FIELD_NAME, JDWP.Tag.OBJECT);
+ log.display(" got objectID: " + monitorID);
+
+ // suspend all threads into debuggee
+ log.display("Suspending all threads into debuggee");
+ debugee.suspend();
+ log.display(" debuggee suspended");
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(threadID, monitorID);
+
+ } finally {
+ log.display("\n>>> Finishing test \n");
+
+ // resume all threads into debuggee
+ log.display("resuming all threads into debuggee");
+ debugee.resume();
+ log.display(" debuggee resumed");
+
+ // quit debugee
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ } else if (signal.equals(ERROR)) {
+ throw new TestBug("Debugee was not able to start tested thread"
+ + " (received signal: " + signal + ")");
+ } else if (!signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for objectID value of static class field.
+ */
+ long queryObjectID(long classID, String fieldName, byte tag) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != tag) {
+ throw new Failure("Wrong objectID tag received from field \"" + fieldName
+ + "\": " + value.getTag() + " (expected: " + tag + ")");
+ }
+
+ // extract threadID from the value
+ long objectID = ((Long)value.getValue()).longValue();
+ return objectID;
+ }
+
+ /**
+ * Perform testing JDWP command for specified threadID.
+ */
+ void testCommand(long threadID, long monitorID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" threadID: " + threadID);
+ command.addObjectID(threadID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract object tag
+ byte tag = (byte)0;
+ try {
+ tag = reply.getByte();
+ log.display(" tag: " + tag);
+ } catch (BoundException e) {
+ log.complain("Unable to extract tag for contended monitor object from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // extract objectID
+ long objectID = 0;
+ try {
+ objectID = reply.getObjectID();
+ log.display(" objectID: " + objectID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract contended monitor objectID from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that tag is an OBJECT tag
+ if (tag != JDWP.Tag.OBJECT) {
+ log.complain("Unexpected tag for monitor object received:" + tag
+ + " (expected" + JDWP.Tag.OBJECT);
+ success = false;
+ }
+
+ // check that objectID is not negative integer
+ if (objectID < 0) {
+ log.complain("Negative value of objectID received: " + objectID);
+ success = false;
+ }
+
+ // check that objectID is as expected
+ if (objectID != monitorID) {
+ log.display("Unexpected monitor objectID received: " + objectID
+ + " (expected" + monitorID);
+ success = false;
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/CurrentContendedMonitor/curcontmonitor001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ThreadReference/CurrentContendedMonitor/curcontmonitor001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ThreadReference
+ * command: CurrentContendedMonitor
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Also test checks that the expected objectID of monitor object
+ * returned for the tested thread.
+ * Test consists of two compoments:
+ * debugger: curcontmonitor001
+ * debuggee: curcontmonitor001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains from debuggee classID for tested thread class
+ * and threadID as the value of a class static field. Also debugger
+ * suspends the thread before sending the tested command. The tested
+ * thread is waiting for the object at this moment.
+ * Then, debugger creates command packet for ThreadReference.CurrenContendedMonitor
+ * command with the found threadID as an argument, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts objectID for the thread current contended monitor. Also
+ * test checks that the extracted objectID is equals to the expected one.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ * COMMENTS
+ * For JDK 1.4.0-beta3 (build 1.4.0-beta3-b84) and earlier this test passed
+ * because target VM does not support VM capability: canGetCurrentContendedMonitor
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ThreadReference.CurrentContendedMonitor.curcontmonitor001
+ * nsk.jdwp.ThreadReference.CurrentContendedMonitor.curcontmonitor001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ThreadReference.CurrentContendedMonitor.curcontmonitor001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/CurrentContendedMonitor/curcontmonitor001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.CurrentContendedMonitor;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class curcontmonitor001a {
+
+ // name for the tested thread
+ public static final String THREAD_NAME = "TestedThreadName";
+ public static final String THREAD_FIELD_NAME = "thread";
+ public static final String MONITOR_FIELD_NAME = "monitor";
+
+ // frames count for tested thread in recursive method invokation
+ public static final int FRAMES_COUNT = 10;
+
+ // notification object to notify debuggee that thread is started
+ private static Object threadStarting = new Object();
+ // object which thread will wait for before being interruted
+ private static Object threadWaiting = new Object();
+
+ // scaffold objects
+ private static volatile ArgumentHandler argumentHandler = null;
+ private static volatile Log log = null;
+
+ public static void main(String args[]) {
+ curcontmonitor001a _curcontmonitor001a = new curcontmonitor001a();
+ System.exit(curcontmonitor001.JCK_STATUS_BASE + _curcontmonitor001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+ long timeout = argumentHandler.getWaitTime() * 60 * 1000; // milliseconds
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // load tested class and create tested thread
+ log.display("Creating object of tested class");
+ TestedClass.thread = new TestedClass(THREAD_NAME);
+
+ // start the thread and wait for notification from it
+ synchronized (threadStarting) {
+ TestedClass.thread.start();
+ try {
+ threadStarting.wait();
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for thread started:\n\t" + e);
+ pipe.println(curcontmonitor001.ERROR);
+ log.display("Debugee FAILED");
+ return curcontmonitor001.FAILED;
+ }
+
+ // ensure that tested thread is waiting for monitor object
+ synchronized (TestedClass.thread.monitor) {
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + curcontmonitor001.READY);
+ pipe.println(curcontmonitor001.READY);
+ }
+ }
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + curcontmonitor001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // interrupt waiting thread
+ log.display("Interrupting tested thread being waited");
+ TestedClass.thread.interrupt();
+
+ // check received signal
+ if (signal == null || !signal.equals(curcontmonitor001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + curcontmonitor001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return curcontmonitor001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return curcontmonitor001.PASSED;
+ }
+
+ // tested thread class
+ public static class TestedClass extends Thread {
+
+ // field with the tested Thread value
+ public static volatile TestedClass thread = null;
+ // field with monitor object which thread will infinitively wait for
+ public static volatile Object monitor = new Object();
+
+ public TestedClass(String name) {
+ super(name);
+ }
+
+ // start the thread and recursive invoke makeFrames()
+ public void run() {
+ log.display("Tested thread started");
+
+ synchronized (monitor) {
+
+ // notify debuggee that thread started
+ synchronized (threadStarting) {
+ threadStarting.notifyAll();
+ }
+
+ // wait infinitely for monitor object
+ try {
+ monitor.wait();
+ } catch (InterruptedException e) {
+ log.display("Tested thread interrupted");
+ }
+ }
+
+ log.display("Tested thread finished");
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn001/forceEarlyReturn001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2007, 2018, 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 converted from VM Testbase nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn001.
+ * VM Testbase keywords: [jpda, jdwp, feature_jdk6_jpda, vm6, monitoring, quarantine]
+ * VM Testbase comments: JDK-7199837
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ThreadReference
+ * command: ForceEarlyReturn
+ * Test checks that debuggee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: forceEarlyReturn001
+ * debuggee: forceEarlyReturn001a
+ * Debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with execution commands.
+ * Debuggee VM create thread(class nsk.share.jpda.ForceEarlyReturnTestThread is used) which sequentially call
+ * test methods with different return value's type:
+ * - void
+ * - all primitive types
+ * - all wrappers of primitive types
+ * - String
+ * - Object
+ * - array of java.lang.Object
+ * - Thread
+ * - ThreadGroup
+ * - Class object
+ * - ClassLoader
+ * Also test thread class contains static fields with predefined values which should be returned through
+ * ForceEarlyReturn('expectedXXXValue') and fields with values which can be used to check is ForceEarlyReturn returns
+ * TYPE_MISMATCH error if value's type in command doesn't match method's return type('invalidXXXValue').
+ * Debugger set breakpoints in test thread's methods and create instances of 'nsk.share.jdwp.JDWP.Value'
+ * based on values predefined in ForceEarlyReturnTestThread (both valid and invalid values are created).
+ * Debugger obtains threadID for test thread.
+ * Debugger force debugee start test thread and wait while BreakpointEvents occurs. When debuggee's
+ * test thread stop at breakpoint debugger first creates command packet for ForceEarlyReturn command with the
+ * found threadID and corresponding instance of invalid 'nsk.share.jdwp.JDWP.Value', writes
+ * packet to the transport channel, and waits for a reply packet. When reply packet is received, debugger
+ * parses the packet structure and checks that reply contain TYPE_MISMATCH error. Then debugger send command
+ * with correct value, checks that reply is empty and resume debuggee VM.
+ * Test thread in debuggee VM checks that value returned from test methods equals predefined value and no
+ * instructions was executed in called method after force return (finally blocks are not executed too).
+ * When all breakpoint events occured debugger sends debuggee signal to finish test thread execution.
+ * Debuggee waits when test thread finish execution and checks is any errors occured during test.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ThreadReference.ForceEarlyReturn.forceEarlyReturn001.forceEarlyReturn001
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ThreadReference.ForceEarlyReturn.forceEarlyReturn001.forceEarlyReturn001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
+package nsk.jdwp.ThreadReference.ForceEarlyReturn.forceEarlyReturn001;
+
+import java.io.*;
+import nsk.share.Consts;
+import nsk.share.jdwp.*;
+import nsk.share.jdwp.JDWP.Value;
+import nsk.share.jpda.ForceEarlyReturnTestThread;
+
+public class forceEarlyReturn001
+extends TestDebuggerType1
+{
+ // data needed to create JDWP command,
+ // also this class create breakpoint in method which should be forced to return
+ class TestData
+ {
+ public TestData(long classID, String methodName, int lineNumber, long threadID, Value value, Value invalidValue)
+ {
+ breakpointID = debuggee.requestBreakpointEvent(
+ JDWP.TypeTag.CLASS,
+ classID,
+ debuggee.getMethodID(classID, methodName, true),
+ lineNumber,
+ JDWP.SuspendPolicy.EVENT_THREAD);
+
+ this.value = value;
+ this.invalidValue = invalidValue;
+ this.threadID = threadID;
+ }
+
+ public int breakpointID;
+ public Value value;
+ public Value invalidValue;
+ public long threadID;
+ }
+
+ protected String getDebugeeClassName()
+ {
+ return "nsk.jdwp.ThreadReference.ForceEarlyReturn.forceEarlyReturn001.forceEarlyReturn001a";
+ }
+
+ public static void main (String argv[])
+ {
+ System.exit(run(argv,System.out) + Consts.JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out)
+ {
+ return new forceEarlyReturn001().runIt(argv, out);
+ }
+
+ // send command and receive empty reply
+ // all asserts should be done in debuggee
+ private void sendCommand(long threadID, Value value, boolean expectError, int errorCode)
+ {
+ try
+ {
+ int JDWP_COMMAND_ID = JDWP.Command.ThreadReference.ForceEarlyReturn;
+
+ log.display("Create command: " + JDWP.commandNames.get(JDWP_COMMAND_ID));
+ log.display("threadID = " + threadID);
+ log.display("Value = " + value);
+
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addObjectID(threadID);
+ command.addValue(value);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ ReplyPacket reply;
+
+ reply = getReply(command, expectError, errorCode);
+
+ if(expectError)
+ return;
+
+ log.display("Empty reply");
+
+ if(!reply.isParsed())
+ {
+ setSuccess(false);
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ }
+ }
+ catch(Exception e)
+ {
+ setSuccess(false);
+ log.complain("Caught exception while testing JDWP command: " + e);
+ e.printStackTrace(log.getOutStream());
+ }
+ }
+
+ private TestData[] testData;
+
+ // create Value objects which should be send in command packet and
+ // initialize breapoints in tested methods
+ private void initTestData()
+ {
+ long classID = debuggee.getReferenceTypeID(createTypeSignature(ForceEarlyReturnTestThread.class.getName()));
+
+ Value testValues[] = new Value[ForceEarlyReturnTestThread.testedTypesNames.length + 1];
+ Value testInvalidValues[] = new Value[ForceEarlyReturnTestThread.testedTypesNames.length + 1];
+
+ testValues[0] = new JDWP.Value(JDWP.Tag.VOID, new Long(0));
+
+ for(int i = 1; i < ForceEarlyReturnTestThread.testedTypesNames.length; i++)
+ {
+ testValues[i] = debuggee.getStaticFieldValue(
+ classID,
+ debuggee.getClassFieldID(classID, "expected" + ForceEarlyReturnTestThread.testedTypesNames[i] + "Value", true));
+ }
+
+ for(int i = 0; i < ForceEarlyReturnTestThread.testedTypesNames.length; i++)
+ {
+ testInvalidValues[i] = debuggee.getStaticFieldValue(
+ classID,
+ debuggee.getClassFieldID(classID, "invalid" + ForceEarlyReturnTestThread.testedTypesNames[i] + "Value", true));
+ }
+
+ long threadID = debuggee.getThreadID(forceEarlyReturn001a.testThreadName);
+
+ testData = new TestData[ForceEarlyReturnTestThread.testedTypesNames.length];
+
+ for(int i = 0; i < ForceEarlyReturnTestThread.testedTypesNames.length; i++)
+ {
+ testData[i] = new TestData(classID,
+ ForceEarlyReturnTestThread.testedTypesNames[i] + "Method",
+ ForceEarlyReturnTestThread.breakpointLines[i],
+ threadID,
+ testValues[i],
+ testInvalidValues[i]);
+ }
+ }
+
+ public void doTest()
+ {
+ initTestData();
+
+ pipe.println(forceEarlyReturn001a.COMMAND_START_EXECUTION);
+
+ if(!isDebuggeeReady())
+ return;
+
+ for(int i = 0; i < testData.length; i++)
+ {
+ // wait when tested thread call method with breapoint
+ debuggee.waitForBreakpointEvent(testData[i].breakpointID);
+
+ log.display("Send invalid command: valid value: " + testData[i].value + " invalid value: " + testData[i].invalidValue);
+ // send ForceEarlyReturn command with invalid value
+ sendCommand(testData[i].threadID, testData[i].invalidValue, true, JDWP.Error.TYPE_MISMATCH);
+
+ log.display("Send valid command: valid value: " + testData[i].value);
+ // send ForceEarlyReturn command
+ sendCommand(testData[i].threadID, testData[i].value, false, 0);
+
+ // resume debuggee
+ debuggee.resume();
+ }
+
+ pipe.println(forceEarlyReturn001a.COMMAND_END_EXECUTION);
+
+ if(!isDebuggeeReady())
+ return;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn001/forceEarlyReturn001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2007, 2018, 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.
+ */
+package nsk.jdwp.ThreadReference.ForceEarlyReturn.forceEarlyReturn001;
+
+import nsk.share.TestBug;
+import nsk.share.jdwp.*;
+import nsk.share.jpda.ForceEarlyReturnTestThread;
+
+public class forceEarlyReturn001a extends AbstractJDWPDebuggee {
+ public static String testThreadName = "ForceEarlyReturnTestThread";
+
+ private ForceEarlyReturnTestThread testThread;
+
+ protected void init(String args[]) {
+ super.init(args);
+
+ // create instance of ForceEarlyReturnTestThread during initialization
+ // to let debugger obtain threadID for this thread
+ testThread = new ForceEarlyReturnTestThread(log, true, 1);
+ testThread.setName(testThreadName);
+ testThread.start();
+ }
+
+ public static String COMMAND_START_EXECUTION = "startExecution";
+
+ public static String COMMAND_END_EXECUTION = "endExecution";
+
+ public boolean parseCommand(String command) {
+ if (super.parseCommand(command))
+ return true;
+
+ // force ForceEarlyReturnTestThread start execution
+ if (command.equals(COMMAND_START_EXECUTION)) {
+ testThread.startExecuion();
+ return true;
+ } else
+ // wait when ForceEarlyReturnTestThread finish execution and check
+ // is any errors occured during test
+ if (command.equals(COMMAND_END_EXECUTION)) {
+ try {
+ testThread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace(log.getOutStream());
+ throw new TestBug("Unexpected exception: " + e);
+ }
+
+ if (!testThread.getSuccess()) {
+ setSuccess(false);
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public static void main(String args[]) {
+ new forceEarlyReturn001a().doTest(args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/forceEarlyReturn002.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2007, 2018, 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 converted from VM Testbase nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002.
+ * VM Testbase keywords: [quick, jpda, jdwp, feature_jdk6_jpda, vm6, monitoring]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ThreadReference
+ * command: ForceEarlyReturn
+ * Test checks that debuggee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: forceEarlyReturn002
+ * debuggee: forceEarlyReturn002a
+ * Debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with execution commands.
+ * Test performs checks for cases when incorrect data are send in command.
+ * Following cases are tested:
+ * - create command with threadID = 1, expect INVALID_OBJECT error
+ * - debuggee creates test thread which sequentially changes its state in following order:
+ * - thread not started
+ * - thread is running
+ * - thread is sleeping
+ * - thread in Object.wait()
+ * - thread wait on java monitor
+ * - thread is finished
+ * Debugger try execute command for this thread without thread suspending for states: thread running, thread sleeping,
+ * thread waiting, thread blocked, THREAD_NOT_SUSPENDED error is expected.
+ * When test thread has finish execution debugger suspends thread and call command for this thread, INVALID_THREAD
+ * error is expected, then, debugger resumes test thread and call command again, INVALID_THREAD error should
+ * be returned in reply.
+ * - debuggee starts test thread which executes infinite loop in native method, debugger calls command for
+ * this thread(without suspending) and expects THREAD_NOT_SUSPENDED error. Then, debugger suspends this thread
+ * and calls command again, OPAQUE_FRAME error is expected.
+ * - debugger creates ThreadStartEventRequest with suspend policy 'JDWP.SuspendPolicy.ALL' and forces debuggee start new thread.
+ * When ThreadStartEvent is received debugger obtains threadID from this event and calls command for this thread. Since
+ * just started thread has no frames yet NO_MORE_FRAMES error is expected.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ThreadReference.ForceEarlyReturn.forceEarlyReturn002.forceEarlyReturn002
+ * @run main/othervm/native PropertyResolvingWrapper
+ * nsk.jdwp.ThreadReference.ForceEarlyReturn.forceEarlyReturn002.forceEarlyReturn002
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
+package nsk.jdwp.ThreadReference.ForceEarlyReturn.forceEarlyReturn002;
+
+import java.io.*;
+
+import nsk.share.Consts;
+import nsk.share.jdwp.*;
+import nsk.share.jdwp.JDWP.Value;
+import nsk.share.jpda.AbstractDebuggeeTest;
+import nsk.share.jpda.StateTestThread;
+
+public class forceEarlyReturn002 extends TestDebuggerType1 {
+ protected String getDebugeeClassName() {
+ return "nsk.jdwp.ThreadReference.ForceEarlyReturn.forceEarlyReturn002.forceEarlyReturn002a";
+ }
+
+ public static void main(String argv[]) {
+ System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new forceEarlyReturn002().runIt(argv, out);
+ }
+
+ private void sendCommand(long threadID, Value value, boolean expectError, int errorCode) {
+ try {
+ int JDWP_COMMAND_ID = JDWP.Command.ThreadReference.ForceEarlyReturn;
+
+ log.display("Create command: " + JDWP.commandNames.get(JDWP_COMMAND_ID));
+ log.display("threadID = " + threadID);
+ log.display("Value = " + value);
+
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addObjectID(threadID);
+ command.addValue(value);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ ReplyPacket reply;
+
+ reply = getReply(command, expectError, errorCode);
+
+ if (expectError)
+ return;
+
+ log.display("Empty reply");
+
+ if (!reply.isParsed()) {
+ setSuccess(false);
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ }
+ } catch (Exception e) {
+ setSuccess(false);
+ log.complain("Caught exception while testing JDWP command: " + e);
+ e.printStackTrace(log.getOutStream());
+ }
+ }
+
+ private int createThreadStartEventRequest() {
+ try {
+ // create command packet and fill requred out data
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set);
+ command.addByte(JDWP.EventKind.THREAD_START);
+ command.addByte(JDWP.SuspendPolicy.ALL);
+ command.addInt(0);
+ command.setLength();
+
+ transport.write(command);
+
+ ReplyPacket reply;
+ reply = getReply(command);
+
+ int requestID = reply.getInt();
+
+ if (!reply.isParsed()) {
+ setSuccess(false);
+ log.complain("Extra trailing bytes found in request reply packet at: " + reply.offsetString());
+ return -1;
+ }
+
+ return requestID;
+ } catch (Exception e) {
+ setSuccess(false);
+ log.complain("Caught exception while testing JDWP command: " + e);
+ e.printStackTrace(log.getOutStream());
+
+ return -1;
+ }
+ }
+
+ public void doTest() {
+ Value value;
+
+ value = new Value(JDWP.Tag.INT, 0);
+ // create command with invalid trheadID, expect INVALID_OBJECT error
+ sendCommand(-1, value, true, JDWP.Error.INVALID_OBJECT);
+
+ // create StateTestThread
+ pipe.println(AbstractDebuggeeTest.COMMAND_CREATE_STATETESTTHREAD);
+
+ if (!isDebuggeeReady())
+ return;
+
+ // switch thread state to RUNNING to get threadID (can't get threadID
+ // when thread not running)
+ pipe.println(AbstractDebuggeeTest.COMMAND_NEXTSTATE_STATETESTTHREAD);
+
+ if (!isDebuggeeReady())
+ return;
+
+ long threadID = debuggee.getThreadID(AbstractDebuggeeTest.stateTestThreadName);
+
+ int state = 2;
+
+ // check following states: "RUNNING", "SLEEPING", "WAIT", "MONITOR"
+ while (state++ < StateTestThread.stateTestThreadStates.length) {
+ sendCommand(threadID, value, true, JDWP.Error.THREAD_NOT_SUSPENDED);
+
+ pipe.println(AbstractDebuggeeTest.COMMAND_NEXTSTATE_STATETESTTHREAD);
+
+ if (!isDebuggeeReady())
+ return;
+ }
+
+ // here thread has exited (state "ZOMBIE")
+ sendCommand(threadID, value, true, JDWP.Error.INVALID_THREAD);
+
+ // suspend thread, but also expect INVALID_THREAD error
+ debuggee.suspendThread(threadID);
+ sendCommand(threadID, value, true, JDWP.Error.INVALID_THREAD);
+
+ // create thread which executes native method
+ pipe.println(forceEarlyReturn002a.COMMAND_STOP_THREAD_IN_NATIVE);
+
+ if (!isDebuggeeReady())
+ return;
+
+ threadID = debuggee.getThreadID(forceEarlyReturn002a.testThreadInNativeName);
+
+ // thread in native not suspended, expect THREAD_NOT_SUSPENDED error
+ sendCommand(threadID, value, true, JDWP.Error.THREAD_NOT_SUSPENDED);
+
+ debuggee.suspendThread(threadID);
+ // suspended thread in native, expect OPAQUE_FRAME error
+ sendCommand(threadID, value, true, JDWP.Error.OPAQUE_FRAME);
+
+ // create request for ThreadStart event
+ int requestID = createThreadStartEventRequest();
+
+ // force debuggee start new thread
+ pipe.println(forceEarlyReturn002a.COMMAND_START_NEW_THREAD);
+
+ // receive ThreadStart event
+ EventPacket eventPacket = receiveSingleEvent(JDWP.EventKind.THREAD_START, requestID);
+
+ try {
+ threadID = eventPacket.getObjectID();
+
+ value = new Value(JDWP.Tag.VOID, 0);
+ // just started thread has no frames, expect NO_MORE_FRAMES error
+ sendCommand(threadID, value, true, JDWP.Error.NO_MORE_FRAMES);
+ } catch (Exception e) {
+ setSuccess(false);
+ log.complain("Caught exception while testing JDWP command: " + e);
+ e.printStackTrace(log.getOutStream());
+ }
+
+ clearRequest(JDWP.EventKind.THREAD_START, requestID);
+
+ debuggee.resume();
+
+ if (!isDebuggeeReady())
+ return;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/forceEarlyReturn002a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2007, 2018, 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.
+ */
+package nsk.jdwp.ThreadReference.ForceEarlyReturn.forceEarlyReturn002;
+
+import nsk.share.Consts;
+import nsk.share.jdwp.*;
+
+public class forceEarlyReturn002a extends AbstractJDWPDebuggee {
+ static {
+ try {
+ System.loadLibrary("forceEarlyReturn002a");
+ } catch (UnsatisfiedLinkError e) {
+ System.out.println("UnsatisfiedLinkError when load library 'forceEarlyReturn002a'");
+ e.printStackTrace(System.out);
+ System.exit(Consts.JCK_STATUS_BASE + Consts.TEST_FAILED);
+ }
+ }
+
+ public final static String testThreadInNativeName = "forceEarlyReturn002aTestThreadInNative";
+
+ public final static String COMMAND_STOP_THREAD_IN_NATIVE = "stopInNative";
+
+ public final static String COMMAND_START_NEW_THREAD = "startNewThread";
+
+ public boolean parseCommand(String command) {
+ if (super.parseCommand(command))
+ return true;
+
+ if (command.equals(COMMAND_STOP_THREAD_IN_NATIVE)) {
+ stopThreadInNative();
+
+ return true;
+ } else if (command.equals(COMMAND_START_NEW_THREAD)) {
+ Thread thread = new Thread(new Runnable() {
+ public void run() {
+ log.display("Thread exit");
+ }
+ });
+
+ thread.setName("forceEarlyReturn002a_NewThread");
+ thread.start();
+
+ return true;
+ }
+
+ return false;
+ }
+
+ private Thread testThreadInNative;
+
+ private void stopThreadInNative() {
+ testThreadInNative = new Thread(new Runnable() {
+ public void run() {
+ Thread.currentThread().setName(testThreadInNativeName);
+ log.display("Enter native method");
+ nativeMethod(forceEarlyReturn002a.this);
+ }
+ });
+
+ testThreadInNative.start();
+
+ while (!threadInNative)
+ Thread.yield();
+ }
+
+ public volatile boolean threadInNative;
+
+ private static native int nativeMethod(Object object);
+
+ public static void main(String args[]) {
+ new forceEarlyReturn002a().doTest(args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/libforceEarlyReturn002a.c Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2007, 2018, 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 "jni.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef JNI_ENV_PTR
+
+#ifdef __cplusplus
+#define JNI_ENV_ARG_2(x, y) y
+#define JNI_ENV_ARG_3(x, y, z) y, z
+#define JNI_ENV_ARG_4(x, y, z, a) y, z, a
+#define JNI_ENV_PTR(x) x
+#else
+#define JNI_ENV_ARG_2(x,y) x, y
+#define JNI_ENV_ARG_3(x, y, z) x, y, z
+#define JNI_ENV_ARG_4(x, y, z, a) x, y, z, a
+#define JNI_ENV_PTR(x) (*x)
+#endif
+
+#endif
+
+int always_true = 1;
+
+JNIEXPORT jint JNICALL
+Java_nsk_jdwp_ThreadReference_ForceEarlyReturn_forceEarlyReturn002_forceEarlyReturn002a_nativeMethod(JNIEnv *env, jobject classObject, jobject object)
+{
+ int dummy_counter = 0;
+ // notify another thread that thread in native method
+ jclass klass = JNI_ENV_PTR(env)->GetObjectClass(JNI_ENV_ARG_2(env, object));
+ jfieldID field = JNI_ENV_PTR(env)->GetFieldID(JNI_ENV_ARG_4(env, klass, "threadInNative", "Z"));
+ JNI_ENV_PTR(env)->SetBooleanField(JNI_ENV_ARG_4(env, object, field, 1));
+
+ // execute infinite loop to be sure that thread in native method
+ while(always_true)
+ {
+ // Need some dummy code so the optimizer does not remove this loop.
+ dummy_counter = dummy_counter < 1000 ? 0 : dummy_counter + 1;
+ }
+ // The optimizer can be surprisingly clever.
+ // Use dummy_counter so it can never be optimized out.
+ // This statement will always return 0.
+ return dummy_counter >= 0 ? 0 : 1;
+}
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/FrameCount/framecnt001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.FrameCount;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ThreadReference.FrameCount.
+ *
+ * See framecnt001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class framecnt001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String ERROR = "error";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ThreadReference.FrameCount";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "framecnt001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ThreadReference.FrameCount";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ThreadReference.FrameCount;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the tested thread and statioc field with thread value
+ static final String TESTED_CLASS_FIELD_NAME = framecnt001a.FIELD_NAME;
+ static final String TESTED_THREAD_NAME = framecnt001a.THREAD_NAME;
+
+ // expected number of frames count
+ static final int FRAMES_COUNT = framecnt001a.FRAMES_COUNT;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new framecnt001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ long threadID = 0;
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for threadID value from a static field
+ log.display("Getting threadID value from static field: "
+ + TESTED_CLASS_FIELD_NAME);
+ threadID = queryThreadID(classID, TESTED_CLASS_FIELD_NAME);
+ log.display(" got threadID: " + threadID);
+
+ // suspend tested thread into debyggee
+ log.display("Suspending thread into debuggee for threadID: " + threadID);
+ debugee.suspendThread(threadID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(threadID);
+
+ } finally {
+ log.display("\n>>> Finishing test \n");
+
+ // resume suspended thread
+ if (threadID != 0) {
+ log.display("Resuming suspended thread");
+ debugee.resumeThread(threadID);
+ }
+
+ // quit debugee
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ } else if (signal.equals(ERROR)) {
+ throw new TestBug("Debugee was not able to start tested thread"
+ + " (received signal: " + signal + ")");
+ } else if (!signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for threadID value of statuic field of the class.
+ */
+ long queryThreadID(long classID, String fieldName) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != JDWP.Tag.THREAD) {
+ throw new Failure("Not threadID value returned from debuggee: " + value);
+ }
+
+ // extract threadID from the value
+ long threadID = ((Long)value.getValue()).longValue();
+ return threadID;
+ }
+
+ /**
+ * Perform testing JDWP command for specified threadID.
+ */
+ void testCommand(long threadID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" threadID: " + threadID);
+ command.addObjectID(threadID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract frames count
+ int frameCount = 0;
+ try {
+ frameCount = reply.getInt();
+ log.display(" frameCount: " + frameCount);
+ } catch (BoundException e) {
+ log.complain("Unable to extract frames count from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that frames count is not negative
+ if (frameCount < 0) {
+ log.complain("Negative value of frames count in reply packet: "
+ + frameCount);
+ success = false;
+ }
+
+ // check that thread has an expected state
+ if (frameCount != FRAMES_COUNT) {
+ log.complain("Unexpected number of frames count returned: "
+ + frameCount + " (expected: " + FRAMES_COUNT + ")");
+ success = false;
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/FrameCount/framecnt001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ThreadReference/FrameCount/framecnt001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ThreadReference
+ * command: FrameCount
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * returned number of thread frames is the same as expected.
+ * Test consists of two compoments:
+ * debugger: framecnt001
+ * debuggee: framecnt001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains from debuggee classID for tested thread class
+ * and threadID as the value of a class static field. Also debugger
+ * suspends the thread before sending the tested command.
+ * Then, debugger creates command packet for ThreadReference.FrameCount
+ * command with the found threadID as an argument, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts number of frames in the thread. Also test checks that
+ * returned frames count is not negative and has the expected value.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ThreadReference.FrameCount.framecnt001
+ * nsk.jdwp.ThreadReference.FrameCount.framecnt001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ThreadReference.FrameCount.framecnt001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/FrameCount/framecnt001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.FrameCount;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class framecnt001a {
+
+ // name for the tested thread
+ public static final String THREAD_NAME = "TestedThreadName";
+ public static final String FIELD_NAME = "thread";
+
+ // frames count for tested thread in recursive method invokation
+ public static final int FRAMES_COUNT = 10;
+
+ // notification object to notify debuggee that thread is ready
+ private static Object threadReady = new Object();
+ // lock object to prevent thread from exit
+ private static Object threadLock = new Object();
+
+ // scaffold objects
+ private static volatile ArgumentHandler argumentHandler = null;
+ private static volatile Log log = null;
+
+ public static void main(String args[]) {
+ framecnt001a _framecnt001a = new framecnt001a();
+ System.exit(framecnt001.JCK_STATUS_BASE + _framecnt001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // lock the object to prevent thread from exit
+ synchronized (threadLock) {
+
+ // load tested class and create tested thread
+ log.display("Creating object of tested class");
+ TestedClass.thread = new TestedClass(THREAD_NAME);
+
+ // start the thread and wait for notification from it
+ synchronized (threadReady) {
+ TestedClass.thread.start();
+ try {
+ threadReady.wait();
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + framecnt001.READY);
+ pipe.println(framecnt001.READY);
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for thread started: " + e);
+ pipe.println(framecnt001.ERROR);
+ }
+ }
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + framecnt001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(framecnt001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + framecnt001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return framecnt001.FAILED;
+ }
+
+ // allow started thread to exit
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return framecnt001.PASSED;
+ }
+
+ // tested thread class
+ public static class TestedClass extends Thread {
+
+ // field with the tested Thread value
+ public static volatile TestedClass thread = null;
+
+ int frames = 0;
+
+ TestedClass(String name) {
+ super(name);
+ }
+
+ // start the thread and recursive invoke makeFrames()
+ public void run() {
+ log.display("Tested thread started");
+
+ // make remaining frames already having one
+ frames = 1;
+ makeFrames(FRAMES_COUNT - frames);
+ }
+
+ // recursive make thread frames and notify debuggee
+ public void makeFrames(int count) {
+ frames++;
+ count--;
+ int local = frames + count;
+ if (count > 0) {
+ makeFrames(count);
+ } else {
+ log.display("Thread frames made: " + frames);
+
+ // notify debuggee that thread ready for testing
+ synchronized (threadReady) {
+ threadReady.notifyAll();
+ }
+
+ // wait for lock object released
+ synchronized (threadLock) {
+ log.display("Tested thread finished");
+ }
+ }
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Frames/frames001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,436 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.Frames;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ThreadReference.Frames.
+ *
+ * See frames001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class frames001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String ERROR = "error";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ThreadReference.Frames";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "frames001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ThreadReference.Frames";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ThreadReference.Frames;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the tested thread and statioc field with thread value
+ static final String TESTED_CLASS_FIELD_NAME = frames001a.FIELD_NAME;
+ static final String TESTED_THREAD_NAME = frames001a.THREAD_NAME;
+
+ // names of the methods with frames
+ static final String TESTED_METHOD_NAME = frames001a.METHOD_NAME;
+ static final String RUN_METHOD_NAME = "run";
+
+ // expected number of frames count
+ static final int START_FRAME_INDEX = 2;
+ static final int FRAMES_COUNT = frames001a.FRAMES_COUNT - START_FRAME_INDEX;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new frames001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ long threadID = 0;
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for methodID of the recursive method
+ log.display("Getting methodID by name: " + TESTED_METHOD_NAME);
+ long methodID = debugee.getMethodID(classID, TESTED_METHOD_NAME, true);
+ log.display(" got methodID: " + methodID);
+
+ // query debuggee for methodID of the run() method
+ log.display("Getting methodID by name: " + RUN_METHOD_NAME);
+ long runMethodID = debugee.getMethodID(classID, RUN_METHOD_NAME, true);
+ log.display(" got methodID: " + runMethodID);
+
+ // query debuggee for threadID value from a static field
+ log.display("Getting threadID value from static field: "
+ + TESTED_CLASS_FIELD_NAME);
+ threadID = queryThreadID(classID, TESTED_CLASS_FIELD_NAME);
+ log.display(" got threadID: " + threadID);
+
+ // suspend tested thread into debyggee
+ log.display("Suspending thread into debuggee for threadID: " + threadID);
+ debugee.suspendThread(threadID);
+ log.display(" thread suspended");
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(threadID, methodID, runMethodID, classID);
+
+ } finally {
+ log.display("\n>>> Finishing test \n");
+
+ // resume suspended thread
+ if (threadID != 0) {
+ log.display("Resuming suspended thread");
+ debugee.resumeThread(threadID);
+ }
+
+ // quit debugee
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ } else if (signal.equals(ERROR)) {
+ throw new TestBug("Debugee was not able to start tested thread"
+ + " (received signal: " + signal + ")");
+ } else if (!signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for threadID value of statuic field of the class.
+ */
+ long queryThreadID(long classID, String fieldName) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != JDWP.Tag.THREAD) {
+ throw new Failure("Not threadID value returned from debuggee: " + value);
+ }
+
+ // extract threadID from the value
+ long threadID = ((Long)value.getValue()).longValue();
+ return threadID;
+ }
+
+ /**
+ * Perform testing JDWP command for specified threadID.
+ */
+ void testCommand(long threadID, long methodID, long runMethodID, long classID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" threadID: " + threadID);
+ command.addObjectID(threadID);
+ log.display(" startFrame: " + START_FRAME_INDEX);
+ command.addInt(START_FRAME_INDEX);
+ log.display(" length: " + FRAMES_COUNT);
+ command.addInt(FRAMES_COUNT);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract number of frames
+ int frames = 0;
+ try {
+ frames = reply.getInt();
+ log.display(" frames: " + frames);
+ } catch (BoundException e) {
+ log.complain("Unable to extract number of frames from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that frames count is not negative
+ if (frames < 0) {
+ log.complain("Negative value of frames count in reply packet: "
+ + frames);
+ success = false;
+ }
+
+ // check that thread has an expected state
+ if (frames != FRAMES_COUNT) {
+ log.complain("Unexpected number of frames returned: "
+ + frames + " (expected: " + FRAMES_COUNT + ")");
+ success = false;
+ }
+
+ // use methodID of the recursive method to check all frames except the last one
+ long checkedMethodID = methodID;
+
+ // extarct frame IDs and locations
+ for (int i = 0; i < frames; i++) {
+
+ log.display(" frame #" + i + ":");
+
+ // extract frame ID
+ long frameID = 0;
+ try {
+ frameID = reply.getFrameID();
+ log.display(" frameID: " + frameID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract " + i + " frameID from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // extract frame location
+ JDWP.Location location = null;
+ try {
+ location = reply.getLocation();
+ log.display(" location: " + location);
+ } catch (BoundException e) {
+ e.printStackTrace(log.getOutStream());
+ log.complain("Unable to extract " + i + " frame location from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that frameID is not negative integer
+ if (frameID < 0) {
+ log.complain("Negative value of " + i + " frameID: "
+ + frameID);
+ success = false;
+ }
+
+ // check that type tag of location is CLASS tag
+ if (location.getTag() != JDWP.TypeTag.CLASS) {
+ log.complain("Unexpected type tag of " + i + " frame location: "
+ + location.getTag() + "(expected: " + JDWP.TypeTag.CLASS + ")");
+ success = false;
+ }
+
+ // check that classID of location is equal to original classID
+ if (location.getClassID() != classID) {
+ log.complain("Unexpected classID of " + i + " frame location: "
+ + location.getClassID() + "(expected: " + classID + ")");
+ success = false;
+ }
+
+ // use methodID of run() method for checking last frame
+ if (i == frames - 1) {
+ checkedMethodID = runMethodID;
+ }
+
+ // check that methodID of location is equal to one of original methodIDs
+ if (location.getMethodID() != checkedMethodID) {
+ log.complain("Unexpected methodID of " + i + " frame location: "
+ + location.getMethodID() + "(expected: " + checkedMethodID + ")");
+ success = false;
+ }
+
+ // check that code index of location is not negative integer
+ if (location.getIndex() < 0) {
+ log.complain("Negative value of index of " + i + " frame location: "
+ + location.getIndex());
+ success = false;
+ }
+
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Frames/frames001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ThreadReference/Frames/frames001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ThreadReference
+ * command: Frames
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Also test checks the following assertions:
+ * 1. Number of returned frames is the same as requested
+ * 2. Location of each frame belongs to the tested class
+ * 3. Location of the last frame belongs to the method run()
+ * 4. Locations of all other frames belogs to the method makeFrames()
+ * 5. Each frameID is a not negative integer value.
+ * Test consists of two compoments:
+ * debugger: frames001
+ * debuggee: frames001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains from debuggee classID for tested thread class
+ * and threadID as the value of a class static field. Also debugger
+ * suspends the thread before sending the tested command.
+ * Then, debugger creates command packet for ThreadReference.Frames
+ * command with the found threadID as an argument, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts number of frames in the thread. Also test checks above
+ * mentioned assertions.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ThreadReference.Frames.frames001
+ * nsk.jdwp.ThreadReference.Frames.frames001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ThreadReference.Frames.frames001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Frames/frames001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.Frames;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class frames001a {
+
+ // name for the tested thread
+ public static final String THREAD_NAME = "TestedThreadName";
+ public static final String FIELD_NAME = "thread";
+ public static final String METHOD_NAME = "makeFrames";
+
+ // frames count for tested thread in recursive method invokation
+ public static final int FRAMES_COUNT = 10;
+
+ // notification object to notify debuggee that thread is ready
+ private static Object threadReady = new Object();
+ // lock object to prevent thread from exit
+ private static Object threadLock = new Object();
+
+ // scaffold objects
+ private static volatile ArgumentHandler argumentHandler = null;
+ private static volatile Log log = null;
+
+ public static void main(String args[]) {
+ frames001a _frames001a = new frames001a();
+ System.exit(frames001.JCK_STATUS_BASE + _frames001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // lock the object to prevent thread from exit
+ synchronized (threadLock) {
+
+ // load tested class and create tested thread
+ log.display("Creating object of tested class");
+ TestedClass.thread = new TestedClass(THREAD_NAME);
+
+ // start the thread and wait for notification from it
+ synchronized (threadReady) {
+ TestedClass.thread.start();
+ try {
+ threadReady.wait();
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + frames001.READY);
+ pipe.println(frames001.READY);
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for thread started: " + e);
+ pipe.println(frames001.ERROR);
+ }
+ }
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + frames001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(frames001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + frames001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return frames001.FAILED;
+ }
+
+ // allow started thread to exit
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return frames001.PASSED;
+ }
+
+ // tested thread class
+ public static class TestedClass extends Thread {
+
+ // field with the tested Thread value
+ public static volatile TestedClass thread = null;
+
+ int frames = 0;
+
+ TestedClass(String name) {
+ super(name);
+ }
+
+ // start the thread and recursive invoke makeFrames()
+ public void run() {
+ log.display("Tested thread started");
+
+ // make remaining frames already having one
+ frames = 1;
+ makeFrames(FRAMES_COUNT - frames);
+
+ }
+
+ // recursive make thread frames and notify debuggee
+ public void makeFrames(int count) {
+ frames++;
+ count--;
+ int local = frames + count;
+ if (count > 0) {
+ makeFrames(count);
+ } else {
+ log.display("Thread frames made: " + frames);
+
+ // notify debuggee that thread ready for testing
+ synchronized (threadReady) {
+ threadReady.notifyAll();
+ }
+
+ // wait for lock object released
+ synchronized (threadLock) {
+ log.display("Tested thread finished");
+ }
+
+ }
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Interrupt/interrupt001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.Interrupt;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ThreadReference.Interrupt.
+ *
+ * See interrupt001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class interrupt001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String ERROR = "error";
+ static final String RUN = "run";
+ static final String INTERRUPTED_TRUE = "interrupted/true";
+ static final String INTERRUPTED_FALSE = "interrupted/false";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ThreadReference.Interrupt";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "interrupt001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ThreadReference.Interrupt";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ThreadReference.Interrupt;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the tested thread and statioc field with thread value
+ static final String TESTED_CLASS_FIELD_NAME = interrupt001a.FIELD_NAME;
+ static final String TESTED_THREAD_NAME = interrupt001a.THREAD_NAME;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new interrupt001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ long threadID = 0;
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for threadID value from a static field
+ log.display("Getting threadID value from static field: "
+ + TESTED_CLASS_FIELD_NAME);
+ threadID = queryThreadID(classID, TESTED_CLASS_FIELD_NAME);
+ log.display(" got threadID: " + threadID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(threadID);
+
+ log.display("\n>>> Checking that tested thread was really interrupted \n");
+
+ // check if the thread was really interrupted
+ confirmThreadInterrupted();
+
+ } finally {
+ log.display("\n>>> Finishing test \n");
+
+ // quit debugee
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ } else if (signal.equals(ERROR)) {
+ throw new TestBug("Debugee was not able to start tested thread"
+ + " (received signal: " + signal + ")");
+ } else if (!signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for threadID value of statuic field of the class.
+ */
+ long queryThreadID(long classID, String fieldName) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != JDWP.Tag.THREAD) {
+ throw new Failure("Not threadID value returned from debuggee: " + value);
+ }
+
+ // extract threadID from the value
+ long threadID = ((Long)value.getValue()).longValue();
+ return threadID;
+ }
+
+ /**
+ * Perform testing JDWP command for specified threadID.
+ */
+ void testCommand(long threadID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" threadID: " + threadID);
+ command.addObjectID(threadID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // there are no data to extract
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ }
+
+ /**
+ * Wait for signal from debugee that thread was really interrupted
+ */
+ void confirmThreadInterrupted() {
+
+ // send debugee signal to run
+ log.display("Sending signal to debugee: " + RUN);
+ pipe.println(RUN);
+
+ // wait for signal DONE from debuggee
+ log.display("Waiting for signal from debugee: " + INTERRUPTED_TRUE);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+
+ // check received signal
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + INTERRUPTED_TRUE + ")");
+ } else if (signal.equals(INTERRUPTED_TRUE)) {
+ log.display("Tested thread was interrupted into debuggee");
+ } else if (signal.equals(INTERRUPTED_FALSE)) {
+ log.complain("Tested thread was NOT interrupted into debuggee");
+ success = false;
+ } else {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + INTERRUPTED_TRUE + ")");
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Interrupt/interrupt001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ThreadReference/Interrupt/interrupt001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ThreadReference
+ * command: Interrupt
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Also test checks following assertions:
+ * 1. Tested thread is really interrupted into debuggee VM.
+ * 2. Thread.isInterrupted() for the thread returns true.
+ * Test consists of two compoments:
+ * debugger: interrupt001
+ * debuggee: interrupt001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains from debuggee classID for tested thread class
+ * and threadID as the value of a class static field. The tested thread
+ * into debuggee is in a waiting state in this time and is ready for
+ * interruption.
+ * Then, debugger creates command packet for ThreadReference.Interrupt
+ * command with the found threadID as an argument, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and ensures the packet does not has any data. Then debugger requests
+ * from debuggee confirmation about thread interruption and checkes
+ * above mentioned assertions.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ * COMMENTS
+ * Modified due to fix of:
+ * 4759463 TEST_BUG: tests against ThreadReference.interrupt() should be corrected
+ * Test fixed due to test bug:
+ * 4960198 TEST_BUG: race in nsk/jdwp/ThreadReference/Interrupt/interrupt001
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ThreadReference.Interrupt.interrupt001
+ * nsk.jdwp.ThreadReference.Interrupt.interrupt001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ThreadReference.Interrupt.interrupt001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Interrupt/interrupt001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.Interrupt;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class interrupt001a {
+
+ // name for the tested thread
+ public static final String THREAD_NAME = "TestedThreadName";
+ public static final String FIELD_NAME = "thread";
+
+ public static volatile boolean interrupted = false;
+
+ // notification object to notify debuggee that thread is started
+ private static Object threadStarting = new Object();
+ // object which thread will wait for before being interruted
+ private static Object threadWaiting = new Object();
+
+ // scaffold objects
+ private static volatile ArgumentHandler argumentHandler = null;
+ private static volatile Log log = null;
+
+ public static void main(String args[]) {
+ interrupt001a _interrupt001a = new interrupt001a();
+ System.exit(interrupt001.JCK_STATUS_BASE + _interrupt001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+ long timeout = argumentHandler.getWaitTime() * 60 * 1000; // milliseconds
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // load tested class and create tested thread
+ log.display("Creating object of tested class");
+ TestedClass.thread = new TestedClass(THREAD_NAME);
+
+ // start the thread and wait for notification from it
+ synchronized (threadStarting) {
+ TestedClass.thread.start();
+ try {
+ threadStarting.wait();
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for thread started:\n\t" + e);
+ pipe.println(interrupt001.ERROR);
+ log.display("Debugee FAILED");
+ return interrupt001.FAILED;
+ }
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + interrupt001.READY);
+ pipe.println(interrupt001.READY);
+ }
+
+ // wait for signal RUN from debugeer
+ log.display("Waiting for signal from debugger: " + interrupt001.RUN);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(interrupt001.RUN)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + interrupt001.RUN + ")");
+ log.display("Debugee FAILED");
+ return interrupt001.FAILED;
+ }
+
+ // wait for thread finished in a waittime interval
+ if (TestedClass.thread.isAlive()) {
+ log.display("Waiting for tested thread finished for timeout: " + timeout);
+ try {
+ TestedClass.thread.join(timeout);
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for tested thread finished:\n\t" + e);
+ pipe.println(interrupt001.ERROR);
+ log.display("Debugee FAILED");
+ return interrupt001.FAILED;
+ }
+ }
+
+ // test if thread was interrupted by debugger
+ if (interrupt001a.interrupted) {
+ log.display("Sending signal to debugger: " + interrupt001.INTERRUPTED_TRUE);
+ pipe.println(interrupt001.INTERRUPTED_TRUE);
+ } else {
+ log.display("Sending signal to debugger: " + interrupt001.INTERRUPTED_FALSE);
+ pipe.println(interrupt001.INTERRUPTED_FALSE);
+ }
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + interrupt001.QUIT);
+ signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(interrupt001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + interrupt001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return interrupt001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return interrupt001.PASSED;
+ }
+
+ // tested thread class
+ public static class TestedClass extends Thread {
+
+ // field with the tested Thread value
+ public static volatile TestedClass thread = null;
+
+ TestedClass(String name) {
+ super(name);
+ }
+
+ // start the thread and recursive invoke makeFrames()
+ public void run() {
+ log.display("Tested thread started");
+
+ synchronized (threadWaiting) {
+
+ // notify debuggee that thread started
+ synchronized (threadStarting) {
+ threadStarting.notifyAll();
+ }
+
+ // wait infinitely for notification object
+ try {
+ threadWaiting.wait();
+ log.complain("Tested thread NOT interrupted");
+ } catch (InterruptedException e) {
+ log.display("Tested thread interrupted");
+ interrupt001a.interrupted = true;
+ }
+ }
+
+ log.display("Tested thread finished");
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Name/name001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.Name;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ThreadReference.Name.
+ *
+ * See name001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class name001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String ERROR = "error";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ThreadReference.Name";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "name001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ThreadReference.Name";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ThreadReference.Name;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the tested thread and statioc field with thread value
+ static final String TESTED_CLASS_FIELD_NAME = name001a.FIELD_NAME;
+ static final String TESTED_THREAD_NAME = name001a.THREAD_NAME;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new name001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for threadID value from a static field
+ log.display("Getting threadID value from static field: "
+ + TESTED_CLASS_FIELD_NAME);
+ long threadID = queryThreadID(classID, TESTED_CLASS_FIELD_NAME);
+ log.display(" got threadID: " + threadID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(threadID);
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ } else if (signal.equals(ERROR)) {
+ throw new TestBug("Debugee was not able to start tested thread"
+ + " (received signal: " + signal + ")");
+ } else if (!signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for threadID value of statuic field of the class.
+ */
+ long queryThreadID(long classID, String fieldName) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != JDWP.Tag.THREAD) {
+ throw new Failure("Not threadID value returned from debuggee: " + value);
+ }
+
+ // extract threadID from the value
+ long threadID = ((Long)value.getValue()).longValue();
+ return threadID;
+ }
+
+ /**
+ * Perform testing JDWP command for specified threadID.
+ */
+ void testCommand(long threadID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" threadID: " + threadID);
+ command.addObjectID(threadID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract thread name
+ String threadName = null;
+ try {
+ threadName = reply.getString();
+ log.display(" threadName: " + threadName);
+ } catch (BoundException e) {
+ log.complain("Unable to extract thread name from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that thread name is equal to the expected one
+ if (!threadName.equals(TESTED_THREAD_NAME)) {
+ log.complain("Unexpected thread name returned in the reply packet: "
+ + threadName + " (expected: " + TESTED_THREAD_NAME + ")");
+ success = false;
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Name/name001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ThreadReference/Name/name001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ThreadReference
+ * command: Name
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * returned name of the tested thread is equal to the expected one.
+ * Test consists of two compoments:
+ * debugger: name001
+ * debuggee: name001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains from debuggee classID for tested thread class
+ * and threadID as the value of a class static field.
+ * Then, debugger creates command packet for ThreadReference.Name
+ * command with the found threadID as arguments, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts thread name. Also test checks that the name is equal
+ * to the expected one.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ThreadReference.Name.name001
+ * nsk.jdwp.ThreadReference.Name.name001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ThreadReference.Name.name001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Name/name001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.Name;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class name001a {
+
+ // name for the tested thread
+ public static final String THREAD_NAME = "TestedThreadName";
+ public static final String FIELD_NAME = "thread";
+
+ // notification object to notify debuggee that thread started
+ private static Object threadStarted = new Object();
+ // lock object to prevent thread from exit
+ private static Object threadLock = new Object();
+
+ // scaffold objects
+ private static volatile ArgumentHandler argumentHandler = null;
+ private static volatile Log log = null;
+
+ public static void main(String args[]) {
+ name001a _name001a = new name001a();
+ System.exit(name001.JCK_STATUS_BASE + _name001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // lock the object to prevent thread from exit
+ synchronized (threadLock) {
+
+ // load tested class and create tested thread
+ log.display("Creating object of tested class");
+ TestedClass.thread = new TestedClass(THREAD_NAME);
+
+ // start the thread and wait for notification from it
+ synchronized (threadStarted) {
+ TestedClass.thread.start();
+ try {
+ threadStarted.wait();
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + name001.READY);
+ pipe.println(name001.READY);
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for thread started: " + e);
+ pipe.println(name001.ERROR);
+ }
+ }
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + name001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(name001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + name001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return name001.FAILED;
+ }
+
+ // allow started thread to exit
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return name001.PASSED;
+ }
+
+ // tested thread class
+ public static class TestedClass extends Thread {
+
+ // field with the tested Thread value
+ public static volatile TestedClass thread = null;
+
+ TestedClass(String name) {
+ super(name);
+ }
+
+ public void run() {
+ log.display("Tested thread started");
+
+ // notify debuggee that thread really started
+ synchronized (threadStarted) {
+ threadStarted.notifyAll();
+ }
+
+ // wait for lock object released
+ synchronized (threadLock) {
+ log.display("Tested thread finished");
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitors/ownmonitors001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,442 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.OwnedMonitors;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ThreadReference.OwnedMonitors.
+ *
+ * See ownmonitors001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class ownmonitors001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String ERROR = "error";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ThreadReference.OwnedMonitors";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "ownmonitors001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // VM capability constatnts
+ static final int VM_CAPABILITY_NUMBER = JDWP.Capability.CAN_GET_OWNED_MONITOR_INFO;
+ static final String VM_CAPABILITY_NAME = "canGetOwnedMonitorInfo";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ThreadReference.OwnedMonitors";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ThreadReference.OwnedMonitors;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the tested thread and statioc field with thread value
+ static final String TESTED_THREAD_NAME = ownmonitors001a.THREAD_NAME;
+ static final String THREAD_FIELD_NAME = ownmonitors001a.THREAD_FIELD_NAME;
+ static final String OWNED_MONITOR_FIELD_NAME =
+ ownmonitors001a.OWNED_MONITOR_FIELD_NAME;
+ static final String NOT_OWNED_MONITOR_FIELD_NAME =
+ ownmonitors001a.NOT_OWNED_MONITOR_FIELD_NAME;
+
+ // expected number of owned monitors
+ static final int OWNED_MONITORS = 1;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new ownmonitors001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ long threadID = 0;
+ try {
+ log.display("\n>>> Checking VM capability \n");
+
+ // check for VM capability
+ log.display("Checking VM capability: " + VM_CAPABILITY_NAME);
+ if (!debugee.getCapability(VM_CAPABILITY_NUMBER, VM_CAPABILITY_NAME)) {
+ out.println("TEST PASSED: unsupported VM capability: "
+ + VM_CAPABILITY_NAME);
+ return PASSED;
+ }
+
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for threadID value from a static field
+ log.display("Getting threadID value from static field: "
+ + THREAD_FIELD_NAME);
+ threadID = queryObjectID(classID, THREAD_FIELD_NAME, JDWP.Tag.THREAD);
+ log.display(" got threadID: " + threadID);
+
+ // query debuggee for objectID value for owned monitor from a static field
+ log.display("Getting objectID value for owned monitor from static field: "
+ + OWNED_MONITOR_FIELD_NAME);
+ long ownedMonitorID = queryObjectID(classID,
+ OWNED_MONITOR_FIELD_NAME, JDWP.Tag.OBJECT);
+ log.display(" got objectID: " + ownedMonitorID);
+
+ // query debuggee for objectID value for not owned monitor from a static field
+ log.display("Getting objectID value for not owned monitor from static field: "
+ + NOT_OWNED_MONITOR_FIELD_NAME);
+ long notOwnedMonitorID = queryObjectID(classID,
+ NOT_OWNED_MONITOR_FIELD_NAME, JDWP.Tag.OBJECT);
+ log.display(" got objectID: " + notOwnedMonitorID);
+
+ // suspend tested thread into debyggee
+ log.display("Suspending thread into debuggee for threadID: " + threadID);
+ debugee.suspendThread(threadID);
+ log.display(" thread suspended");
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(threadID, ownedMonitorID, notOwnedMonitorID);
+
+ } finally {
+ log.display("\n>>> Finishing test \n");
+
+ // resume suspended thread
+ if (threadID != 0) {
+ log.display("Resuming suspended thread");
+ debugee.resumeThread(threadID);
+ }
+
+ // quit debugee
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ } else if (signal.equals(ERROR)) {
+ throw new TestBug("Debugee was not able to start tested thread"
+ + " (received signal: " + signal + ")");
+ } else if (!signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for objectID value of static class field.
+ */
+ long queryObjectID(long classID, String fieldName, byte tag) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != tag) {
+ throw new Failure("Wrong objectID tag received from field \"" + fieldName
+ + "\": " + value.getTag() + " (expected: " + tag + ")");
+ }
+
+ // extract threadID from the value
+ long objectID = ((Long)value.getValue()).longValue();
+ return objectID;
+ }
+
+ /**
+ * Perform testing JDWP command for specified threadID.
+ */
+ void testCommand(long threadID, long expectedObjectID, long unexpectedObjectID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" threadID: " + threadID);
+ command.addObjectID(threadID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract number of frames
+ int owned = 0;
+ try {
+ owned = reply.getInt();
+ log.display(" owned: " + owned);
+ } catch (BoundException e) {
+ log.complain("Unable to extract number of owned minitors from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that frames count is not negative
+ if (owned < 0) {
+ log.complain("Negative number of owned monitors in reply packet: "
+ + owned);
+ success = false;
+ }
+
+ // check that thread has an expected state
+ if (owned != OWNED_MONITORS) {
+ log.complain("Unexpected number of owned monitors returned: "
+ + owned + " (expected: " + OWNED_MONITORS + ")");
+ success = false;
+ }
+
+ boolean foundExpected = false;
+
+ // extract objectID's for owned monitors
+ for (int i = 0; i < owned; i++) {
+
+ log.display(" monitor #" + i + ":");
+
+ // extract object tag
+ byte tag = (byte)0;
+ try {
+ tag = reply.getByte();
+ log.display(" tag: " + tag);
+ } catch (BoundException e) {
+ log.complain("Unable to extract tag for monitor object from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // extract objectID
+ long objectID = 0;
+ try {
+ objectID = reply.getObjectID();
+ log.display(" objectID: " + objectID);
+ } catch (BoundException e) {
+ log.complain("Unable to extract " + i + " monitor objectID from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that tag is an OBJECT tag
+ if (tag != JDWP.Tag.OBJECT) {
+ log.complain("Unexpected tag for monitor object received:" + tag
+ + " (expected" + JDWP.Tag.OBJECT);
+ success = false;
+ }
+
+ // check that objectID is not negative integer
+ if (objectID < 0) {
+ log.complain("Negative value of " + i + " objectID received: "
+ + objectID);
+ success = false;
+ }
+
+ // check that expected objectID is in the list
+ if (objectID == expectedObjectID) {
+ log.display("Found expected monitor objectID: " + expectedObjectID);
+ foundExpected = true;
+ }
+
+ // check that not expected objectID is in the list
+ if (objectID == unexpectedObjectID) {
+ log.complain("Unexpected objectID found in the list of owned monitors: "
+ + unexpectedObjectID);
+ success = false;
+ }
+
+ }
+
+ // check if expected owned monitor objectID not found
+ if (!foundExpected) {
+ log.complain("Expected objectID not found in the list of owned monitors: "
+ + expectedObjectID);
+ success = false;
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitors/ownmonitors001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ThreadReference/OwnedMonitors/ownmonitors001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ThreadReference
+ * command: OwnedMonitors
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Also test checks that only one owned monitor returned
+ * for the tested thread.
+ * Test consists of two compoments:
+ * debugger: ownmonitors001
+ * debuggee: ownmonitors001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains from debuggee classID for tested thread class
+ * and threadID as the value of a class static field. Also debugger
+ * suspends the thread before sending the tested command. The tested
+ * thread is owning only one object monitor at this moment.
+ * Then, debugger creates command packet for ThreadReference.OwnedMonitors
+ * command with the found threadID as an argument, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts list ob objectIDs for thread owned monitors. Also test
+ * checks above mentioned assertions.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ * COMMENTS
+ * For JDK 1.4.0-beta3 (build 1.4.0-beta3-b84) and earlier this test passed
+ * because target VM does not support VM capability: canGetOwnedMonitorInfo
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ThreadReference.OwnedMonitors.ownmonitors001
+ * nsk.jdwp.ThreadReference.OwnedMonitors.ownmonitors001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ThreadReference.OwnedMonitors.ownmonitors001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitors/ownmonitors001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.OwnedMonitors;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class ownmonitors001a {
+
+ // name for the tested thread
+ public static final String THREAD_NAME = "TestedThreadName";
+ public static final String THREAD_FIELD_NAME = "thread";
+ public static final String OWNED_MONITOR_FIELD_NAME = "ownedMonitor";
+ public static final String NOT_OWNED_MONITOR_FIELD_NAME = "notOwnedMonitor";
+
+ // notification object to notify debuggee that thread is ready
+ private static Object threadReady = new Object();
+ // lock object to prevent thread from exit
+ private static Object threadLock = new Object();
+
+ // scaffold objects
+ private static volatile ArgumentHandler argumentHandler = null;
+ private static volatile Log log = null;
+
+ public static void main(String args[]) {
+ ownmonitors001a _ownmonitors001a = new ownmonitors001a();
+ System.exit(ownmonitors001.JCK_STATUS_BASE + _ownmonitors001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // lock the object to prevent thread from exit
+ synchronized (threadLock) {
+
+ // load tested class and create tested thread
+ log.display("Creating object of tested class");
+ TestedClass.thread = new TestedClass(THREAD_NAME);
+
+ // start the thread and wait for notification from it
+ synchronized (threadReady) {
+ TestedClass.thread.start();
+ try {
+ threadReady.wait();
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + ownmonitors001.READY);
+ pipe.println(ownmonitors001.READY);
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for thread started: " + e);
+ pipe.println(ownmonitors001.ERROR);
+ }
+ }
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + ownmonitors001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(ownmonitors001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + ownmonitors001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return ownmonitors001.FAILED;
+ }
+
+ // allow started thread to exit
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return ownmonitors001.PASSED;
+ }
+
+ // tested thread class
+ public static class TestedClass extends Thread {
+
+ // field with the tested Thread value
+ public static volatile TestedClass thread = null;
+
+ // field with object whose monitor the tested thread owns
+ public static Object ownedMonitor = new Object();
+
+ // field with object whose monitor the tested thread does not own
+ public static Object notOwnedMonitor = new Object();
+
+ TestedClass(String name) {
+ super(name);
+ }
+
+ // start the thread and recursive invoke makeFrames()
+ public void run() {
+ log.display("Tested thread started");
+
+ // get ownership for the tested monitors
+ synchronized (ownedMonitor) {
+
+ // notify debuggee that thread ready for testing
+ synchronized (threadReady) {
+ threadReady.notifyAll();
+ }
+
+ // wait for lock object released
+ synchronized (threadLock) {
+ log.display("Tested thread finished");
+ }
+
+ }
+
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitorsStackDepthInfo/ownedMonitorsStackDepthInfo001/ownedMonitorsStackDepthInfo001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2007, 2018, 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 converted from VM Testbase nsk/jdwp/ThreadReference/OwnedMonitorsStackDepthInfo/ownedMonitorsStackDepthInfo001.
+ * VM Testbase keywords: [quick, jpda, jdwp, feature_jdk6_jpda, vm6, monitoring]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ThreadReference
+ * command: OwnedMonitorsStackDepthInfo
+ * Test checks that debuggee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: ownedMonitorsStackDepthInfo001
+ * debuggee: ownedMonitorsStackDepthInfo001a
+ * Debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with execution commands.
+ * Debuggee during startup start test thread which acquires 6 different monitors in following ways:
+ * - entering synchronized method
+ * - entering synchronized method for thread object itself
+ * - entering synchronized static method
+ * - entering synchronized method for thread class itself
+ * - entering synchronized block on non-static object
+ * - acquire JNI monitor through JNI MonitorEnter()
+ * Debuggee save information about acquired monitors(monitor instance and stack depth location
+ * where monitor was acquired) in static fields with names monitor1, ..., monitor6 and depth1, ..., depth6 to
+ * simplify access to this information for debugger.
+ * Debugger obtains threadID for test thread.
+ * Debugger creates command packet for OwnedMonitorsStackDepthInfo command with the
+ * found threadID as an argument, writes packet to the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure and extract
+ * monitors ids and stack depth locations.
+ * Debugger obtains information about acquired monitors from debuggee's static fields monitor1, ..., monitor6 and
+ * depth1, ..., depth6 and checks that this data and data received via JDWP command are identical.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ThreadReference.OwnedMonitorsStackDepthInfo.ownedMonitorsStackDepthInfo001.ownedMonitorsStackDepthInfo001
+ * @run main/othervm/native/timeout=420 PropertyResolvingWrapper
+ * nsk.jdwp.ThreadReference.OwnedMonitorsStackDepthInfo.ownedMonitorsStackDepthInfo001.ownedMonitorsStackDepthInfo001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
+package nsk.jdwp.ThreadReference.OwnedMonitorsStackDepthInfo.ownedMonitorsStackDepthInfo001;
+
+import java.io.*;
+import nsk.share.Consts;
+import nsk.share.jdwp.*;
+
+public class ownedMonitorsStackDepthInfo001 extends TestDebuggerType1 {
+ protected String getDebugeeClassName() {
+ return nsk.jdwp.ThreadReference.OwnedMonitorsStackDepthInfo.ownedMonitorsStackDepthInfo001.ownedMonitorsStackDepthInfo001a.class.getName();
+ }
+
+ public static void main(String argv[]) {
+ System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new ownedMonitorsStackDepthInfo001().runIt(argv, out);
+ }
+
+ // information for acquired monitor
+ static class MonitorInfo {
+ long monitorObjectID;
+
+ int depth;
+
+ public MonitorInfo(long monitorObjectID, int depth) {
+ this.monitorObjectID = monitorObjectID;
+ this.depth = depth;
+ }
+ }
+
+ private void testCommand() {
+ try {
+ int JDWP_COMMAND_ID = JDWP.Command.ThreadReference.OwnedMonitorsStackDepthInfo;
+
+ log.display("Create command: " + JDWP.commandNames.get(JDWP_COMMAND_ID));
+
+ long threadID = debuggee.getThreadID(ownedMonitorsStackDepthInfo001a.lockingThreadName);
+ log.display("threadID = " + threadID);
+
+ debuggee.suspendThread(threadID);
+
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addObjectID(threadID);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ ReplyPacket reply;
+
+ reply = getReply(command);
+
+ MonitorInfo expectedMonitors[] = new MonitorInfo[ownedMonitorsStackDepthInfo001a.expectedMonitorCounts];
+
+ long classID = debuggee.getReferenceTypeID(createTypeSignature(getDebugeeClassName()));
+
+ // obtain information about aquired monitors
+ for (int i = 0; i < ownedMonitorsStackDepthInfo001a.expectedMonitorCounts; i++) {
+ long monitorID = queryObjectID(classID, "monitor" + (i + 1));
+ int depth = ((Integer) debuggee.getStaticFieldValue(classID, "depth" + (i + 1), JDWP.Tag.INT).getValue()).intValue();
+
+ expectedMonitors[i] = new MonitorInfo(monitorID, depth);
+ }
+
+ int owned = reply.getInt();
+
+ log.display("owned = " + owned);
+
+ // check that correct value of 'owned' was received
+ if (owned != expectedMonitors.length) {
+ setSuccess(false);
+ log.complain("Unexpected value of 'owned': " + owned + ", expected value is " + expectedMonitors.length);
+ }
+
+ MonitorInfo receivedMonitors[] = new MonitorInfo[owned];
+
+ for (int i = 0; i < owned; i++) {
+ JDWP.Value value = reply.getValue();
+ log.display("tagged-ObjectID = " + value);
+
+ int stack_depth = reply.getInt();
+ log.display("stack_depth = " + stack_depth);
+
+ receivedMonitors[i] = new MonitorInfo(((Long) value.getValue()).longValue(), stack_depth);
+ }
+
+ // check that correct information about acquired monitors was received
+ for (int i = 0; i < owned; i++) {
+ boolean monitorFound = false;
+
+ for (int j = 0; j < expectedMonitors.length; j++) {
+ if (receivedMonitors[i].monitorObjectID == expectedMonitors[j].monitorObjectID) {
+ monitorFound = true;
+
+ if (receivedMonitors[i].depth != expectedMonitors[j].depth) {
+ setSuccess(false);
+ log.complain("Unexpected monitor depth for monitor " + receivedMonitors[i].monitorObjectID + ": "
+ + receivedMonitors[i].depth + ", expected value is " + expectedMonitors[j].depth);
+ }
+
+ break;
+ }
+ }
+
+ if (!monitorFound) {
+ setSuccess(false);
+ log.complain("Unexpected monitor: monitor" + receivedMonitors[i].monitorObjectID + " stack_depth" + receivedMonitors[i].depth);
+ }
+ }
+
+ if (!getSuccess()) {
+ log.complain("Expected monitors: ");
+ for (int i = 0; i < expectedMonitors.length; i++) {
+ log.complain("monitor: " + expectedMonitors[i].monitorObjectID + " " + expectedMonitors[i].depth);
+ }
+ }
+
+ if (!reply.isParsed()) {
+ setSuccess(false);
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ }
+ } catch (Exception e) {
+ setSuccess(false);
+ log.complain("Caught exception while testing JDWP command: " + e);
+ e.printStackTrace(log.getOutStream());
+ }
+ }
+
+ public void doTest() {
+ testCommand();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitorsStackDepthInfo/ownedMonitorsStackDepthInfo001/ownedMonitorsStackDepthInfo001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2007, 2018, 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.
+ */
+package nsk.jdwp.ThreadReference.OwnedMonitorsStackDepthInfo.ownedMonitorsStackDepthInfo001;
+
+import java.util.*;
+import nsk.share.TestBug;
+import nsk.share.jdwp.*;
+import nsk.share.locks.LockingThread;
+
+public class ownedMonitorsStackDepthInfo001a extends AbstractJDWPDebuggee {
+ public static Object monitor1;
+
+ public static int depth1;
+
+ public static Object monitor2;
+
+ public static int depth2;
+
+ public static Object monitor3;
+
+ public static int depth3;
+
+ public static Object monitor4;
+
+ public static int depth4;
+
+ public static Object monitor5;
+
+ public static int depth5;
+
+ public static Object monitor6;
+
+ public static int depth6;
+
+ public static int expectedMonitorCounts = 6;
+
+ public static String lockingThreadName = "LockingThread";
+
+ public static LockingThread lockingThread;
+
+ protected void init(String args[]) {
+ super.init(args);
+
+ List<String> locksTypes = new ArrayList<String>();
+
+ // LockingThread acquire 6 different monitors
+ locksTypes.add(LockingThread.SYNCHRONIZED_METHOD);
+ locksTypes.add(LockingThread.JNI_MONITOR_ENTER);
+ locksTypes.add(LockingThread.SYNCHRONIZED_THREAD_METHOD);
+ locksTypes.add(LockingThread.SYNCHRONIZED_STATIC_THREAD_METHOD);
+ locksTypes.add(LockingThread.SYNCHRONIZED_OBJECT_BLOCK);
+ locksTypes.add(LockingThread.SYNCHRONIZED_STATIC_METHOD);
+
+ lockingThread = new LockingThread(log, locksTypes);
+ lockingThread.setName(lockingThreadName);
+ lockingThread.start();
+ lockingThread.waitState();
+
+ // get information about acquired monitors and save it in static fields to simplify
+ // access to this information for debugger
+ LockingThread.DebugMonitorInfo monitorsInfo[] = lockingThread.getMonitorsInfo(true);
+
+ if (monitorsInfo.length != 6) {
+ throw new TestBug("Locking thread return invalid monitors count: " + monitorsInfo.length + ", expected value is " + 6);
+ }
+
+ monitor1 = monitorsInfo[0].monitor;
+ depth1 = monitorsInfo[0].stackDepth;
+
+ monitor2 = monitorsInfo[1].monitor;
+ depth2 = monitorsInfo[1].stackDepth;
+
+ monitor3 = monitorsInfo[2].monitor;
+ depth3 = monitorsInfo[2].stackDepth;
+
+ monitor4 = monitorsInfo[3].monitor;
+ depth4 = monitorsInfo[3].stackDepth;
+
+ monitor5 = monitorsInfo[4].monitor;
+ depth5 = monitorsInfo[4].stackDepth;
+
+ monitor6 = monitorsInfo[5].monitor;
+ depth6 = monitorsInfo[5].stackDepth;
+ }
+
+ public static void main(String args[]) {
+ new ownedMonitorsStackDepthInfo001a().doTest(args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/OwnedMonitorsStackDepthInfo/ownedMonitorsStackDepthInfo002/ownedMonitorsStackDepthInfo002.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2007, 2018, 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 converted from VM Testbase nsk/jdwp/ThreadReference/OwnedMonitorsStackDepthInfo/ownedMonitorsStackDepthInfo002.
+ * VM Testbase keywords: [quick, jpda, jdwp, feature_jdk6_jpda, vm6, monitoring]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ThreadReference
+ * command: OwnedMonitorsStackDepthInfo
+ * Test checks that debuggee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: ownedMonitorsStackDepthInfo002
+ * debuggee: nsk.share.jdwp.TestDebuggeeType2
+ * Debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with execution commands.
+ * Test performs checks for cases when incorrect data is sent in command.
+ * Following cases are tested:
+ * - create command with -1 as threadID, expect INVALID_OBJECT error
+ * - create command with referenceID instead of threadID, expect INVALID_THREAD error
+ * - try execute command for thread wich has finished execution, expect INVALID_THREAD error
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ThreadReference.OwnedMonitorsStackDepthInfo.ownedMonitorsStackDepthInfo002.ownedMonitorsStackDepthInfo002
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ThreadReference.OwnedMonitorsStackDepthInfo.ownedMonitorsStackDepthInfo002.ownedMonitorsStackDepthInfo002
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
+package nsk.jdwp.ThreadReference.OwnedMonitorsStackDepthInfo.ownedMonitorsStackDepthInfo002;
+
+import java.io.*;
+import nsk.share.Consts;
+import nsk.share.jdwp.*;
+import nsk.share.jpda.AbstractDebuggeeTest;
+import nsk.share.jpda.StateTestThread;
+
+public class ownedMonitorsStackDepthInfo002 extends TestDebuggerType1 {
+ protected String getDebugeeClassName() {
+ return AbstractJDWPDebuggee.class.getName();
+ }
+
+ public static void main(String argv[]) {
+ System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new ownedMonitorsStackDepthInfo002().runIt(argv, out);
+ }
+
+ private void sendCommand(long threadID, boolean trySuspend, int errorCode) {
+ try {
+ int JDWP_COMMAND_ID = JDWP.Command.ThreadReference.OwnedMonitorsStackDepthInfo;
+
+ log.display("Create command: " + JDWP.commandNames.get(JDWP_COMMAND_ID));
+ log.display("threadID = " + threadID);
+
+ // suspend thread or not (can't use suspending when create command with invalid threadID)
+ if (trySuspend)
+ debuggee.suspendThread(threadID);
+
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addObjectID(threadID);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ // in this test always expect reply with error
+ getReply(command, true, errorCode);
+
+ return;
+ } catch (Exception e) {
+ setSuccess(false);
+ log.complain("Caught exception while testing JDWP command: " + e);
+ e.printStackTrace(log.getOutStream());
+ }
+ }
+
+ public void doTest() {
+ // create command with threadID = -1, expect INVALID_OBJECT error
+ sendCommand(-1, false, JDWP.Error.INVALID_OBJECT);
+
+ // create command with referenceTypeID instead of trheadID, expect INVALID_THREAD error
+ sendCommand(debuggee.getReferenceTypeID(createTypeSignature(getDebugeeClassName())), false, JDWP.Error.INVALID_THREAD);
+
+ // create StateTestThread and force this finish execution
+ pipe.println(AbstractDebuggeeTest.COMMAND_CREATE_STATETESTTHREAD);
+
+ if (!isDebuggeeReady())
+ return;
+
+ // skip one state(thread not running), because of can obtain threadID only for running thread
+ pipe.println(AbstractDebuggeeTest.COMMAND_NEXTSTATE_STATETESTTHREAD);
+
+ if (!isDebuggeeReady())
+ return;
+
+ long threadID = debuggee.getThreadID(AbstractDebuggeeTest.stateTestThreadName);
+
+ int state = 2;
+
+ // skip all states
+ while (state++ < StateTestThread.stateTestThreadStates.length) {
+ pipe.println(AbstractDebuggeeTest.COMMAND_NEXTSTATE_STATETESTTHREAD);
+
+ if (!isDebuggeeReady())
+ return;
+ }
+
+ // send command for thread which has exited expect INVALID_THREAD error
+ sendCommand(threadID, true, JDWP.Error.INVALID_THREAD);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Resume/resume001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.Resume;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ThreadReference.Resume.
+ *
+ * See resume001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class resume001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String ERROR = "error";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ThreadReference.Resume";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "resume001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ThreadReference.Resume";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ThreadReference.Resume;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the tested thread and statioc field with thread value
+ static final String TESTED_CLASS_FIELD_NAME = resume001a.FIELD_NAME;
+ static final String TESTED_THREAD_NAME = resume001a.THREAD_NAME;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new resume001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ long threadID = 0;
+
+ // work with prepared debuggee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for threadID value from a static field
+ log.display("Getting threadID value from static field: "
+ + TESTED_CLASS_FIELD_NAME);
+ threadID = queryThreadID(classID, TESTED_CLASS_FIELD_NAME);
+ log.display(" got threadID: " + threadID);
+
+ // request debuggee to suspend tested thread
+ log.display("Suspendig thread into debuggee for threadID: " + threadID);
+ debugee.suspendThread(threadID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(threadID);
+
+ } finally {
+
+ log.display("\n>>> Finishing test \n");
+
+ // resume suspended thread
+ if (threadID != 0) {
+ log.display("Resuming potentially suspended thread");
+ debugee.resumeThread(threadID);
+ }
+
+ // quit debugee
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ } else if (signal.equals(ERROR)) {
+ throw new TestBug("Debugee was not able to start tested thread"
+ + " (received signal: " + signal + ")");
+ } else if (!signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for threadID value of statuic field of the class.
+ */
+ long queryThreadID(long classID, String fieldName) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != JDWP.Tag.THREAD) {
+ throw new Failure("Not threadID value returned from debuggee: " + value);
+ }
+
+ // extract threadID from the value
+ long threadID = ((Long)value.getValue()).longValue();
+ return threadID;
+ }
+
+ /**
+ * Query debuggee for suspend status of the thread.
+ */
+ int querySuspendStatus(long threadID) {
+ log.display("Getting suspend status for threadID: " + threadID);
+ CommandPacket command = new CommandPacket(JDWP.Command.ThreadReference.Status);
+ command.addObjectID(threadID);
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+
+ try {
+ reply.resetPosition();
+
+ int threadStatus = reply.getInt();
+ int suspendStatus = reply.getInt();
+ log.display(" got suspendStatus: " + suspendStatusString(suspendStatus));
+ return suspendStatus;
+ } catch (BoundException e) {
+ throw new Failure("Caught BoundException while parsing reply for ThreadReference.Status:\n\t"
+ + e);
+ }
+ }
+
+ /**
+ * Perform testing JDWP command for specified threadID.
+ */
+ void testCommand(long threadID) {
+ // check that tested thread is not suspended before command sent
+ int suspendStatus = querySuspendStatus(threadID);
+ if (suspendStatus != JDWP.SuspendStatus.SUSPEND_STATUS_SUSPENDED) {
+ throw new Failure("SuspendStatus reports thread is not suspended before sending Resume command: "
+ + suspendStatusString(suspendStatus));
+ } else {
+ log.display("Thread is suspended");
+ }
+
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" threadID: " + threadID);
+ command.addObjectID(threadID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ // check that tested thread is suspended after Resume command sent
+ suspendStatus = querySuspendStatus(threadID);
+ if ((suspendStatus & JDWP.SuspendStatus.SUSPEND_STATUS_SUSPENDED) != 0) {
+ log.complain("SuspendStatus reports thread is suspended after Resume command sent: "
+ + suspendStatusString(suspendStatus));
+ } else {
+ log.display("Thread is not suspended");
+ }
+
+ }
+
+ /**
+ * Return string representation of thread suspend status.
+ */
+ private static String suspendStatusString(int status) {
+ String s = null;
+ if ((status & JDWP.SuspendStatus.SUSPEND_STATUS_SUSPENDED) != 0) {
+ s = "SUSPEND_STATUS_SUSPENDED";
+ } else if (status == 0) {
+ s = "NONE";
+ } else {
+ s = "unknown";
+ }
+ return status + "=" + s;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Resume/resume001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ThreadReference/Resume/resume001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ThreadReference
+ * command: Resume
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * thread becomes "not suspended" status after the command.
+ * Test consists of two compoments:
+ * debugger: resume001
+ * debuggee: resume001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains from debuggee classID for tested thread class
+ * and threadID as the value of a class static field. Debugger suspends
+ * the thread and checks that the thread has "suspended" status before
+ * sending the tested command.
+ * Then, debugger creates command packet for ThreadReference.Resume
+ * command with the found threadID as an argument, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and ensures there is no data into the package. Also debugger queries
+ * debuggee for suspend status of the tested thread and chacks that thread
+ * has status "not suspended".
+ * Finally, debugger resumes suspended thread into debuggee, sends debuggee
+ * signal to quit, waits for it exits and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ThreadReference.Resume.resume001
+ * nsk.jdwp.ThreadReference.Resume.resume001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ThreadReference.Resume.resume001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Resume/resume001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.Resume;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class resume001a {
+
+ // name for the tested thread
+ public static final String THREAD_NAME = "TestedThreadName";
+ public static final String FIELD_NAME = "thread";
+
+ // notification object to notify debuggee that thread started
+ private static Object threadStarted = new Object();
+ // lock object to prevent thread from exit
+ private static Object threadLock = new Object();
+
+ // scaffold objects
+ private static volatile ArgumentHandler argumentHandler = null;
+ private static volatile Log log = null;
+
+ public static void main(String args[]) {
+ resume001a _resume001a = new resume001a();
+ System.exit(resume001.JCK_STATUS_BASE + _resume001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // lock the object to prevent thread from exit
+ synchronized (threadLock) {
+
+ // load tested class and create tested thread
+ log.display("Creating object of tested class");
+ TestedClass.thread = new TestedClass(THREAD_NAME);
+
+ // start the thread and wait for notification from it
+ synchronized (threadStarted) {
+ TestedClass.thread.start();
+ try {
+ threadStarted.wait();
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + resume001.READY);
+ pipe.println(resume001.READY);
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for thread started: " + e);
+ pipe.println(resume001.ERROR);
+ }
+ }
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + resume001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(resume001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + resume001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return resume001.FAILED;
+ }
+
+ // allow started thread to exit
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return resume001.PASSED;
+ }
+
+ // tested thread class
+ public static class TestedClass extends Thread {
+
+ // field with the tested Thread value
+ public static volatile TestedClass thread = null;
+
+ TestedClass(String name) {
+ super(name);
+ }
+
+ public void run() {
+ log.display("Tested thread started");
+
+ // notify debuggee that thread really started
+ synchronized (threadStarted) {
+ threadStarted.notifyAll();
+ }
+
+ // wait for lock object released
+ synchronized (threadLock) {
+ log.display("Tested thread finished");
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Status/status001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.Status;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ThreadReference.Status.
+ *
+ * See status001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class status001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String ERROR = "error";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ThreadReference.Status";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "status001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ThreadReference.Status";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ThreadReference.Status;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the tested thread and statioc field with thread value
+ static final String TESTED_CLASS_FIELD_NAME = status001a.FIELD_NAME;
+ static final String TESTED_THREAD_NAME = status001a.THREAD_NAME;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new status001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for threadID value from a static field
+ log.display("Getting threadID value from static field: "
+ + TESTED_CLASS_FIELD_NAME);
+ long threadID = queryThreadID(classID, TESTED_CLASS_FIELD_NAME);
+ log.display(" got threadID: " + threadID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(threadID);
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ } else if (signal.equals(ERROR)) {
+ throw new TestBug("Debugee was not able to start tested thread"
+ + " (received signal: " + signal + ")");
+ } else if (!signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for threadID value of statuic field of the class.
+ */
+ long queryThreadID(long classID, String fieldName) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != JDWP.Tag.THREAD) {
+ throw new Failure("Not threadID value returned from debuggee: " + value);
+ }
+
+ // extract threadID from the value
+ long threadID = ((Long)value.getValue()).longValue();
+ return threadID;
+ }
+
+ /**
+ * Perform testing JDWP command for specified threadID.
+ */
+ void testCommand(long threadID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" threadID: " + threadID);
+ command.addObjectID(threadID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // extract thread status
+ int threadStatus = 0;
+ try {
+ threadStatus = reply.getInt();
+ log.display(" threadStatus: " + threadStatusString(threadStatus));
+ } catch (BoundException e) {
+ log.complain("Unable to extract thread status from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // extract suspend status
+ int suspendStatus = 0;
+ try {
+ suspendStatus = reply.getInt();
+ log.display(" suspendStatus: " + suspendStatusString(suspendStatus));
+ } catch (BoundException e) {
+ log.complain("Unable to extract thread status from reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check that both status code are not negative values
+ if (threadStatus < 0) {
+ log.complain("Negative value of thread status in reply packet: "
+ + threadStatusString(threadStatus));
+ success = false;
+ }
+ if (suspendStatus < 0) {
+ log.complain("Negative value of suspend status in reply packet: "
+ + suspendStatusString(suspendStatus));
+ success = false;
+ }
+
+ // check that thread has an expected state
+ if (!(threadStatus == JDWP.ThreadStatus.RUNNING
+ || threadStatus == JDWP.ThreadStatus.MONITOR)) {
+ log.complain("Unexpected thread status returned in the reply packet: "
+ + threadStatusString(threadStatus)
+ + " (expected: " + threadStatusString(JDWP.ThreadStatus.RUNNING)
+ + " or " + threadStatusString(JDWP.ThreadStatus.MONITOR) + ")");
+ success = false;
+ }
+
+ // check that thread was not suspended
+ if ((suspendStatus & JDWP.SuspendStatus.SUSPEND_STATUS_SUSPENDED) != 0) {
+ log.complain("Unexpected suspend status returned in the reply packet: "
+ + threadStatusString(threadStatus)
+ + " (expected: " + "not suspended" + ")");
+ success = false;
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+ }
+
+ /**
+ * Return string representation of thread status code.
+ */
+ private static String threadStatusString(int status) {
+ String s = null;
+ switch (status) {
+ case JDWP.ThreadStatus.MONITOR:
+ s = "MONITOR";
+ break;
+ case JDWP.ThreadStatus.RUNNING:
+ s = "RUNNING";
+ break;
+ case JDWP.ThreadStatus.SLEEPING:
+ s = "SLEEPING";
+ break;
+ case JDWP.ThreadStatus.WAIT:
+ s = "WAIT";
+ break;
+ case JDWP.ThreadStatus.ZOMBIE:
+ s = "ZOMBIE";
+ break;
+ default:
+ s = "unknown";
+ break;
+ }
+ return status + "=" + s;
+ }
+
+ /**
+ * Return string representation of thread suspend status.
+ */
+ private static String suspendStatusString(int status) {
+ String s = null;
+ if ((status & JDWP.SuspendStatus.SUSPEND_STATUS_SUSPENDED) != 0) {
+ s = "SUSPEND_STATUS_SUSPENDED";
+ } else if (status == 0) {
+ s = "NONE";
+ } else {
+ s = "unknown";
+ }
+ return status + "=" + s;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Status/status001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ThreadReference/Status/status001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ThreadReference
+ * command: Status
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * returned thread status and suspend status have expected values.
+ * Test consists of two compoments:
+ * debugger: status001
+ * debuggee: status001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains from debuggee classID for tested thread class
+ * and threadID as the value of a class static field.
+ * Then, debugger creates command packet for ThreadReference.Status
+ * command with the found threadID as arguments, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts thread name. Also test checks that thread status and
+ * suspend status have expected values.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ThreadReference.Status.status001
+ * nsk.jdwp.ThreadReference.Status.status001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ThreadReference.Status.status001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Status/status001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.Status;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class status001a {
+
+ // name for the tested thread
+ public static final String THREAD_NAME = "TestedThreadName";
+ public static final String FIELD_NAME = "thread";
+
+ // notification object to notify debuggee that thread started
+ private static Object threadStarted = new Object();
+ // lock object to prevent thread from exit
+ private static Object threadLock = new Object();
+
+ // scaffold objects
+ private static volatile ArgumentHandler argumentHandler = null;
+ private static volatile Log log = null;
+
+ public static void main(String args[]) {
+ status001a _status001a = new status001a();
+ System.exit(status001.JCK_STATUS_BASE + _status001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // lock the object to prevent thread from exit
+ synchronized (threadLock) {
+
+ // load tested class and create tested thread
+ log.display("Creating object of tested class");
+ TestedClass.thread = new TestedClass(THREAD_NAME);
+
+ // start the thread and wait for notification from it
+ synchronized (threadStarted) {
+ TestedClass.thread.start();
+ try {
+ threadStarted.wait();
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + status001.READY);
+ pipe.println(status001.READY);
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for thread started: " + e);
+ pipe.println(status001.ERROR);
+ }
+ }
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + status001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(status001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + status001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return status001.FAILED;
+ }
+
+ // allow started thread to exit
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return status001.PASSED;
+ }
+
+ // tested thread class
+ public static class TestedClass extends Thread {
+
+ // field with the tested Thread value
+ public static volatile TestedClass thread = null;
+
+ TestedClass(String name) {
+ super(name);
+ }
+
+ public void run() {
+ log.display("Tested thread started");
+
+ // notify debuggee that thread really started
+ synchronized (threadStarted) {
+ threadStarted.notifyAll();
+ }
+
+ // wait for lock object released
+ synchronized (threadLock) {
+ log.display("Tested thread finished");
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Stop/stop001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.Stop;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ThreadReference.Stop.
+ *
+ * See stop001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class stop001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String ERROR = "error";
+ static final String RUN = "run";
+ static final String STOPPED = "stopped";
+ static final String NOT_STOPPED = "not_stopped";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ThreadReference.Stop";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "stop001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ThreadReference.Stop";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ThreadReference.Stop;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the tested thread and statioc field with thread value
+ static final String TESTED_THREAD_NAME = stop001a.THREAD_NAME;
+ static final String THREAD_FIELD_NAME = stop001a.THREAD_FIELD_NAME;
+ static final String THROWABLE_FIELD_NAME = stop001a.THROWABLE_FIELD_NAME;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new stop001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for threadID value from a static field
+ log.display("Getting threadID value from static field: "
+ + THREAD_FIELD_NAME);
+ long threadID = queryObjectID(classID, THREAD_FIELD_NAME, JDWP.Tag.THREAD);
+ log.display(" got threadID: " + threadID);
+
+ // query debuggee for throwable objectID value from a static field
+ log.display("Getting throwable objectID value from static field: "
+ + THROWABLE_FIELD_NAME);
+ long objectID = queryObjectID(classID, THROWABLE_FIELD_NAME, JDWP.Tag.OBJECT);
+ log.display(" got objectID: " + objectID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(threadID, objectID);
+
+ log.display("\n>>> Checking that tested thread was really stopped \n");
+
+ // check if the thread was really stopped
+ confirmThreadStopped();
+
+ } finally {
+ log.display("\n>>> Finishing test \n");
+
+ // quit debugee
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ } else if (signal.equals(ERROR)) {
+ throw new TestBug("Debugee was not able to start tested thread"
+ + " (received signal: " + signal + ")");
+ } else if (!signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for objectID value from the class static field.
+ */
+ long queryObjectID(long classID, String fieldName, byte tag) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != tag) {
+ throw new Failure("Not threadID value returned from debuggee: " + value);
+ }
+
+ // extract threadID from the value
+ long objectID = ((Long)value.getValue()).longValue();
+ return objectID;
+ }
+
+ /**
+ * Perform testing JDWP command for specified threadID and throwable objectID.
+ */
+ void testCommand(long threadID, long objectID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" threadID: " + threadID);
+ command.addObjectID(threadID);
+ log.display(" throwable: " + objectID);
+ command.addObjectID(objectID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // there are no data to extract
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ }
+
+ /**
+ * Wait for signal from debugee that thread was really stopped
+ */
+ void confirmThreadStopped() {
+
+ // send debugee signal to run
+ log.display("Sending signal to debugee: " + RUN);
+ pipe.println(RUN);
+
+ // wait for signal DONE from debuggee
+ log.display("Waiting for signal from debugee: " + STOPPED);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+
+ // check received signal
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + STOPPED + ")");
+ } else if (signal.equals(STOPPED)) {
+ log.display("Tested thread was really stopped into debuggee");
+ } else if (signal.equals(NOT_STOPPED)) {
+ log.complain("Tested thread was NOT really stopped into debuggee");
+ success = false;
+ } else {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + STOPPED + ")");
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Stop/stop001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ThreadReference/Stop/stop001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ThreadReference
+ * command: Stop
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * the thread is really stopped into debuggee VM.
+ * Test consists of two compoments:
+ * debugger: stop001
+ * debuggee: stop001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains from debuggee classID for tested thread class
+ * and threadID as the value of a class static field. The tested thread
+ * into debuggee is in a waiting state in this time and is ready for
+ * stopping.
+ * Then, debugger creates command packet for ThreadReference.Stop
+ * command with the found threadID as an argument, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and ensures the packet does not has any data. Then debugger requests
+ * from debuggee confirmation about thread stopped and checks above
+ * mentioned assertions.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ThreadReference.Stop.stop001
+ * nsk.jdwp.ThreadReference.Stop.stop001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ThreadReference.Stop.stop001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Stop/stop001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.Stop;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class stop001a {
+
+ // name for the tested thread
+ public static final String THREAD_NAME = "TestedThreadName";
+ public static final String THREAD_FIELD_NAME = "thread";
+ public static final String THROWABLE_FIELD_NAME = "throwable";
+
+ // frames count for tested thread in recursive method invokation
+ public static final int FRAMES_COUNT = 10;
+
+ // notification object to notify debuggee that thread is started
+ private static Object threadStarting = new Object();
+ // object which thread will wait for before being interruted
+ private static Object threadWaiting = new Object();
+
+ // scaffold objects
+ private static volatile ArgumentHandler argumentHandler = null;
+ private static volatile Log log = null;
+
+ public static void main(String args[]) {
+ stop001a _stop001a = new stop001a();
+ System.exit(stop001.JCK_STATUS_BASE + _stop001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+ long timeout = argumentHandler.getWaitTime() * 60 * 1000; // milliseconds
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // load tested class and create tested thread
+ log.display("Creating object of tested class");
+ TestedClass.thread = new TestedClass(THREAD_NAME);
+
+ // start the thread and wait for notification from it
+ synchronized (threadStarting) {
+ TestedClass.thread.start();
+ try {
+ threadStarting.wait();
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for thread started:\n\t" + e);
+ pipe.println(stop001.ERROR);
+ log.display("Debugee FAILED");
+ return stop001.FAILED;
+ }
+
+ // ensure that tested thread is waiting for object
+ synchronized (threadWaiting) {
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + stop001.READY);
+ pipe.println(stop001.READY);
+ }
+ }
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + stop001.RUN);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(stop001.RUN)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + stop001.RUN + ")");
+ log.display("Debugee FAILED");
+ return stop001.FAILED;
+ }
+
+ // wait for thread finished in a waittime interval
+ log.display("Waiting for tested thread finished for timeout: " + timeout);
+ try {
+ TestedClass.thread.join(timeout);
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for tested thread finished:\n\t" + e);
+ pipe.println(stop001.ERROR);
+ log.display("Debugee FAILED");
+ return stop001.FAILED;
+ }
+
+ // test if thread was interrupted by debugger
+ if (TestedClass.thread.isAlive()) {
+ log.display("Sending signal to debugger: " + stop001.NOT_STOPPED);
+ pipe.println(stop001.NOT_STOPPED);
+ // interrupt thread to allow it to finish
+ TestedClass.thread.interrupt();
+ } else {
+ log.display("Sending signal to debugger: " + stop001.STOPPED);
+ pipe.println(stop001.STOPPED);
+ }
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + stop001.QUIT);
+ signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(stop001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + stop001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return stop001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return stop001.PASSED;
+ }
+
+ // tested thread class
+ public static class TestedClass extends Thread {
+
+ // field with the tested Thread value
+ public static volatile TestedClass thread = null;
+
+ // field with the tested Throwable value
+ public static volatile Throwable throwable = new Throwable("Tested throwable");
+
+ TestedClass(String name) {
+ super(name);
+ }
+
+ // start the thread and recursive invoke makeFrames()
+ public void run() {
+ log.display("Tested thread started");
+
+ synchronized (threadWaiting) {
+
+ // notify debuggee that thread started
+ synchronized (threadStarting) {
+ threadStarting.notifyAll();
+ }
+
+ // wait infinitely for notification object
+ try {
+ threadWaiting.wait();
+ log.complain("Tested thread NOT interrupted");
+ } catch (InterruptedException e) {
+ log.display("Tested thread interrupted");
+ }
+ }
+
+ log.display("Tested thread finished");
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Suspend/suspend001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.Suspend;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ThreadReference.Suspend.
+ *
+ * See suspend001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class suspend001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String ERROR = "error";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ThreadReference.Suspend";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "suspend001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ThreadReference.Suspend";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ThreadReference.Suspend;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the tested thread and statioc field with thread value
+ static final String TESTED_CLASS_FIELD_NAME = suspend001a.FIELD_NAME;
+ static final String TESTED_THREAD_NAME = suspend001a.THREAD_NAME;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new suspend001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ long threadID = 0;
+
+ // work with prepared debuggee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for threadID value from a static field
+ log.display("Getting threadID value from static field: "
+ + TESTED_CLASS_FIELD_NAME);
+ threadID = queryThreadID(classID, TESTED_CLASS_FIELD_NAME);
+ log.display(" got threadID: " + threadID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(threadID);
+
+ } finally {
+
+ log.display("\n>>> Finishing test \n");
+
+ // resumme suspended thread
+ if (threadID != 0) {
+ log.display("Resuming suspended thread");
+ debugee.resumeThread(threadID);
+ }
+
+ // quit debugee
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ } else if (signal.equals(ERROR)) {
+ throw new TestBug("Debugee was not able to start tested thread"
+ + " (received signal: " + signal + ")");
+ } else if (!signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for threadID value of statuic field of the class.
+ */
+ long queryThreadID(long classID, String fieldName) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != JDWP.Tag.THREAD) {
+ throw new Failure("Not threadID value returned from debuggee: " + value);
+ }
+
+ // extract threadID from the value
+ long threadID = ((Long)value.getValue()).longValue();
+ return threadID;
+ }
+
+ /**
+ * Query debuggee for suspend status of the thread.
+ */
+ int querySuspendStatus(long threadID) {
+ log.display("Getting suspend status for threadID: " + threadID);
+ CommandPacket command = new CommandPacket(JDWP.Command.ThreadReference.Status);
+ command.addObjectID(threadID);
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+
+ try {
+ reply.resetPosition();
+
+ int threadStatus = reply.getInt();
+ int suspendStatus = reply.getInt();
+ log.display(" got suspendStatus: " + suspendStatusString(suspendStatus));
+ return suspendStatus;
+ } catch (BoundException e) {
+ throw new Failure("Caught BoundException while parsing reply for ThreadReference.Status:\n\t"
+ + e);
+ }
+ }
+
+ /**
+ * Perform testing JDWP command for specified threadID.
+ */
+ void testCommand(long threadID) {
+ // check that tested thread is not suspended before command sent
+ int suspendStatus = querySuspendStatus(threadID);
+ if (suspendStatus == JDWP.SuspendStatus.SUSPEND_STATUS_SUSPENDED) {
+ throw new Failure("SuspendStatus reports thread is suspended before sending Suspend command: "
+ + suspendStatusString(suspendStatus));
+ } else {
+ log.display("Thread is not suspended");
+ }
+
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" threadID: " + threadID);
+ command.addObjectID(threadID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ // check that tested thread is suspended after Suspend command sent
+ suspendStatus = querySuspendStatus(threadID);
+ if ((suspendStatus & JDWP.SuspendStatus.SUSPEND_STATUS_SUSPENDED) == 0) {
+ log.complain("SuspendStatus reports thread is not suspended after Suspend command sent: "
+ + suspendStatusString(suspendStatus));
+ } else {
+ log.display("Thread is suspended");
+ }
+
+ }
+
+ /**
+ * Return string representation of thread suspend status.
+ */
+ private static String suspendStatusString(int status) {
+ String s = null;
+ if ((status & JDWP.SuspendStatus.SUSPEND_STATUS_SUSPENDED) != 0) {
+ s = "SUSPEND_STATUS_SUSPENDED";
+ } else if (status == 0) {
+ s = "NONE";
+ } else {
+ s = "unknown";
+ }
+ return status + "=" + s;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Suspend/suspend001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ThreadReference/Suspend/suspend001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ThreadReference
+ * command: Suspend
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * thread becomes suspended status.
+ * Test consists of two compoments:
+ * debugger: suspend001
+ * debuggee: suspend001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains from debuggee classID for tested thread class
+ * and threadID as the value of a class static field. Debugger checks
+ * that thread has not suspended status before sending tested command.
+ * Then, debugger creates command packet for ThreadReference.Suspend
+ * command with the found threadID as an argument, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and ensures there is no data into the package. Also debugger queries
+ * debuggee for suspend status of the tested thread and chacks that thread
+ * has status suspended.
+ * Finally, debugger resumes suspended thread into debuggee, sends debuggee
+ * signal to quit, waits for it exits and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ThreadReference.Suspend.suspend001
+ * nsk.jdwp.ThreadReference.Suspend.suspend001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ThreadReference.Suspend.suspend001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Suspend/suspend001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.Suspend;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class suspend001a {
+
+ // name for the tested thread
+ public static final String THREAD_NAME = "TestedThreadName";
+ public static final String FIELD_NAME = "thread";
+
+ // notification object to notify debuggee that thread started
+ private static Object threadStarted = new Object();
+ // lock object to prevent thread from exit
+ private static Object threadLock = new Object();
+
+ // scaffold objects
+ private static volatile ArgumentHandler argumentHandler = null;
+ private static volatile Log log = null;
+
+ public static void main(String args[]) {
+ suspend001a _suspend001a = new suspend001a();
+ System.exit(suspend001.JCK_STATUS_BASE + _suspend001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // lock the object to prevent thread from exit
+ synchronized (threadLock) {
+
+ // load tested class and create tested thread
+ log.display("Creating object of tested class");
+ TestedClass.thread = new TestedClass(THREAD_NAME);
+
+ // start the thread and wait for notification from it
+ synchronized (threadStarted) {
+ TestedClass.thread.start();
+ try {
+ threadStarted.wait();
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + suspend001.READY);
+ pipe.println(suspend001.READY);
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for thread started: " + e);
+ pipe.println(suspend001.ERROR);
+ }
+ }
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + suspend001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(suspend001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + suspend001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return suspend001.FAILED;
+ }
+
+ // allow started thread to exit
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return suspend001.PASSED;
+ }
+
+ // tested thread class
+ public static class TestedClass extends Thread {
+
+ // field with the tested Thread value
+ public static volatile TestedClass thread = null;
+
+ TestedClass(String name) {
+ super(name);
+ }
+
+ public void run() {
+ log.display("Tested thread started");
+
+ // notify debuggee that thread really started
+ synchronized (threadStarted) {
+ threadStarted.notifyAll();
+ }
+
+ // wait for lock object released
+ synchronized (threadLock) {
+ log.display("Tested thread finished");
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/SuspendCount/suspendcnt001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.SuspendCount;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: ThreadReference.SuspendCount.
+ *
+ * See suspendcnt001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class suspendcnt001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String ERROR = "error";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.ThreadReference.SuspendCount";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "suspendcnt001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "ThreadReference.SuspendCount";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ThreadReference.SuspendCount;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of the tested thread and statioc field with thread value
+ static final String TESTED_CLASS_FIELD_NAME = suspendcnt001a.FIELD_NAME;
+ static final String TESTED_THREAD_NAME = suspendcnt001a.THREAD_NAME;
+
+ // expected number od suspend count
+ static final int SUSPEND_COUNT = 5;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new suspendcnt001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ long threadID = 0;
+
+ // work with prepared debuggee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for threadID value from a static field
+ log.display("Getting threadID value from static field: "
+ + TESTED_CLASS_FIELD_NAME);
+ threadID = queryThreadID(classID, TESTED_CLASS_FIELD_NAME);
+ log.display(" got threadID: " + threadID);
+
+ // request debuggee to suspend tested thread
+ log.display("Suspendig thread " + SUSPEND_COUNT + " times for threadID: " + threadID);
+ for (int i = 0; i < SUSPEND_COUNT; i++) {
+ debugee.suspendThread(threadID);
+ }
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(threadID);
+
+ } finally {
+
+ log.display("\n>>> Finishing test \n");
+
+ // resumme suspended thread
+ if (threadID != 0) {
+ log.display("Resuming " + SUSPEND_COUNT + " times suspended thread: " + threadID);
+ for (int i = 0; i < SUSPEND_COUNT; i++) {
+ debugee.resumeThread(threadID);
+ }
+ }
+
+ // quit debugee
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (signal == null) {
+ throw new TestBug("Null signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ } else if (signal.equals(ERROR)) {
+ throw new TestBug("Debugee was not able to start tested thread"
+ + " (received signal: " + signal + ")");
+ } else if (!signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for threadID value of statuic field of the class.
+ */
+ long queryThreadID(long classID, String fieldName) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debugee.getClassFieldID(classID, fieldName, true);
+ // get value of the field
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has THREAD tag
+ if (value.getTag() != JDWP.Tag.THREAD) {
+ throw new Failure("Not threadID value returned from debuggee: " + value);
+ }
+
+ // extract threadID from the value
+ long threadID = ((Long)value.getValue()).longValue();
+ return threadID;
+ }
+
+ /**
+ * Query debuggee for suspend status of the thread.
+ */
+ int querySuspendStatus(long threadID) {
+ log.display("Getting suspend status for threadID: " + threadID);
+ CommandPacket command = new CommandPacket(JDWP.Command.ThreadReference.Status);
+ command.addObjectID(threadID);
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+
+ try {
+ reply.resetPosition();
+
+ int threadStatus = reply.getInt();
+ int suspendStatus = reply.getInt();
+ log.display(" got suspendStatus: " + suspendStatusString(suspendStatus));
+ return suspendStatus;
+ } catch (BoundException e) {
+ throw new Failure("Caught BoundException while parsing reply for ThreadReference.Status:\n\t"
+ + e);
+ }
+ }
+
+ /**
+ * Perform testing JDWP command for specified threadID.
+ */
+ void testCommand(long threadID) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" threadID: " + threadID);
+ command.addObjectID(threadID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ int suspendCount = 0;
+ try {
+ suspendCount = reply.getInt();
+ log.display(" suspendCount: " + suspendCount);
+ } catch (BoundException e) {
+ log.complain("Unable to extract suspend count number form the reply packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ if (suspendCount < 0) {
+ log.complain("Negative number of suspend count returned: " + suspendCount
+ + "(expected: " + SUSPEND_COUNT + ")");
+ success = false;
+ }
+
+ if (suspendCount != SUSPEND_COUNT) {
+ log.complain("Unexpected number of suspend count returned: " + suspendCount
+ + "(expected: " + SUSPEND_COUNT + ")");
+ success = false;
+ }
+
+ }
+
+ /**
+ * Return string representation of thread suspend status.
+ */
+ private static String suspendStatusString(int status) {
+ String s = null;
+ if ((status & JDWP.SuspendStatus.SUSPEND_STATUS_SUSPENDED) != 0) {
+ s = "SUSPEND_STATUS_SUSPENDED";
+ } else if (status == 0) {
+ s = "NONE";
+ } else {
+ s = "unknown";
+ }
+ return status + "=" + s;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/SuspendCount/suspendcnt001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ThreadReference/SuspendCount/suspendcnt001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ThreadReference
+ * command: SuspendCount
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * returned number of suspend count is equal to real number
+ * of thread suspending attempts.
+ * Test consists of two compoments:
+ * debugger: suspendcnt001
+ * debuggee: suspendcnt001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains from debuggee classID for tested thread class
+ * and threadID as the value of a class static field. Debugger suspends
+ * the thread SUSPEND_COUNT times before sending the tested command.
+ * Then, debugger creates command packet for ThreadReference.SuspendCount
+ * command with the found threadID as an argument, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts number of suspend count. Also debugger checks that returned
+ * suspend count is not negative and equal to the expected SUSPEND_COUNT.
+ * Finally, debugger resumes suspended thread into debuggee, sends debuggee
+ * signal to quit, waits for it exits and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ThreadReference.SuspendCount.suspendcnt001
+ * nsk.jdwp.ThreadReference.SuspendCount.suspendcnt001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ThreadReference.SuspendCount.suspendcnt001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/SuspendCount/suspendcnt001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.SuspendCount;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class suspendcnt001a {
+
+ // name for the tested thread
+ public static final String THREAD_NAME = "TestedThreadName";
+ public static final String FIELD_NAME = "thread";
+
+ // notification object to notify debuggee that thread started
+ private static Object threadStarted = new Object();
+ // lock object to prevent thread from exit
+ private static Object threadLock = new Object();
+
+ // scaffold objects
+ private static volatile ArgumentHandler argumentHandler = null;
+ private static volatile Log log = null;
+
+ public static void main(String args[]) {
+ suspendcnt001a _suspendcnt001a = new suspendcnt001a();
+ System.exit(suspendcnt001.JCK_STATUS_BASE + _suspendcnt001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // lock the object to prevent thread from exit
+ synchronized (threadLock) {
+
+ // load tested class and create tested thread
+ log.display("Creating object of tested class");
+ TestedClass.thread = new TestedClass(THREAD_NAME);
+
+ // start the thread and wait for notification from it
+ synchronized (threadStarted) {
+ TestedClass.thread.start();
+ try {
+ threadStarted.wait();
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + suspendcnt001.READY);
+ pipe.println(suspendcnt001.READY);
+ } catch (InterruptedException e) {
+ log.complain("Interruption while waiting for thread started: " + e);
+ pipe.println(suspendcnt001.ERROR);
+ }
+ }
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + suspendcnt001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (signal == null || !signal.equals(suspendcnt001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + suspendcnt001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return suspendcnt001.FAILED;
+ }
+
+ // allow started thread to exit
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return suspendcnt001.PASSED;
+ }
+
+ // tested thread class
+ public static class TestedClass extends Thread {
+
+ // field with the tested Thread value
+ public static volatile TestedClass thread = null;
+
+ TestedClass(String name) {
+ super(name);
+ }
+
+ public void run() {
+ log.display("Tested thread started");
+
+ // notify debuggee that thread really started
+ synchronized (threadStarted) {
+ threadStarted.notifyAll();
+ }
+
+ // wait for lock object released
+ synchronized (threadLock) {
+ log.display("Tested thread finished");
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ThreadGroup/threadgroup001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.ThreadGroup;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class threadgroup001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.ThreadReference.ThreadGroup";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "threadgroup001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "ThreadReference.ThreadGroup";
+ static final int JDWP_COMMAND_ID = JDWP.Command.ThreadReference.ThreadGroup;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new threadgroup001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+
+ try {
+
+ // get top level thread groups
+
+ log.display("Getting IDs for top level thread groups");
+
+ long[] threadGroupIDs = null;
+ int groups = 0;
+
+ {
+ log.display("Create command packet " + "TopLevelThreadGroups");
+ CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.TopLevelThreadGroups);
+
+ log.display("Waiting for reply to command");
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+ log.display("Valid reply packet received");
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ groups = reply.getInt();
+ log.display(" groups: " + groups);
+
+ threadGroupIDs = new long[groups];
+
+ for (int i = 0; i < groups; i++) {
+ long threadGroupID = reply.getObjectID();
+ log.display(" #" + i + " threadGroupID: " + threadGroupID);
+ threadGroupIDs[i] = threadGroupID;
+ }
+
+ if (groups < 0) {
+ log.complain("Negative number of thread groups returned while getting top level thread groups IDs: " + groups);
+ success = false;
+ }
+
+ if (groups == 0) {
+ log.complain("No thread groups IDs returned while getting top level thread groups IDs: " + groups);
+ success = false;
+ }
+
+ }
+
+ // get threads from all thread groups found
+
+ boolean found = false;
+ long checkedThreadGroupID = 0;
+
+ long[] threadIDs = null;
+ int threads = 0;
+
+ for (int i = 0; i < groups; i++) {
+ checkedThreadGroupID = threadGroupIDs[i];
+ log.display("Getting IDs of the thread from thread group: #" + i);
+
+ log.display("Create command packet " +
+ "ThreadGroupReference.Children");
+ CommandPacket command = new CommandPacket(JDWP.Command.ThreadGroupReference.Children);
+ command.addObjectID(checkedThreadGroupID);
+ command.setLength();
+
+ log.display("Waiting for reply to command");
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+ log.display("Valid reply packet received");
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ threads = reply.getInt();
+ log.display(" threads: " + threads);
+
+ threadIDs = new long[threads];
+
+ for (int j = 0; j < threads; j++) {
+ long threadID = reply.getObjectID();
+ log.display(" #" + j + " threadID: " + threadID);
+ threadIDs[j] = threadID;
+ }
+
+ if (threads < 0) {
+ log.complain("Negative number of threads in the thread group: " + threads);
+ success = false;
+ }
+
+ if (threads > 0) {
+ log.display("Testing threads from thread group: #" + i);
+ found = true;
+ }
+ }
+
+ if (!found) {
+ log.complain("No threads found in all top level thread groups");
+ success = false;
+ }
+
+ // begin test of JDWP command
+
+ for (int i = 0; i < threads; i++) {
+
+ long threadID = threadIDs[i];
+
+ log.display("");
+ log.display("Getting ThreadGroup ID for " + i + " thread ID: "
+ + threadID);
+ log.display("Create command " + JDWP_COMMAND_NAME
+ + " with thread ID: " + threadID);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addObjectID(threadID);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ long threadGroupID = reply.getObjectID();
+ log.display(" group: " + threadGroupID);
+
+ if (threadGroupID != checkedThreadGroupID) {
+ log.complain("Unexpected threadGroupID returned for a thread: " + threadGroupID
+ + " (expected: " + checkedThreadGroupID + ")");
+ success = false;
+ }
+
+ if (! reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ success = false;
+ } else {
+ log.display("Reply packet parsed successfully");
+ }
+
+ }
+
+ // end test of JDWP command
+
+ } catch (Exception e) {
+ log.complain("Caught exception while testing JDWP command: " + e);
+ success = false;
+ } finally {
+ log.display("");
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ } catch (Exception e) {
+ log.complain("Caught unexpected exception while communicating with debugee: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Caught unexpected exception while starting the test: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ThreadGroup/threadgroup001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/ThreadReference/ThreadGroup/threadgroup001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: ThreadReference (11)
+ * command: ThreadGroup (5)
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * returned threadGroupID of a thread is equal to the expected
+ * one for all threads from a top level threads group.
+ * Test consists of two compoments:
+ * debugger: threadgroup001
+ * debuggee: threadgroup001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger prepares for testing JDWP command and finds
+ * top level thread group with a number threads and obtains
+ * ID's for this ThreadGroup and all its threads.
+ * Then, for each found thread debugger creates command packet for
+ * ThreadGroup command with the found checkedThreadGroupID as an argument,
+ * writes packet to the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and extracts threadGroupID from it. Also test checks that extracted
+ * threadGroupID of a thread is equal to the expected one.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.ThreadReference.ThreadGroup.threadgroup001
+ * nsk.jdwp.ThreadReference.ThreadGroup.threadgroup001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.ThreadReference.ThreadGroup.threadgroup001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/ThreadGroup/threadgroup001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.ThreadReference.ThreadGroup;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class threadgroup001a {
+
+ public static void main(String args[]) {
+ threadgroup001a _threadgroup001a = new threadgroup001a();
+ System.exit(threadgroup001.JCK_STATUS_BASE + _threadgroup001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return threadgroup001.PASSED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClasses/allclasses001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.AllClasses;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class allclasses001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.AllClasses";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "allclasses001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.AllClasses";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.AllClasses;
+
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new allclasses001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ String classSignature = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // begin test of JDWP command
+
+ try {
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ int classes = reply.getInt();
+ log.display(" classes: " + classes);
+
+ int found = 0;
+ for (int i = 0; i < classes; i++) {
+
+ byte refTypeTag = reply.getByte();
+ log.display(" " + i + " refTypeTag: " + refTypeTag);
+
+ long typeID = reply.getReferenceTypeID();
+ log.display(" " + i + " typeID: " + typeID);
+
+ String signature = reply.getString();
+ log.display(" " + i + " signature: " + signature);
+
+ int status = reply.getInt();
+ log.display(" " + i + " status: " + status);
+
+ if (signature.equals(classSignature)) {
+ found++;
+ log.display("FOUND: expected class signature: " + found + " time");
+ }
+ }
+
+ if (! reply.isParsed()) {
+ log.complain("Extra bytes in reply packet at: " + reply.currentPosition());
+ success = false;
+ }
+
+ if (classes < 0) {
+ log.complain("Negative number of returned classes: " + classes);
+ success = false;
+ }
+
+ if (classes == 0) {
+ log.complain("No class returned");
+ success = false;
+ }
+
+ if (found <= 0) {
+ log.complain("No expected class signature found: " + classSignature);
+ success = false;
+ }
+
+ if (found > 1) {
+ log.complain("Too many classes (" + found + ") found for signature: " + classSignature);
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Exception catched: " + e);
+ success = false;
+ }
+
+ // end test of JDWP command
+
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED: " + code);
+ } else {
+ log.complain("Debugee FAILED: " + code);
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClasses/allclasses001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/AllClasses/allclasses001.
+ * VM Testbase keywords: [jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: VirtualMachine
+ * command: AllClasses
+ * Test checks that debugee accept command and replies
+ * with correct reply packet.
+ * First, test launches debuggee VM using support classes
+ * and connects to it.
+ * Then test sends AllClasses command and waits for a
+ * reply packet.
+ * Then test checks if the received reply packet has proper
+ * structure and extracts class signatures from the packet data.
+ * Also test check if debugee class signature is in the
+ * among the received classes.
+ * After JDWP command has been tested, test sends debugee VM
+ * signal to quit, waits for debugee VM exits and exits too
+ * with a proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.AllClasses.allclasses001
+ * nsk.jdwp.VirtualMachine.AllClasses.allclasses001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.AllClasses.allclasses001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClasses/allclasses001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.AllClasses;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class allclasses001a {
+
+ public static void main(String args[]) {
+ allclasses001a _allclasses001a = new allclasses001a();
+ System.exit(allclasses001.JCK_STATUS_BASE + _allclasses001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return allclasses001.PASSED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2003, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.AllClassesWithGeneric;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * This test checks that the JDWP command <code>AllClassesWithGeneric</code>
+ * from the <code>VirtualMachine</code> command set returns generic signature
+ * information properly.<br>
+ * Debuggee part of the test creates instances of several tested classes. Some
+ * of the classes are generic. Debugger part obtains signature information of
+ * all loaded classes by sending the tested JDWP command. Proper generic
+ * signature should be returned for each tested class which is generic, or
+ * an empty string for non-generic one. All tested classes should be found
+ * in reply packet as well.
+ */
+public class allclswithgeneric001 {
+ static final String DEBUGGEE_CLASS =
+ "nsk.jdwp.VirtualMachine.AllClassesWithGeneric.allclswithgeneric001t";
+
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.AllClassesWithGeneric";
+ static final int JDWP_COMMAND_ID =
+ JDWP.Command.VirtualMachine.AllClassesWithGeneric;
+
+ static final String COMMAND_READY = "ready";
+ static final String COMMAND_QUIT = "quit";
+
+ static final String[][] classes = {
+ {"Lnsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001t;",
+ "NULL"},
+
+ {"Lnsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001b;",
+ "<L:Ljava/lang/String;>Ljava/lang/Object;"},
+
+ {"Lnsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001c;",
+ "<A:Ljava/lang/Object;B:Ljava/lang/Integer;>Ljava/lang/Object;"},
+
+ {"Lnsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001d;",
+ "<T:Ljava/lang/Object;>Ljava/lang/Object;Lnsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001if<TT;>;"},
+
+ {"Lnsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001e;",
+ "NULL"},
+
+ {"Lnsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001if;",
+ "<I:Ljava/lang/Object;>Ljava/lang/Object;"},
+
+ {"Lnsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001f;",
+ "NULL"},
+
+ {"Lnsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001g;",
+ "<E:Lnsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001e;:Lnsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001if;>Ljava/lang/Object;"},
+
+ {"Lnsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001h;",
+ "<A1:Ljava/lang/Object;B1:Ljava/lang/Object;C1:Ljava/lang/Object;>Lnsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001d<TA1;>;Lnsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001if2<TA1;TB1;TC1;>;"}
+ };
+
+ static final int CLS_NUM = classes.length;
+
+ private int foundClasses[] = new int[CLS_NUM];
+
+ private Log log;
+
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + Consts.JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new allclswithgeneric001().runThis(argv, out);
+ }
+
+ public int runThis(String argv[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ boolean result = true;
+
+ try {
+ for(int i=0; i<CLS_NUM; i++)
+ foundClasses[i] = 0;
+
+ Binder binder = new Binder(argumentHandler, log);
+
+ log.display("Starting debuggee VM ...");
+ Debugee debuggee = binder.bindToDebugee(DEBUGGEE_CLASS);
+
+ Transport transport = debuggee.getTransport();
+ IOPipe pipe = debuggee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event ...");
+ debuggee.waitForVMInit();
+
+ log.display("Querying for IDSizes ...");
+ debuggee.queryForIDSizes();
+
+ log.display("Resuming debuggee VM ...");
+ debuggee.resume();
+
+ log.display("Waiting for command: " + COMMAND_READY
+ + " ...");
+ String cmd = pipe.readln();
+ log.display(" ... Received command: " + cmd);
+
+ try {
+ /////// begin test of JDWP command
+ log.display("\n>>>>>> Create command " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("\nWaiting for reply packet ...");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display(" ... Reply packet received:\n" + reply);
+
+ log.display("\nChecking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ /* parsing of reply data:
+ int classes - Number of reference types that follow
+
+ ---- Repeated 'classes' times:
+ byte refTypeTag - Kind of following reference type.
+ referenceTypeID typeID - Loaded reference type.
+ string signature - The JNI signature for the loaded reference type.
+ string genericSignature - The generic signature for the loaded reference type
+ or an empty string if there is none.
+ int status - The current class status.
+ ----
+ */
+ log.display("\nParsing reply packet:");
+ reply.resetPosition();
+
+ int cls_num = reply.getInt();
+ log.display("\tclasses: " + cls_num);
+
+ for (int i=0; i<cls_num; i++) {
+ byte refTypeTag = reply.getByte();
+ long typeID = reply.getReferenceTypeID();
+ String signature = reply.getString();
+ String genSignature = reply.getString();
+ int status = reply.getInt();
+
+ int idx = findClass(signature);
+ if (idx != -1) {
+ foundClasses[idx]++;
+
+ log.display("\n--> found tested class "
+ + classes[idx][0] + " :"
+ + "\n\t\trefTypeTag: " + refTypeTag
+ + "\n\t\ttypeID: " + typeID
+ + "\n\t\tsignature: " + signature);
+
+ if (genSignature.length() == 0) // a non-generic class
+ genSignature = "NULL";
+ if (!genSignature.equals(classes[idx][1])) {
+ log.complain("TEST FAILED: Unexpected generic signature of tested class #"
+ + (i+1) + " (" + classes[idx][0] + ")"
+ + " in the reply packet:"
+ + "\n\tGot: " + genSignature
+ + "\n\tExpected: " + classes[idx][1] + "\n");
+ result = false;
+ }
+ else
+ log.display("\t\tgeneric signature: " + genSignature);
+
+ log.display("\t\tstatus: " + status);
+ }
+ }
+
+ if (!reply.isParsed()) {
+ log.complain("TEST FAILED: Extra trailing bytes found in reply packet at: "
+ + reply.currentPosition());
+ result = false;
+ } else
+ log.display("\n<<<<<< Reply packet parsed");
+ /////// end test of JDWP command
+
+ for (int i=0; i<CLS_NUM; i++)
+ if (foundClasses[i] != 1) {
+ result = false;
+ log.complain("TEST FAILED: Unexpected number of reference types for the tested class\n\t"
+ + classes[i][0] + "\n\tin reply packet on "
+ + JDWP_COMMAND_NAME
+ + ":\n\tGot: " + foundClasses[i]
+ + "\n\tExpected: 1");
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught exception while testing JDWP command: "
+ + e);
+ result = false;
+ } finally {
+ log.display("Sending command: " + COMMAND_QUIT + " ...");
+ pipe.println(COMMAND_QUIT);
+
+ log.display("Waiting for debuggee exits ...");
+ int code = debuggee.waitFor();
+ if (code == Consts.JCK_STATUS_BASE + Consts.TEST_PASSED) {
+ log.display(" ... Debuggee PASSED with the exit code: "
+ + code);
+ } else {
+ log.complain(" ... Debuggee FAILED with the exit code: "
+ + code);
+ result = false;
+ }
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while communicating with debugee: "
+ + e);
+ result = false;
+ }
+
+ if (!result)
+ return Consts.TEST_FAILED;
+
+ return Consts.TEST_PASSED;
+ }
+
+ private int findClass(String cls) {
+ for (int i=0; i<CLS_NUM; i++)
+ if (cls.equals(classes[i][0]))
+ return i; // the tested class found
+
+ return -1; // the tested class not found
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001.
+ * VM Testbase keywords: [jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * JDWP command set: VirtualMachine
+ * JDWP command: AllClassesWithGeneric
+ * It checks that the command returns generic signature information
+ * properly.
+ * Debuggee part of the test creates instances of several tested classes.
+ * Some of the classes are generic. Debugger part obtains signature
+ * information of all loaded classes by sending the tested JDWP command.
+ * Proper generic signature should be returned for each tested class
+ * which is generic, or an empty string for non-generic one. All tested
+ * classes should be found in reply packet as well.
+ * COMMENTS
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.AllClassesWithGeneric.allclswithgeneric001
+ * nsk.jdwp.VirtualMachine.AllClassesWithGeneric.allclswithgeneric001t
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.AllClassesWithGeneric.allclswithgeneric001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllClassesWithGeneric/allclswithgeneric001t.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2003, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.AllClassesWithGeneric;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class allclswithgeneric001t {
+ public static void main(String args[]) {
+ ArgumentHandler argHandler = new ArgumentHandler(args);
+ Log log = new Log(System.err, argHandler);
+ IOPipe pipe = argHandler.createDebugeeIOPipe(log);
+
+ // load tested classes
+ allclswithgeneric001b<String> _allclswithgeneric001b =
+ new allclswithgeneric001b<String>();
+ allclswithgeneric001c<Boolean, Integer> _allclswithgeneric001c =
+ new allclswithgeneric001c<Boolean, Integer>();
+ allclswithgeneric001e _allclswithgeneric001e =
+ new allclswithgeneric001e();
+ allclswithgeneric001if<Object> _allclswithgeneric001if =
+ new allclswithgeneric001d<Object>();
+ allclswithgeneric001f _allclswithgeneric001f =
+ new allclswithgeneric001f();
+ allclswithgeneric001g<allclswithgeneric001f> _allclswithgeneric001g =
+ new allclswithgeneric001g<allclswithgeneric001f>();
+ allclswithgeneric001h<Byte, Double, Float> _allclswithgeneric001h =
+ new allclswithgeneric001h<Byte, Double, Float>();
+
+ log.display("Debuggee VM started\nSending command: "
+ + allclswithgeneric001.COMMAND_READY);
+ pipe.println(allclswithgeneric001.COMMAND_READY);
+
+ log.display("Waiting for command: "
+ + allclswithgeneric001.COMMAND_QUIT + " ...");
+ String cmd = pipe.readln();
+ log.display(" ... Received command: " + cmd
+ + "\nDebuggee is exiting ...");
+
+ System.exit(Consts.JCK_STATUS_BASE + Consts.TEST_PASSED);
+ }
+}
+
+/*
+ * Dummy classes used only for verifying generic signature information
+ * in a debugger.
+ */
+
+class allclswithgeneric001b<L extends String> {}
+
+class allclswithgeneric001c<A, B extends Integer> {}
+
+interface allclswithgeneric001if<I> {
+ int allclswithgeneric001ifMeth();
+
+ <I> int allclswithgeneric001ifMeth2(I v);
+}
+
+class allclswithgeneric001d<T> implements allclswithgeneric001if<T> {
+ public int allclswithgeneric001ifMeth() {
+ return 1;
+ }
+
+ public <T> int allclswithgeneric001ifMeth2(T v) {
+ return 2;
+ }
+}
+
+class allclswithgeneric001e {}
+
+class allclswithgeneric001f extends allclswithgeneric001e implements allclswithgeneric001if {
+ public int allclswithgeneric001ifMeth() {
+ return 3;
+ }
+
+ public int allclswithgeneric001ifMeth2(Object v) {
+ return 4;
+ }
+}
+
+class allclswithgeneric001g<E extends allclswithgeneric001e & allclswithgeneric001if> {}
+
+interface allclswithgeneric001if2<A, B, C> {}
+
+class allclswithgeneric001h<A1, B1, C1>
+ extends allclswithgeneric001d<A1>
+ implements allclswithgeneric001if2<A1, B1, C1> {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllThreads/allthreads001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.AllThreads;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class allthreads001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.AllThreads";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "allthreads001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.AllThreads";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.AllThreads;
+
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new allthreads001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ String classSignature = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // begin test of JDWP command
+
+ try {
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ int threads = reply.getInt();
+ log.display(" threads: " + threads);
+
+ if (threads < 0) {
+ log.complain("Negative number of returned threads: " + threads);
+ success = false;
+ }
+
+ if (threads == 0) {
+ log.complain("No threads returned");
+ success = false;
+ }
+
+ for (int i = 0; i < threads; i++) {
+ long threadID = reply.getObjectID();
+ log.display(" " + i + " threadID: " + threadID);
+ }
+
+ if (! reply.isParsed()) {
+ log.complain("Extra bytes in reply packet at: "
+ + reply.currentPosition());
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Exception catched: " + e);
+ success = false;
+ }
+
+ // end test of JDWP command
+
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED: " + code);
+ } else {
+ log.complain("Debugee FAILED: " + code);
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllThreads/allthreads001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/AllThreads/allthreads001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: VirtualMachine
+ * command: AllThreads
+ * Test checks that debugee accept command and replies
+ * with correct reply packet.
+ * First, test launches debuggee VM using support classes
+ * and connects to it.
+ * Then test sends AllThreads command and waits for a
+ * reply packet.
+ * Then test checks if the received reply packet has proper
+ * structure and extracts threadIDs list from the packet data.
+ * After JDWP command has been tested, test sends debugee VM
+ * signal to quit, waits for debugee VM exits and exits too
+ * with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.AllThreads.allthreads001
+ * nsk.jdwp.VirtualMachine.AllThreads.allthreads001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.AllThreads.allthreads001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/AllThreads/allthreads001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.AllThreads;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class allthreads001a {
+
+ public static void main(String args[]) {
+ allthreads001a _allclasses001a = new allthreads001a();
+ System.exit(allthreads001.JCK_STATUS_BASE + _allclasses001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return allthreads001.PASSED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Capabilities/capabilities001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.Capabilities;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+import java.util.*;
+
+public class capabilities001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.Capabilities";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "capabilities001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.Capabilities";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.Capabilities;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new capabilities001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ // begin test of JDWP command
+
+ try {
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ byte canWatchFieldModification = reply.getByte();
+ log.display(" canWatchFieldModification: " + canWatchFieldModification);
+
+ byte canWatchFieldAction = reply.getByte();
+ log.display(" canWatchFieldAction: " + canWatchFieldAction);
+
+ byte canGetBytecodes = reply.getByte();
+ log.display(" canGetBytecodes: " + canGetBytecodes);
+
+ byte canGetSyntheticAttribute = reply.getByte();
+ log.display(" canGetSyntheticAttribute: " + canGetSyntheticAttribute);
+
+ byte canGetOwnedMonitorInfo = reply.getByte();
+ log.display(" canGetOwnedMonitorInfo: " + canGetOwnedMonitorInfo);
+
+ byte canGetCurrentContendedMonitor = reply.getByte();
+ log.display(" canGetCurrentContendedMonitor: " + canGetCurrentContendedMonitor);
+
+ byte canGetMonitorInfo = reply.getByte();
+ log.display(" canGetMonitorInfo: " + canGetMonitorInfo);
+
+ if (! reply.isParsed()) {
+ log.complain("Extra bytes in reply packet at: " + reply.currentPosition());
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Exception catched: " + e);
+ success = false;
+ }
+
+ // end test of JDWP command
+
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED: " + code);
+ } else {
+ log.complain("Debugee FAILED: " + code);
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Capabilities/capabilities001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/Capabilities/capabilities001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: VirtualMachine
+ * command: Capabilities
+ * Test checks that debugee accept command and replies
+ * with correct reply packet.
+ * First, test launches debuggee VM using support classes
+ * and connects to it.
+ * Then test sends Capabilities command and waits for a
+ * reply packet.
+ * Then test checks if the received reply packet has proper
+ * structure and extracts capabilities info from the packet data.
+ * After JDWP command has been tested, test sends debugee VM
+ * signal to quit, waits for debugee VM exits and exits too
+ * with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.Capabilities.capabilities001
+ * nsk.jdwp.VirtualMachine.Capabilities.capabilities001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.Capabilities.capabilities001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Capabilities/capabilities001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.Capabilities;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class capabilities001a {
+
+ public static void main(String args[]) {
+ capabilities001a _capabilities001a = new capabilities001a();
+ System.exit(capabilities001.JCK_STATUS_BASE + _capabilities001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return capabilities001.PASSED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CapabilitiesNew/capabilitiesnew001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.CapabilitiesNew;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+import java.util.*;
+
+public class capabilitiesnew001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.CapabilitiesNew";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "capabilitiesnew001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.CapabilitiesNew";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.CapabilitiesNew;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new capabilitiesnew001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ // begin test of JDWP command
+
+ try {
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ byte canWatchFieldModification = reply.getByte();
+ log.display(" canWatchFieldModification: "
+ + canWatchFieldModification);
+
+ byte canWatchFieldAction = reply.getByte();
+ log.display(" canWatchFieldAction: "
+ + canWatchFieldAction);
+
+ byte canGetBytecodes = reply.getByte();
+ log.display(" canGetBytecodes: "
+ + canGetBytecodes);
+
+ byte canGetSyntheticAttribute = reply.getByte();
+ log.display(" canGetSyntheticAttribute: "
+ + canGetSyntheticAttribute);
+
+ byte canGetOwnedMonitorInfo = reply.getByte();
+ log.display(" canGetOwnedMonitorInfo: "
+ + canGetOwnedMonitorInfo);
+
+ byte canGetCurrentContendedMonitor = reply.getByte();
+ log.display(" canGetCurrentContendedMonitor: "
+ + canGetCurrentContendedMonitor);
+
+ byte canGetMonitorInfo = reply.getByte();
+ log.display(" canGetMonitorInfo: "
+ + canGetMonitorInfo);
+
+ byte canRedefineClasses = reply.getByte();
+ log.display(" canRedefineClasses: "
+ + canRedefineClasses);
+
+ byte canAddMethod = reply.getByte();
+ log.display(" canAddMethod: "
+ + canAddMethod);
+
+ byte canUnrestrictedlyRedefineClasses = reply.getByte();
+ log.display(" canUnrestrictedlyRedefineClasses: "
+ + canUnrestrictedlyRedefineClasses);
+
+ byte canPopFrames = reply.getByte();
+ log.display(" canPopFrames: "
+ + canPopFrames);
+
+ byte canUseInstanceFilters = reply.getByte();
+ log.display(" canUseInstanceFilters: "
+ + canUseInstanceFilters);
+
+ byte canGetSourceDebugExtension = reply.getByte();
+ log.display(" canGetSourceDebugExtension: "
+ + canGetSourceDebugExtension);
+
+ byte canRequestVMDeathEvent = reply.getByte();
+ log.display(" canRequestVMDeathEvent: "
+ + canRequestVMDeathEvent);
+
+ byte canSetDefaultStratum = reply.getByte();
+ log.display(" canSetDefaultStratum: "
+ + canSetDefaultStratum);
+
+ for (int i = 16; i <=32; i++) {
+ byte reserved = reply.getByte();
+ log.display(" reserved" + i + ": "
+ + reserved);
+ }
+
+ if (! reply.isParsed()) {
+ log.complain("Extra bytes in reply packet at: "
+ + reply.currentPosition());
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Exception catched: " + e);
+ success = false;
+ }
+
+ // end test of JDWP command
+
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED: " + code);
+ } else {
+ log.complain("Debugee FAILED: " + code);
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CapabilitiesNew/capabilitiesnew001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/CapabilitiesNew/capabilitiesnew001.
+ * VM Testbase keywords: [quick, jpda, jdwp, redefine]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: VirtualMachine
+ * command: CapabilitiesNew
+ * Test checks that debugee accept command and replies
+ * with correct reply packet.
+ * First, test launches debuggee VM using support classes
+ * and connects to it.
+ * Then test sends CapabilitiesNew command and waits for a
+ * reply packet.
+ * Then test checks if the received reply packet has proper
+ * structure and extracts capabilities info from the packet data.
+ * After JDWP command has been tested, test sends debugee VM
+ * signal to quit, waits for debugee VM exits and exits too
+ * with the proper exit code.
+ * COMMENTS
+ * This test is for JDK-1.4 or higher.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.CapabilitiesNew.capabilitiesnew001
+ * nsk.jdwp.VirtualMachine.CapabilitiesNew.capabilitiesnew001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.CapabilitiesNew.capabilitiesnew001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CapabilitiesNew/capabilitiesnew001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.CapabilitiesNew;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class capabilitiesnew001a {
+
+ public static void main(String args[]) {
+ capabilitiesnew001a _capabilitiesnew001a = new capabilitiesnew001a();
+ System.exit(capabilitiesnew001.JCK_STATUS_BASE + _capabilitiesnew001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return capabilitiesnew001.PASSED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassPaths/classpaths001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.ClassPaths;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class classpaths001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.ClassPaths";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "classpaths001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.ClassPaths";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.ClassPaths;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new classpaths001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ // begin test of JDWP command
+
+ try {
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ String baseDir = reply.getString();
+ log.display(" baseDir: " + baseDir);
+
+ int classpaths = reply.getInt();
+ log.display(" classpaths: " + classpaths);
+
+ for (int i = 0; i < classpaths; i++) {
+ String path = reply.getString();
+ log.display(" " + i + " path: " + path);
+ }
+
+ int bootclasspaths = reply.getInt();
+ log.display(" bootclasspaths: " + bootclasspaths);
+
+ for (int i = 0; i < bootclasspaths; i++) {
+ String path = reply.getString();
+ log.display(" " + i + " path: " + path);
+ }
+
+ if (! reply.isParsed()) {
+ log.complain("Extra bytes in reply packet at: " + reply.currentPosition());
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Exception catched: " + e);
+ success = false;
+ }
+
+ // end test of JDWP command
+
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED: " + code);
+ } else {
+ log.complain("Debugee FAILED: " + code);
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassPaths/classpaths001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/ClassPaths/classpaths001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test perform checking for
+ * command set: VirtualMachine
+ * command: ClassPaths
+ * Test launches debuggee VM using support classes and sends
+ * ClassPaths command to it. Then test receives reply for this
+ * command and prints classpath and bootclasspath value
+ * from received reply.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.ClassPaths.classpaths001
+ * nsk.jdwp.VirtualMachine.ClassPaths.classpaths001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.ClassPaths.classpaths001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassPaths/classpaths001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.ClassPaths;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class classpaths001a {
+
+ public static void main(String args[]) {
+ classpaths001a _classpaths001a = new classpaths001a();
+ System.exit(classpaths001.JCK_STATUS_BASE + _classpaths001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return classpaths001.PASSED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassesBySignature/classbysig001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.ClassesBySignature;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class classbysig001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.ClassesBySignature";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "classbysig001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.ClassesBySignature";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.ClassesBySignature;
+
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME;
+// static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME + ";";
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new classbysig001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ String classSignature = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // begin test of JDWP command
+
+ try {
+ log.display("Create command " + JDWP_COMMAND_NAME
+ + " with class signature: " + classSignature);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addString(classSignature);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ int classes = reply.getInt();
+ log.display(" classes: " + classes);
+
+ for (int i = 0; i < classes; i++) {
+
+ byte refTypeTag = reply.getByte();
+ log.display(" " + i + " refTypeTag: " + refTypeTag);
+
+ long typeID = reply.getReferenceTypeID();
+ log.display(" " + i + " typeID: " + typeID);
+
+ int status = reply.getInt();
+ log.display(" " + i + " status: " + status);
+ }
+
+ if (! reply.isParsed()) {
+ log.complain("Extra bytes in reply packet at: " + reply.currentPosition());
+ success = false;
+ }
+
+ if (classes < 0) {
+ log.complain("Negative number of returned classes: " + classes);
+ success = false;
+ }
+
+ if (classes == 0) {
+ log.complain("No class returned for signature: " + classSignature);
+ success = false;
+ }
+
+ if (classes > 1) {
+ log.complain("Too many classes returned for signature: " + classSignature);
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Exception catched: " + e);
+ success = false;
+ }
+
+ // end test of JDWP command
+
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED: " + code);
+ } else {
+ log.complain("Debugee FAILED: " + code);
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassesBySignature/classbysig001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/ClassesBySignature/classbysig001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test perform checking for
+ * command set: VirtualMachine
+ * command: ClassBySignature
+ * Test checks that debugee accept command and replies
+ * with correct reply packet. Also test checks that one
+ * and only one class will be found for specified class
+ * signature.
+ * First, test launches debuggee VM using support classes
+ * and connects to it.
+ * Than test sends ClassByName command with debugee class
+ * signature as an command argument and waits for a reply.
+ * Than test checks if the received reply packet has proper
+ * structure and only one class is found for specified
+ * class signature.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.ClassesBySignature.classbysig001
+ * nsk.jdwp.VirtualMachine.ClassesBySignature.classbysig001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.ClassesBySignature.classbysig001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ClassesBySignature/classbysig001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.ClassesBySignature;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class classbysig001a {
+
+ public static void main(String args[]) {
+ classbysig001a _classbysig001a = new classbysig001a();
+ System.exit(classbysig001.JCK_STATUS_BASE + _classbysig001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return classbysig001.PASSED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CreateString/createstr001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.CreateString;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+import java.util.*;
+
+public class createstr001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.CreateString";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "createstr001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.CreateString";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.CreateString;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new createstr001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ String stringValue = "Testing string value";
+
+ // begin test of JDWP command
+
+ try {
+ log.display("Create command " + JDWP_COMMAND_NAME
+ + " with string value: " + stringValue);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addString(stringValue);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ long stringID = reply.getObjectID();
+ log.display(" stringID: " + stringID);
+
+ if (! reply.isParsed()) {
+ log.complain("Extra bytes in reply packet at: " + reply.currentPosition());
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Exception catched: " + e);
+ success = false;
+ }
+
+ // end test of JDWP command
+
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED: " + code);
+ } else {
+ log.complain("Debugee FAILED: " + code);
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CreateString/createstr001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/CreateString/createstr001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test perform checking for
+ * command set: VirtualMachine
+ * command: CreateString
+ * Test checks that debugee accept command and replies
+ * with correct reply packet.
+ * First, test launches debuggee VM using support classes
+ * and connects to it.
+ * Than test sends CreateString command and waits for a reply.
+ * Than test checks if the received reply packet has proper
+ * structure and returns stringID.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.CreateString.createstr001
+ * nsk.jdwp.VirtualMachine.CreateString.createstr001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.CreateString.createstr001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/CreateString/createstr001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.CreateString;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class createstr001a {
+
+ public static void main(String args[]) {
+ createstr001a _createstr001a = new createstr001a();
+ System.exit(createstr001.JCK_STATUS_BASE + _createstr001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return createstr001.PASSED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Dispose/dispose001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.Dispose;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class dispose001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.Dispose";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "dispose001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.Dispose";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.Dispose;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new dispose001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ final ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ final Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ final Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ int bytesToWrite = 1024;
+
+ // begin test of JDWP command
+
+ try {
+ log.display("Creating command packet for " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ if (! reply.isParsed()) {
+ log.complain("Extra bytes in reply packet at: " + reply.currentPosition());
+ success = false;
+ }
+
+ log.display("Reply packet parsed successfully");
+
+ } catch (Exception e) {
+ log.complain("Exception catched: " + e);
+ success = false;
+ }
+
+/*
+ // check if transport connection has been actually closed
+
+ if (success) {
+
+ log.display("Trying to write VirtualMachine.Version command packet "
+ + "to the closed Transport connection");
+
+ try {
+ CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.Version);
+ transport.write(command);
+
+ log.complain("Command packet successfully written to the closed transport channel\n"
+ + "without any I/O exception thrown");
+ success = false;
+ } catch (IOException e) {
+ log.display("Caught expected IOException:\n\t" + e);
+ }
+
+ }
+*/
+
+ // end test of JDWP command
+
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED: " + code);
+ } else {
+ log.complain("Debugee FAILED: " + code);
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Dispose/dispose001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/Dispose/dispose001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for:
+ * command set: VirtualMachine
+ * command: Dispose
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: dispose001
+ * debuggee: dispose001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with execution commands.
+ * Then debugger creates command packet for Dispose command,
+ * writes packet to the transport channel, and waits for a reply
+ * packet.
+ * When reply packet is received debugger parses the packet structure.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with a proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.Dispose.dispose001
+ * nsk.jdwp.VirtualMachine.Dispose.dispose001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.Dispose.dispose001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Dispose/dispose001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.Dispose;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class dispose001a {
+
+ public static void main(String args[]) {
+ dispose001a _dispose001a = new dispose001a();
+ System.exit(dispose001.JCK_STATUS_BASE + _dispose001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return dispose001.PASSED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/DisposeObjects/disposeobj001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.DisposeObjects;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: VirtualMachine.DisposeObjects.
+ *
+ * See disposeobj001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class disposeobj001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.DisposeObjects";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "disposeobj001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.DisposeObjects";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.DisposeObjects;
+
+ // tested class name and signature constants
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // Number of references to free for tested objects
+ static final int REF_COUNT = 3;
+
+ // list of static fields with tested objects
+ static final String fieldsList[] = {
+ "objectValue",
+ "stringValue",
+ "classValue"
+ };
+ static final int fieldsCount = fieldsList.length;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new disposeobj001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ try {
+ log.display("\n>>> Obtaining requred data from debugee \n");
+
+ // query debuggee for classID of tested class
+ log.display("Getting classID by signature:\n"
+ + " " + TESTED_CLASS_SIGNATURE);
+ long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);
+ log.display(" got classID: " + classID);
+
+ // query debuggee for objectIDs values of static fields
+ long objectIDs[] = getObjectIDs(classID);
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand(objectIDs);
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Query debuggee for IDs of objects which are values of static fields.
+ */
+ long[] getObjectIDs(long classID) {
+ long[] objectIDs = new long[fieldsCount];
+
+ for (int i = 0; i < fieldsCount; i++ ) {
+ String name = fieldsList[i];
+
+ log.display("Getting fieldID of static field: " + name);
+ long fieldID = debugee.getClassFieldID(classID, name, true);
+ log.display(" got fieldID: " + fieldID);
+
+ // query for objectID value REF_COUNT times
+ log.display("Getting " + REF_COUNT + " times value of static fieldID: "
+ + fieldID);
+ for (int j = 0; j < REF_COUNT; j++) {
+ JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);
+ log.display(" #" + i + ": got value: " + value);
+
+ if (value.getTag() != JDWP.Tag.OBJECT
+ && value.getTag() != JDWP.Tag.STRING) {
+ throw new Failure("Not object value returned for static field \""
+ + name + "\": " + value);
+ }
+ long objectID = ((Long)value.getValue()).longValue();
+
+ // check that returned objectID is the same
+ if (j > 0) {
+ if (objectID != objectIDs[i]) {
+ throw new Failure("Last request for object value returned"
+ + " unexpected objectID: " + objectID
+ + "(expected: " + objectIDs[i] + ")");
+ }
+ } else {
+ objectIDs[i] = objectID;
+ }
+ }
+ }
+ return objectIDs;
+ }
+
+ /**
+ * Perform testing JDWP command for specified TypeID.
+ */
+ void testCommand(long objectIDs[]) {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+
+ log.display(" requested: " + fieldsCount);
+ command.addInt(fieldsCount);
+
+ for (int i = 0; i < fieldsCount; i++) {
+ log.display(" object: " + objectIDs[i]);
+ command.addObjectID(objectIDs[i]);
+ log.display(" refCnt: " + REF_COUNT);
+ command.addInt(REF_COUNT);
+ }
+
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/DisposeObjects/disposeobj001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/DisposeObjects/disposeobj001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: VirtualMachine
+ * command: DisposeObjects
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: disposeobj001
+ * debuggee: disposeobj001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Next, debugger obtains classID and also objectIDs as values of
+ * the static fields. Debugger queries each objectID value REF_COUNT
+ * times to increase references count for objects on back-end.
+ * Then, debugger creates command packet for VirtualMachine.DisposeObjects
+ * command with the found methodIDs as arguments, writes packet to
+ * the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and checks that the received reply packet contains no data.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.DisposeObjects.disposeobj001
+ * nsk.jdwp.VirtualMachine.DisposeObjects.disposeobj001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.DisposeObjects.disposeobj001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/DisposeObjects/disposeobj001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.DisposeObjects;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class disposeobj001a {
+
+ public static void main(String args[]) {
+ disposeobj001a _disposeobj001a = new disposeobj001a();
+ System.exit(disposeobj001.JCK_STATUS_BASE + _disposeobj001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // ensure tested class loaded
+ log.display("Creating object of tested class");
+ TestedClass foo = new TestedClass();
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + disposeobj001.READY);
+ pipe.println(disposeobj001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + disposeobj001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (! signal.equals(disposeobj001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + disposeobj001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return disposeobj001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return disposeobj001.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass {
+
+ // tested objects
+ static Object objectValue = new Object();
+ static String stringValue = new String();
+ static TestedClass classValue = new TestedClass();
+
+ int foo = 0;
+
+ TestedClass() {
+ foo = 100;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Exit/exit001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.Exit;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class exit001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.Exit";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "exit001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.Exit";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.Exit;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new exit001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ final ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ final Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ final Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+
+ // Linux returns only 8 least significant bits of exit status - see #4459019 bug.
+ int expectedExitCode = 0x0F;
+
+ // begin test of JDWP command
+
+ try {
+ log.display("Creating command packet for " + JDWP_COMMAND_NAME
+ + " with exit code: " + expectedExitCode);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addInt(expectedExitCode);
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ if (! reply.isParsed()) {
+ log.complain("Extra bytes in reply packet at: " + reply.currentPosition());
+ success = false;
+ }
+ } catch (Exception e) {
+ log.complain("Exception catched: " + e);
+ success = false;
+ }
+
+ // check if debugee has been actually terminated
+
+ if (success) {
+ int waittime = argumentHandler.getWaitTime() * 60; // seconds
+ int pause = 1; // seconds
+ int tries = waittime / pause;
+ success = false;
+
+ for (int i = 0; i < tries; i++) {
+ if (debugee.terminated()) {
+ log.display("Debugee has been terminated successfully");
+ success = true;
+ break;
+ }
+ try {
+ Thread.currentThread().sleep(pause * 1000);
+ } catch (InterruptedException e) {
+ log.complain("Interrupted exception catched: " + e);
+ }
+ }
+ if (! success) {
+ log.complain("Debugee has not been terminated by request");
+ }
+ }
+
+ // check if debugee exit code is as expected
+
+ if (success) {
+ int exitCode = debugee.getStatus();
+ log.display("Debugee exit code is: " + exitCode);
+ if (exitCode != expectedExitCode) {
+ log.complain("Debugee exit code is not equal to expected: " + expectedExitCode);
+ success = false;
+ }
+ }
+
+ // end test of JDWP command
+
+ } catch (Exception e) {
+ log.complain("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Exit/exit001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/Exit/exit001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: VirtualMachine
+ * command: Exit
+ * Test checks that debugee accept command and replies
+ * with correct reply packet. Also test checks that
+ * debugee is actually resumed by the command.
+ * First, test launches debuggee VM using support classes
+ * and connects to it.
+ * Then test sends Exit command with particular exit code
+ * and waits for a reply packet.
+ * Then test checks if the received reply packet has proper
+ * structure. Then test checks if debugee process is actually
+ * terminated with requested exit code. If debugee is not
+ * terminated for the specified in WAITTIME timeout test
+ * complains about an error.
+ * After JDWP command has been tested, test exits too
+ * with a proper exit code.
+ * COMMENTS:
+ * Modified due to fix of the bug:
+ * 4759453 TEST_BUG: tests against VirtualMachine.exit(int) should be corrected for Mantis
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.Exit.exit001
+ * nsk.jdwp.VirtualMachine.Exit.exit001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.Exit.exit001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Exit/exit001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.Exit;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class exit001a {
+
+ public static void main(String args[]) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = argumentHandler.createDebugeeLog();
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ /*
+ * In this test debugger kills debuggee using VirtualMachine.exit, so
+ * standard JDWP tests communication protocol isn't used here
+ */
+ try {
+ Thread.sleep(Long.MAX_VALUE);
+ } catch (Throwable t) {
+ // ignore all exceptions
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/HoldEvents/holdevents001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.HoldEvents;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: VirtualMachine.HoldEvents.
+ *
+ * See holdevents001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class holdevents001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.HoldEvents";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "holdevents001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.HoldEvents";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.HoldEvents;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new holdevents001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ try {
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand();
+
+ } finally {
+
+ log.display("\n>>> Finishing test \n");
+
+ // finally release events
+ log.display("Releasing events into debuggee");
+ releaseEvents();
+
+ // quit debugee
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Release events into debuggee.
+ */
+ void releaseEvents() {
+ CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.ReleaseEvents);
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+ }
+
+ /**
+ * Perform testing JDWP command.
+ */
+ void testCommand() {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // no data in reply packet
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/HoldEvents/holdevents001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/HoldEvents/holdevents001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: VirtualMachine
+ * command: HoldEvents
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: holdevents001
+ * debuggee: holdevents001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Then, debugger creates command packet for VirtualMachine.HoldEvents
+ * command with no out data, writes packet to the transport channel,
+ * and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and checks that the received reply packet contains no data.
+ * Finally, debugger releases debuggee's events, sends debuggee signal
+ * to quit, waits for it exits and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.HoldEvents.holdevents001
+ * nsk.jdwp.VirtualMachine.HoldEvents.holdevents001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.HoldEvents.holdevents001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/HoldEvents/holdevents001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.HoldEvents;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class holdevents001a {
+
+ public static void main(String args[]) {
+ holdevents001a _holdevents001a = new holdevents001a();
+ System.exit(holdevents001.JCK_STATUS_BASE + _holdevents001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + holdevents001.READY);
+ pipe.println(holdevents001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + holdevents001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (! signal.equals(holdevents001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + holdevents001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return holdevents001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return holdevents001.PASSED;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/HoldEvents/holdevents002.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,409 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.HoldEvents;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: VirtualMachine.HoldEvents.
+ *
+ * See holdevents002.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ *
+ * @see #runIt()
+ */
+public class holdevents002 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.HoldEvents";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "holdevents002";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.HoldEvents";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.HoldEvents;
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.BREAKPOINT;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+ static final byte TESTED_EVENT_MODIFIER = JDWP.EventModifierKind.LOCATION_ONLY;
+
+ // name and signature of the tested class
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of field and method of tested class
+ static final String TESTED_METHOD_NAME = "run";
+ static final int BREAKPOINT_LINE = holdevents002a.BREAKPOINT_LINE;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // obtained data
+ long testedClassID = 0;
+ long testedMethodID = 0;
+ int eventRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new holdevents002().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // get debuggee prepared for testing
+ log.display("\n>>> Get debuggee prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+
+ log.display("Holding events into debuggee");
+ holdEvents();
+ log.display(" ... events held");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for BREAKPOINT event NOT occured
+ log.display("Waiting for BREAKPOINT event NOT received");
+ waitForBreakpointEvent();
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debuggee for testing.
+ */
+ void prepareForTest() {
+ // wait for tested class loaded
+ log.display("Waiting for tested class loaded");
+ testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... got classID: " + testedClassID);
+ log.display("");
+
+ // get methodID for breakpoint method
+ log.display("Getting breakpoint methodID by name: " + TESTED_METHOD_NAME);
+ testedMethodID = debugee.getMethodID(testedClassID, TESTED_METHOD_NAME, true);
+ log.display(" ... got methodID: " + testedMethodID);
+
+ // make request for BREAKPOINT event
+ log.display("Making request for BREAKPOINT event at: "
+ + TESTED_METHOD_NAME + ":" + BREAKPOINT_LINE);
+ eventRequestID = debugee.requestBreakpointEvent(JDWP.TypeTag.CLASS, testedClassID,
+ testedMethodID, BREAKPOINT_LINE,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... got requestID: " + eventRequestID);
+ }
+
+ /**
+ * Hold events into debuggee.
+ */
+ void holdEvents() {
+ CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.HoldEvents);
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+ }
+
+ /**
+ * Wait for requested BREAKPOINT event NOT occured.
+ */
+ void waitForBreakpointEvent() {
+
+ EventPacket eventPacket = new EventPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for event packet");
+ transport.setReadTimeout(timeout);
+ transport.read(eventPacket);
+ log.display(" ... event packet received:\n" + eventPacket);
+ } catch (IOException e) {
+ log.display("No event packet received for default timeout:\n\t" + e);
+ log.display("Requested BREAKPOINT event is not received after holding events");
+ return;
+ }
+
+ log.complain("An event received after holding events into debuggee");
+ log.display("");
+
+ // check reply packet header
+ try{
+ log.display("Checking header of event packet");
+ eventPacket.checkHeader();
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Bad header of received event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from received event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from received event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in received event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in received event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ long eventThreadID = 0;
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from received event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check eventKind
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ log.display("Unexpected VM_DEATH event received intead of BREAKPOINT event");
+ success = false;
+ dead = true;
+ return;
+ } else if (eventKind == JDWP.EventKind.BREAKPOINT) {
+ log.complain("Hold BREAKPOINT event received in event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.BREAKPOINT + ")");
+ success = false;
+ } else {
+ log.complain("Unexpected eventKind of event " + i + " in event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.BREAKPOINT + ")");
+ success = false;
+ return;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from BREAKPOINT event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != eventRequestID) {
+ log.complain("Unexpected requestID of event " + i + " in BREAKPOINT event packet: " +
+ requestID + " (expected: " + eventRequestID + ")");
+ success = false;
+ }
+
+ // get threadID
+ long threadID = 0;
+ try {
+ threadID = eventPacket.getObjectID();
+ log.display(" threadID: " + threadID);
+ } catch (BoundException e) {
+ log.complain("Unable to get threadID of event #" + i + " from BREAKPOINT event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // get location
+ JDWP.Location location = null;
+ try {
+ location = eventPacket.getLocation();
+ log.display(" location: " + location);
+ } catch (BoundException e) {
+ log.complain("Unable to get location of event #" + i + " from BREAKPOINT event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event packet parsed");
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee if not dead
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/HoldEvents/holdevents002/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/HoldEvents/holdevents002.
+ * VM Testbase keywords: [jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: VirtualMachine
+ * command: HoldEvents
+ * event kind: BREAKPOINT
+ * Test checks that no requested BREAKPOINT events received from
+ * debuggee after holding events.
+ * Test consists of two compoments:
+ * debugger: holdevents002
+ * debuggee: holdevents002a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded and requests an
+ * BREAKPOINT event for some location into tested class.
+ * Then, debugger uses tesed command VirtualMachine.HoldEvents to
+ * hold events into debuggee and resumes debuggee to allow it to
+ * reach the breakpoint. Debugger waits for WAITTIME timeout for
+ * an event packet. If no event packet received, tests passes.
+ * If requested BREAKPOINT or any other event received? test failed.
+ * Finally, debugger disconnectes debuggee, waits for it exit
+ * and exits too with proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.HoldEvents.holdevents002
+ * nsk.jdwp.VirtualMachine.HoldEvents.holdevents002a
+ * @run main/othervm/timeout=420 PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.HoldEvents.holdevents002
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/HoldEvents/holdevents002a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.VirtualMachine.HoldEvents;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class holdevents002a {
+
+ static final int BREAKPOINT_LINE = 80;
+
+ static ArgumentHandler argumentHandler = null;
+ static Log log = null;
+
+ public static void main(String args[]) {
+ holdevents002a _holdevents002a = new holdevents002a();
+ System.exit(holdevents002.JCK_STATUS_BASE + _holdevents002a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // ensure tested class is loaded
+ log.display("Creating object of tested class");
+ TestedClass object = new TestedClass();
+ log.display(" ... object created");
+
+ // invoke method with breakpoint
+ log.display("Invoking method with breakpoint");
+ object.run();
+ log.display(" ... method invoked");
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return holdevents002.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass {
+ int foo = 0;
+
+ public TestedClass() {
+ foo = 1000;
+ }
+
+ public void run() {
+ log.display("Breakpoint line reached");
+ // next line is for breakpoint
+ foo = 0; // BREAKPOINT_LINE
+ log.display("Breakpoint line passed");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/IDSizes/idsizes001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.IDSizes;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class idsizes001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.IDSizes";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "idsizes001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.IDSizes";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.IDSizes;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new idsizes001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ // begin test of JDWP command
+
+ try {
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ int fieldIDSize = reply.getInt();
+ log.display(" fieldIDSize: " + fieldIDSize);
+
+ int methodIDSize = reply.getInt();
+ log.display(" methodIDSize: " + methodIDSize);
+
+ int objectIDSize = reply.getInt();
+ log.display(" objectIdSize: " + objectIDSize);
+
+ int referenceTypeIDSize = reply.getInt();
+ log.display(" referenceTypeIDSize: " + referenceTypeIDSize);
+
+ int frameIDSize = reply.getInt();
+ log.display(" frameIdSize: " + frameIDSize);
+
+ if (! reply.isParsed()) {
+ log.complain("Extra bytes in reply packet at: " + reply.currentPosition());
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Exception catched: " + e);
+ success = false;
+ }
+
+ // end test of JDWP command
+
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED: " + code);
+ } else {
+ log.complain("Debugee FAILED: " + code);
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/IDSizes/idsizes001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/IDSizes/idsizes001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test perform checking for
+ * command set: VirtualMachine
+ * command: IDSizes
+ * Test launches debuggee VM using support classes and sends
+ * IDSizes command to it. Then test receives reply for this
+ * command and checks that the returned values of VM dependent
+ * type sizes are equal to the JDWP predefinite values.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.IDSizes.idsizes001
+ * nsk.jdwp.VirtualMachine.IDSizes.idsizes001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.IDSizes.idsizes001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/IDSizes/idsizes001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.IDSizes;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class idsizes001a {
+
+ public static void main(String args[]) {
+ idsizes001a _idsizes001a = new idsizes001a();
+ System.exit(idsizes001.JCK_STATUS_BASE + _idsizes001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return idsizes001.PASSED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/InstanceCounts/instanceCounts001/instanceCounts001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2007, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/InstanceCounts/instanceCounts001.
+ * VM Testbase keywords: [quick, jpda, jdwp, feature_jdk6_jpda, vm6, monitoring]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: VirtualMachine
+ * command: InstanceCounts
+ * Test checks that debuggee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: instanceCounts001
+ * debuggee: instanceCounts001a
+ * Debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with execution commands.
+ * Debuggee during startup creates instances of 'nsk.jdwp.VirtualMachine.InstanceCounts.instanceCounts001.TestClass1'
+ * and 'nsk.jdwp.VirtualMachine.InstanceCounts.instanceCounts001.TestClass2' reachable via references with types
+ * which should be supported by command VirtualMachine.InstanceCounts:
+ * - strong reference
+ * - soft reference
+ * - weak reference
+ * - phantom reference
+ * - JNI global reference
+ * - JNI local reference
+ * First, debugger obtains referenceTypeID for 'nsk.jdwp.VirtualMachine.InstanceCounts.instanceCounts001.TestClass1'.
+ * Then, debugger creates command packet for InstanceCounts command with the found referenceTypeID
+ * as an argument, writes packet to the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure, extracts number of instances
+ * and checks that received value is correct.
+ * Then debugger repeat described above actions, but created command packet contains 2 referenceTypeIDs for
+ * 'nsk.jdwp.VirtualMachine.InstanceCounts.instanceCounts001.TestClass1' and 'nsk.jdwp.VirtualMachine.InstanceCounts.instanceCounts001.TestClass2'.
+ * Also, test performs check for case when incorrect data is sent in command:
+ * - create command with refTypesCount < 0, expect ILLEGAL_ARGUMENT error
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.InstanceCounts.instanceCounts001.instanceCounts001
+ * nsk.jdwp.VirtualMachine.InstanceCounts.instanceCounts001.instanceCounts001a
+ * @run main/othervm/native PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.InstanceCounts.instanceCounts001.instanceCounts001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="-Xmx128M ${test.vm.opts} ${test.java.opts}"
+ */
+
+package nsk.jdwp.VirtualMachine.InstanceCounts.instanceCounts001;
+
+import java.io.*;
+import nsk.share.Consts;
+import nsk.share.jdwp.*;
+import nsk.share.jpda.AbstractDebuggeeTest;
+
+public class instanceCounts001 extends TestDebuggerType1 {
+ protected String getDebugeeClassName() {
+ return "nsk.jdwp.VirtualMachine.InstanceCounts.instanceCounts001.instanceCounts001a";
+ }
+
+ public static void main(String argv[]) {
+ System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new instanceCounts001().runIt(argv, out);
+ }
+
+ private void testCommand(long typeIDs[], int refTypesCount, int[] expectedInstanceCounts, boolean expectError, int errorCode) {
+ try {
+ int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.InstanceCounts;
+
+ log.display("Create command: " + JDWP.commandNames.get(JDWP_COMMAND_ID));
+ log.display("refTypesCount = " + refTypesCount);
+ for (long typeID : typeIDs)
+ log.display("refType = " + typeID);
+
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.addInt(refTypesCount);
+
+ for (int i = 0; i < refTypesCount; i++)
+ command.addReferenceTypeID(typeIDs[i]);
+
+ command.setLength();
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ ReplyPacket reply;
+
+ reply = getReply(command, expectError, errorCode);
+
+ if (expectError)
+ return;
+
+ int counts = reply.getInt();
+ log.display("counts = " + counts);
+
+ // check received 'counts' value
+ if (counts != refTypesCount) {
+ setSuccess(false);
+ log.complain("Invalid 'counts' value, expected is: " + refTypesCount);
+ }
+
+ // check received 'instanceCount' value for all classes
+ for (int i = 0; i < counts; i++) {
+ long instanceCount = reply.getLong();
+ log.display("instanceCount = " + instanceCount);
+
+ if (instanceCount != expectedInstanceCounts[i]) {
+ setSuccess(false);
+ log.complain("Unexpected value 'instanceCount': " + instanceCount + ", expected is " + expectedInstanceCounts[i]);
+ }
+ }
+
+ if (!reply.isParsed()) {
+ setSuccess(false);
+ log.complain("Extra trailing bytes found in reply packet at: " + reply.currentPosition());
+ }
+ } catch (Exception e) {
+ setSuccess(false);
+ log.complain("Caught exception while testing JDWP command: " + e);
+ e.printStackTrace(log.getOutStream());
+ }
+ }
+
+ public void doTest() {
+ String testClass1 = nsk.jdwp.VirtualMachine.InstanceCounts.instanceCounts001.TestClass1.class.getName();
+ String testClass2 = nsk.jdwp.VirtualMachine.InstanceCounts.instanceCounts001.TestClass2.class.getName();
+
+ forceGC();
+ pipe.println(instanceCounts001a.COMMAND_CREATE_TEST_INSTANCES);
+
+ if (!isDebuggeeReady())
+ return;
+
+ int expectedCount = instanceCounts001a.expectedCount;
+
+ String classNames[];
+
+ classNames = new String[] { createTypeSignature(testClass1) };
+
+ long typeIDs[];
+
+ typeIDs = new long[classNames.length];
+
+ // create valid command for 1 class
+ for (int i = 0; i < classNames.length; i++)
+ typeIDs[i] = debuggee.getReferenceTypeID(classNames[i]);
+
+ testCommand(typeIDs, typeIDs.length, new int[] { expectedCount }, false, 0);
+
+ classNames = new String[] { createTypeSignature(testClass1), createTypeSignature(testClass2) };
+
+ typeIDs = new long[classNames.length];
+
+ // create valid command for 2 classes
+ for (int i = 0; i < classNames.length; i++)
+ typeIDs[i] = debuggee.getReferenceTypeID(classNames[i]);
+
+ testCommand(typeIDs, typeIDs.length, new int[] { expectedCount, expectedCount }, false, 0);
+
+ // create command with refTypesCount < 0, expect ILLEGAL_ARGUMENT error
+ testCommand(typeIDs, -1, new int[] { expectedCount }, true, JDWP.Error.ILLEGAL_ARGUMENT);
+ resetStatusIfGC();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/InstanceCounts/instanceCounts001/instanceCounts001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2007, 2018, 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.
+ */
+package nsk.jdwp.VirtualMachine.InstanceCounts.instanceCounts001;
+
+import java.util.ArrayList;
+import nsk.share.ReferringObjectSet;
+import nsk.share.jdi.HeapwalkingDebuggee;
+import nsk.share.jdwp.*;
+
+class TestClass1 {
+
+}
+
+class TestClass2 {
+
+}
+
+public class instanceCounts001a extends AbstractJDWPDebuggee {
+ public static final int expectedCount = HeapwalkingDebuggee.includedIntoInstancesCountTypes.size();
+
+ public static final String COMMAND_CREATE_TEST_INSTANCES = "COMMAND_CREATE_TEST_INSTANCES";
+
+ private ArrayList<ReferringObjectSet> referrers = new ArrayList<ReferringObjectSet>();
+
+ public boolean parseCommand(String command) {
+ if (super.parseCommand(command))
+ return true;
+
+ if (command.equals(COMMAND_CREATE_TEST_INSTANCES)) {
+ for (String referenceType : HeapwalkingDebuggee.includedIntoInstancesCountTypes) {
+ referrers.add(new ReferringObjectSet(new TestClass1(), 1, referenceType));
+ referrers.add(new ReferringObjectSet(new TestClass2(), 1, referenceType));
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public static void main(String args[]) {
+ new instanceCounts001a().doTest(args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/RedefineClasses/redefinecls001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,466 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.RedefineClasses;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: VirtualMachine.RedefineClasses.
+ *
+ * See redefinecls001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class redefinecls001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // VM capability constatnts
+ static final int VM_CAPABILITY_NUMBER = JDWP.Capability.CAN_REDEFINE_CLASSES;
+ static final String VM_CAPABILITY_NAME = "canRedefineClasses";
+
+ // package and classes names
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.RedefineClasses";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "redefinecls001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.RedefineClasses";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.RedefineClasses;
+
+ // tested class name and signature
+ static final String TESTED_CLASS_NAME = TEST_CLASS_NAME + "b";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // field and method names
+ static final String CONSTRUCTOR_FIELD_NAME = "constructorInvoked";
+ static final String STATIC_METHOD_FIELD_NAME = "staticMethodInvoked";
+ static final String OBJECT_METHOD_FIELD_NAME = "objectMethodInvoked";
+ static final String BREAKPOINT_METHOD_NAME = "runIt";
+ static final int BREAKPOINT_LINE_BEFORE = redefinecls001a.BREAKPOINT_LINE_BEFORE;
+ static final int BREAKPOINT_LINE_AFTER = redefinecls001a.BREAKPOINT_LINE_AFTER;
+
+ // filename for redefined class
+// 4691123 TEST: some jdi tests contain precompiled .klass files undes SCCS
+// precomiled class was removed
+// static final String REDEFINED_CLASS_FILE_NAME = "redefinecls001b.klass";
+ static final String REDEFINED_CLASS_FILE_NAME = "newclass"
+ + File.separator + PACKAGE_NAME.replace('.',File.separatorChar)
+ + File.separator + "redefinecls001b.class";
+// static final String REDEFINED_CLASS_DIR = ".";
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ String testDir = null;
+ boolean dead = false;
+ boolean success = true;
+
+ // data obtained from debuggee
+ long debugeeClassID = 0;
+ long testedClassID = 0;
+ long breakpointMethodID = 0;
+ ByteBuffer redefinedClassBytes = null;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new redefinecls001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime(); // minutes
+ timeout = waitTime * 60 * 1000; // milliseconds
+
+ // get testDir as first positional parameter
+ String args[] = argumentHandler.getArguments();
+ if (args.length < 1) {
+ log.complain("Test dir required as the first positional argument");
+ return FAILED;
+ }
+ testDir = args[0];
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Loading redefined class \n");
+
+ // load class file for redefined class
+ log.display("Loading bytecode of redefined class from file: " +
+ REDEFINED_CLASS_FILE_NAME);
+ redefinedClassBytes = loadClassBytes(REDEFINED_CLASS_FILE_NAME, testDir);
+ log.display(" ... loaded bytes: " + redefinedClassBytes.length());
+
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee VM");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debuggee launched");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for VM_INIT event
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // check for VM capability
+ log.display("\n>>> Checking VM capability \n");
+ log.display("Getting new VM capability: " + VM_CAPABILITY_NAME);
+ boolean capable = debugee.getNewCapability(VM_CAPABILITY_NUMBER, VM_CAPABILITY_NAME);
+ log.display(" ... got VM capability: " + capable);
+
+ // exit as PASSED if this capability is not supported
+ if (!capable) {
+ out.println("TEST PASSED: unsupported VM capability: "
+ + VM_CAPABILITY_NAME);
+ return PASSED;
+ }
+
+ // prepare debuggee for testing and obtain required data
+ log.display("\n>>> Getting prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP command
+ log.display("\n>> Testing JDWP command \n");
+ testCommand();
+
+ // check command results
+ if (success) {
+ log.display("\n>>> Checking result of tested command \n");
+ checkResult();
+ }
+
+ // finish debuggee
+ log.display("\n>> Finishing debuggee \n");
+
+ // resume debuggee after testing command
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // wait for VM_DEATH event
+ log.display("Waiting for VM_DEATH event");
+ debugee.waitForVMDeath();
+ log.display(" ... VM_DEATH event received");
+ dead = true;
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ log.display("\n>>> Finishing test \n");
+
+ // disconnect debugee and wait for its exit
+ if (debugee != null) {
+ quitDebugee();
+ }
+ }
+
+ // check result
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+ out.println("TEST PASSED");
+ return PASSED;
+ }
+
+ /**
+ * Get debuggee prepared for testing and obtain required data.
+ */
+ void prepareForTest() {
+ // wait for debuggee and tested classes loaded on debuggee startup
+ log.display("Waiting for classes loaded:"
+ + "\n\t" + DEBUGEE_CLASS_NAME
+ + "\n\t" + TESTED_CLASS_NAME);
+ String classNames[] = {DEBUGEE_CLASS_NAME, TESTED_CLASS_NAME};
+ long classIDs[] = debugee.waitForClassesLoaded(classNames,
+ JDWP.SuspendPolicy.ALL);
+ debugeeClassID = classIDs[0];
+ log.display(" ... debuggee class loaded with classID: " + debugeeClassID);
+ testedClassID = classIDs[1];
+ log.display(" ... tested class loaded with classID: " + testedClassID);
+ log.display("");
+
+ // set breakpoint before redefinition and wait for debugee reached it
+ log.display("Waiting for breakpoint before redefiniton reached at: "
+ + BREAKPOINT_METHOD_NAME + ":" + BREAKPOINT_LINE_BEFORE);
+ long threadID = debugee.waitForBreakpointReached(debugeeClassID,
+ BREAKPOINT_METHOD_NAME,
+ BREAKPOINT_LINE_BEFORE,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... breakpoint before redefinition reached with threadID: " + threadID);
+ log.display("");
+ }
+
+ /**
+ * Perform testing JDWP command.
+ */
+ void testCommand() {
+ int length = redefinedClassBytes.length();
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" classes: " + 1);
+ command.addInt(1);
+ log.display(" refTypeID: " + testedClassID);
+ command.addReferenceTypeID(testedClassID);
+ log.display(" classfile: " + length + " bytes");
+ command.addInt(length);
+ log.display(" classbytes:\n" + redefinedClassBytes);
+ command.addBytes(redefinedClassBytes.getBytes(), 0, length);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // receive reply packet from debugee
+ ReplyPacket reply = new ReplyPacket();
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display(" ... reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet for tested command:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking header of reply packet");
+ reply.checkHeader(command.getPacketID());
+ log.display(" ... packet header is correct");
+ } catch (BoundException e) {
+ log.complain("Wrong header of reply packet for tested command:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet data:");
+ reply.resetPosition();
+
+ // no reply data to parse
+ log.display(" no reply data");
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+
+ log.display(" ... packed data parsed");
+ }
+
+ /**
+ * Check result of the tested JDWP command.
+ */
+ void checkResult() {
+ // set breakpoint after redefinition and wait for debugee reached it
+ log.display("Waiting for breakpoint after redefiniton reached at: "
+ + BREAKPOINT_METHOD_NAME + ":" + BREAKPOINT_LINE_AFTER);
+ long threadID = debugee.waitForBreakpointReached(debugeeClassID,
+ BREAKPOINT_METHOD_NAME,
+ BREAKPOINT_LINE_AFTER,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... breakpoint after redefinition reached with threadID: " + threadID);
+ log.display("");
+
+ // check invoked methods
+ log.display("Getting value of static field: " + CONSTRUCTOR_FIELD_NAME);
+ JDWP.Value value = debugee.getStaticFieldValue(testedClassID,
+ CONSTRUCTOR_FIELD_NAME, JDWP.Tag.INT);
+ int constructorInvoked = ((Integer)value.getValue()).intValue();
+ log.display(" ... got constructorInvoked: " + methodKind(constructorInvoked));
+
+ if (constructorInvoked != redefinecls001b.NOT_REDEFINED_METHOD_INVOKED) {
+ log.complain("Constructor has been invoked after class redefinition");
+ success = false;
+ }
+
+ log.display("Getting value of static field: " + STATIC_METHOD_FIELD_NAME);
+ value = debugee.getStaticFieldValue(testedClassID,
+ STATIC_METHOD_FIELD_NAME, JDWP.Tag.INT);
+ int staticMethodInvoked = ((Integer)value.getValue()).intValue();
+ log.display(" ... got staticMethodInvoked: " + methodKind(staticMethodInvoked));
+
+ if (staticMethodInvoked != redefinecls001b.REDEFINED_METHOD_INVOKED) {
+ log.complain("Not redefined static method is invoked after class redefinition");
+ success = false;
+ }
+
+ log.display("Getting value of static field: " + OBJECT_METHOD_FIELD_NAME);
+ value = debugee.getStaticFieldValue(testedClassID,
+ OBJECT_METHOD_FIELD_NAME, JDWP.Tag.INT);
+ int objectMethodInvoked = ((Integer)value.getValue()).intValue();
+ log.display(" ... got objectMethodInvoked: " + methodKind(objectMethodInvoked));
+
+ if (objectMethodInvoked != redefinecls001b.REDEFINED_METHOD_INVOKED) {
+ log.complain("Not redefined object method is invoked after class redefinition");
+ success = false;
+ }
+ }
+
+ /**
+ * Load class bytes form the given file.
+ */
+ ByteBuffer loadClassBytes(String fileName, String dirName) {
+ String fileSep = System.getProperty("file.separator");
+ String filePath = dirName + fileSep + fileName;
+
+ String error = "Unable to read bytes from class file:\n\t" + filePath;
+
+ int length = 0;
+ byte bytes[] = null;
+ try {
+ File file = new File(filePath);
+ length = (int)file.length();
+ FileInputStream is = new FileInputStream(file);
+ bytes = new byte[length];
+ int number = is.read(bytes);
+ if (number < 0) {
+ log.complain("EOF reached while reading bytes from file");
+ throw new Failure(error);
+ } else if (number != length) {
+ log.complain("Unexpected number of bytes red from file: " + number
+ + " (expected: " + length + ")");
+ throw new Failure(error);
+ }
+ is.close();
+ } catch ( IOException e ) {
+ log.complain("Caught IOException while reading bytes from file:\n\t" + e);
+ throw new Failure(error);
+ }
+ ByteBuffer byteBuffer = new ByteBuffer(length, 0);
+ byteBuffer.addBytes(bytes, 0, length);
+ return byteBuffer;
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ // return string representation of kind of invoked method
+ private static String methodKind(int kind) {
+ switch (kind) {
+ case redefinecls001b.METHOD_NOT_INVOKED:
+ return "METHOD_NOT_INVOKED";
+ case redefinecls001b.REDEFINED_METHOD_INVOKED:
+ return "REDEFINED_METHOD_INVOKED";
+ case redefinecls001b.NOT_REDEFINED_METHOD_INVOKED:
+ return "NOT_REDEFINED_METHOD_INVOKED";
+ default:
+ return "UNKNOWN_METHOD_KIND";
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/RedefineClasses/redefinecls001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/RedefineClasses/redefinecls001.
+ * VM Testbase keywords: [quick, jpda, jdwp, redefine]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: VirtualMachine
+ * command: RedefineClasses
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet. Also test checks that
+ * after class redefinition invocation of static and object
+ * methods resuts in invocation of redefined methods, and
+ * no constructors are invoked.
+ * Test consists of two compoments:
+ * debugger: redefinecls001
+ * debuggee: redefinecls001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * It also loads bytecode of redefined class from *.klass file.
+ * Next, debugger waits for tested classes are loaded, and breakpoint
+ * before class redefinition is reached.
+ * Then, debugger creates command packet for VirtualMachine.RedefineClasses
+ * command for the found classID and loaded bytecode, writes this packet
+ * to the transport channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and checks if no reply data returned in the packet.
+ * Then, debugger resumes debuggee to allow methods of redefined class
+ * to be invoked and waits for second breakpoint is reached.
+ * Upon their invocation redefined methods puts proper value into
+ * the special static fields of debuggee class. The debugger then
+ * checks these fields to verify if the redefined methods were invoked
+ * and no constructors were invoked.
+ * Finally, debugger disconnects debuggee, waits for it exits
+ * and exits too with the proper exit code.
+ * COMMENTS
+ * First positional argument for the test should be path to the test
+ * work directory where loaded *.klass file should be located.
+ * Test was updated according to rfe:
+ * 4691123 TEST: some jdi tests contain precompiled .klass files undes SCCS.
+ * redefinecl001b.ja was moved into newclass directory and renamed
+ * to redefinecl001b.java.
+ * The precompiled class file is created during test base build process.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build ExecDriver
+ * @build nsk.jdwp.VirtualMachine.RedefineClasses.redefinecls001
+ * nsk.jdwp.VirtualMachine.RedefineClasses.redefinecls001a
+ * nsk.jdwp.VirtualMachine.RedefineClasses.redefinecls001b
+ * @run driver PropertyResolvingWrapper ExecDriver --cmd
+ * ${compile.jdk}/bin/javac
+ * -cp ${test.class.path}
+ * -d newclass
+ * newclass/redefinecls001b.java
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.RedefineClasses.redefinecls001
+ * .
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/RedefineClasses/redefinecls001/newclass/redefinecls001b.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2002, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.RedefineClasses;
+
+import nsk.share.*;
+
+/**
+ * This class is for class redefinition.
+ */
+public class redefinecls001b {
+
+ // values for tested fields
+ public static final int INITIAL_FIELD_VALUE = 111;
+ public static final int FINAL_FIELD_VALUE = 222;
+
+ // values for method redefinition
+ public static final int METHOD_NOT_INVOKED = 0;
+ public static final int REDEFINED_METHOD_INVOKED = 10;
+ public static final int NOT_REDEFINED_METHOD_INVOKED = 20;
+
+ // static field
+ public static int staticField = INITIAL_FIELD_VALUE;
+ // object field
+ public int objectField = INITIAL_FIELD_VALUE;
+
+ public static Log log;
+ // fields for methods redefinition results
+ public static int constructorInvoked = METHOD_NOT_INVOKED;
+ public static int staticMethodInvoked = METHOD_NOT_INVOKED;
+ public static int objectMethodInvoked = METHOD_NOT_INVOKED;
+
+ // constructor
+ public redefinecls001b(int value) {
+ log.display("Constructor invoked: REDEFINED");
+ constructorInvoked = REDEFINED_METHOD_INVOKED;
+ objectField = value;
+ }
+
+ // static method to be redefined
+ public static void testedStaticMethod() {
+ log.display("Static method invoked: REDEFINED");
+ staticMethodInvoked = REDEFINED_METHOD_INVOKED;
+
+ log.display("Static fields values:");
+ log.display(" staticField: " + staticField
+ + " (expected: " + FINAL_FIELD_VALUE + ")");
+ }
+
+ // object method to be redefined
+ public void testedObjectMethod() {
+ log.display("Object method invoked: REDEFINED");
+ objectMethodInvoked = REDEFINED_METHOD_INVOKED;
+
+ log.display("Object fields values:");
+ log.display(" objectField: " + objectField
+ + " (expected: " + FINAL_FIELD_VALUE + ")");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/RedefineClasses/redefinecls001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.VirtualMachine.RedefineClasses;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class redefinecls001a {
+
+ // line nunber for breakpoint
+ public static final int BREAKPOINT_LINE_BEFORE = 76;
+ public static final int BREAKPOINT_LINE_AFTER = 86;
+
+ // fields for methods redefinition results
+// public static Integer constructorInvoked = Integer(redefinecls001.METHOD_NOT_INVOKED);
+// public static Integer staticMethodInvoked = Integer(redefinecls001.METHOD_NOT_INVOKED);
+// public static Integer objectMethodInvoked = Integer(redefinecls001.METHOD_NOT_INVOKED);
+
+ // scaffold objects
+ static volatile ArgumentHandler argumentHandler = null;
+ static volatile Log log = null;
+
+ public static void main(String args[]) {
+ System.exit(redefinecls001.JCK_STATUS_BASE + redefinecls001a.runIt(args, System.err));
+ }
+
+ public static int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // create tested thread
+ log.display("Creating object of tested class");
+ redefinecls001b.staticField = redefinecls001b.FINAL_FIELD_VALUE;
+ redefinecls001b.log = log;
+ redefinecls001b object = new redefinecls001b(redefinecls001b.FINAL_FIELD_VALUE);
+ log.display(" ... object created");
+
+ // invoke tested method before redefinition
+ log.display("Invoking tested methods before redefinition");
+ redefinecls001b.testedStaticMethod();
+ object.testedObjectMethod();
+ printInvocationResult();
+
+ log.display("\nBreakpoint line before redefinition reached");
+ // next line is for breakpoint before redefinition
+ int foo = 0; // BREAKPOINT_LINE_BEFORE
+
+ // invoke tested method after redefinition
+ log.display("Invoking tested methods after redefinition");
+ redefinecls001b.testedStaticMethod();
+ object.testedObjectMethod();
+ printInvocationResult();
+
+ log.display("\nBreakpoint line after redefinition reached");
+ // next line is for breakpoint after redefinition
+ foo = 1; // BREAKPOINT_LINE_AFTER
+
+ log.display("Debugee PASSED");
+ return redefinecls001.PASSED;
+ }
+
+ // print information about kind of invoked methods
+ private static void printInvocationResult() {
+ log.display("Result of methods invokation:");
+ log.display(" constructorInvoked: " + methodKind(redefinecls001b.constructorInvoked));
+ log.display(" staticMethodInvoked: " + methodKind(redefinecls001b.staticMethodInvoked));
+ log.display(" objectMethodInvoked: " + methodKind(redefinecls001b.objectMethodInvoked));
+ }
+
+ // return string representation of kind of invoked method
+ private static String methodKind(int kind) {
+ switch (kind) {
+ case redefinecls001b.METHOD_NOT_INVOKED:
+ return "METHOD_NOT_INVOKED";
+ case redefinecls001b.REDEFINED_METHOD_INVOKED:
+ return "REDEFINED_METHOD_INVOKED";
+ case redefinecls001b.NOT_REDEFINED_METHOD_INVOKED:
+ return "NOT_REDEFINED_METHOD_INVOKED";
+ default:
+ return "UNKNOWN_METHOD_KIND";
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/RedefineClasses/redefinecls001b.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.RedefineClasses;
+
+import nsk.share.*;
+
+/**
+ * This class is to be redefined.
+ */
+public class redefinecls001b {
+
+ // values for tested fields
+ public static final int INITIAL_FIELD_VALUE = 111;
+ public static final int FINAL_FIELD_VALUE = 222;
+
+ // values for method redefinition
+ public static final int METHOD_NOT_INVOKED = 0;
+ public static final int REDEFINED_METHOD_INVOKED = 10;
+ public static final int NOT_REDEFINED_METHOD_INVOKED = 20;
+
+ // static field
+ public static int staticField = INITIAL_FIELD_VALUE;
+ // object field
+ public int objectField = INITIAL_FIELD_VALUE;
+
+ public static Log log;
+ // fields for methods redefinition results
+ public static int constructorInvoked = METHOD_NOT_INVOKED;
+ public static int staticMethodInvoked = METHOD_NOT_INVOKED;
+ public static int objectMethodInvoked = METHOD_NOT_INVOKED;
+
+ // constructor
+ public redefinecls001b(int value) {
+ log.display("Constructor invoked: NOT REDEFINED");
+ constructorInvoked = NOT_REDEFINED_METHOD_INVOKED;
+ objectField = value;
+ }
+
+ // static method to be redefined
+ public static void testedStaticMethod() {
+ log.display("Static method invoked: NOT REDEFINED");
+ staticMethodInvoked = NOT_REDEFINED_METHOD_INVOKED;
+
+ log.display("Static fields values:");
+ log.display(" staticField: " + staticField
+ + " (expected: " + FINAL_FIELD_VALUE + ")");
+ }
+
+ // object method to be redefined
+ public void testedObjectMethod() {
+ log.display("Object method invoked: NOT REDEFINED");
+ objectMethodInvoked = NOT_REDEFINED_METHOD_INVOKED;
+
+ log.display("Object fields values:");
+ log.display(" objectField: " + objectField
+ + " (expected: " + FINAL_FIELD_VALUE + ")"); // BREAKPOINT_LINE_BEFORE
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.ReleaseEvents;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: VirtualMachine.ReleaseEvents.
+ *
+ * See releaseevents001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class releaseevents001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.ReleaseEvents";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "releaseevents001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.ReleaseEvents";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.ReleaseEvents;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new releaseevents001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ try {
+
+ // finally release events
+ log.display("Holding events into debuggee");
+ holdEvents();
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand();
+
+ } finally {
+
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Hold events into debuggee.
+ */
+ void holdEvents() {
+ CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.HoldEvents);
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+ }
+
+ /**
+ * Perform testing JDWP command.
+ */
+ void testCommand() {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // no data in reply packet
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: VirtualMachine
+ * command: ReleaseEvents
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: releaseevents001
+ * debuggee: releaseevents001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Before testing JDWP command debugger holds debuggee's events.
+ * Then, debugger creates command packet for VirtualMachine.ReleaseEvents
+ * command with no out data, writes packet to the transport channel,
+ * and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and checks that the received reply packet contains no data.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ * COMMENTS
+ * Test fixed according to test bug:
+ * 4954298 TEST_BUG: typo in nsk/jdwp/VirtualMachine/ReleaseEvents/<*> tests
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.ReleaseEvents.releaseevents001
+ * nsk.jdwp.VirtualMachine.ReleaseEvents.releaseevents001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.ReleaseEvents.releaseevents001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.ReleaseEvents;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class releaseevents001a {
+
+ public static void main(String args[]) {
+ releaseevents001a _releaseevents001a = new releaseevents001a();
+ System.exit(releaseevents001.JCK_STATUS_BASE + _releaseevents001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + releaseevents001.READY);
+ pipe.println(releaseevents001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + releaseevents001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (! signal.equals(releaseevents001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + releaseevents001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return releaseevents001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return releaseevents001.PASSED;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents002.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,405 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.ReleaseEvents;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: VirtualMachine.ReleaseEvents.
+ *
+ * See releaseevents002.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ *
+ * @see #runIt()
+ */
+public class releaseevents002 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.ReleaseEvents";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "releaseevents002";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.ReleaseEvents";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.ReleaseEvents;
+ static final byte TESTED_EVENT_KIND = JDWP.EventKind.BREAKPOINT;
+ static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
+ static final byte TESTED_EVENT_MODIFIER = JDWP.EventModifierKind.LOCATION_ONLY;
+
+ // name and signature of the tested class
+ static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";
+ static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
+
+ // name of field and method of tested class
+ static final String TESTED_METHOD_NAME = "run";
+ static final int BREAKPOINT_LINE = releaseevents002a.BREAKPOINT_LINE;
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ int waitTime = 0; // minutes
+ long timeout = 0; // milliseconds
+ boolean dead = false;
+ boolean success = true;
+
+ // obtained data
+ long testedClassID = 0;
+ long testedMethodID = 0;
+ int eventRequestID = 0;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main(String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start test from JCK-compilant environment.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new releaseevents002().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+ waitTime = argumentHandler.getWaitTime();
+ timeout = waitTime * 60 * 1000;
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Starting debugee \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ log.display(" ... debugee launched");
+ log.display("");
+
+ // set timeout for debuggee responces
+ log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
+ transport.setReadTimeout(timeout);
+ log.display(" ... timeout set");
+
+ // wait for debuggee started
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+ log.display(" ... VM_INIT event received");
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+ log.display(" ... size of VM-dependent types adjusted");
+
+ // get debuggee prepared for testing
+ log.display("\n>>> Get debuggee prepared for testing \n");
+ prepareForTest();
+
+ // test JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+
+ // hold events
+ log.display("Holding events into debuggee");
+ holdEvents();
+ log.display(" ... events held");
+
+ // resume debuggee
+ log.display("Resuming debuggee");
+ debugee.resume();
+ log.display(" ... debuggee resumed");
+
+ // release events
+ log.display("Release events into debuggee");
+ releaseEvents();
+ log.display(" ... events released");
+
+ // wait for BREAKPOINT event
+ log.display("Waiting for BREAKPOINT event");
+ waitForBreakpointEvent();
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ // check test results
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debuggee for testing.
+ */
+ void prepareForTest() {
+ // wait for tested class loaded
+ log.display("Waiting for tested class loaded");
+ testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
+ log.display(" ... got classID: " + testedClassID);
+ log.display("");
+
+ // get methodID for breakpoint method
+ log.display("Getting breakpoint methodID by name: " + TESTED_METHOD_NAME);
+ testedMethodID = debugee.getMethodID(testedClassID, TESTED_METHOD_NAME, true);
+ log.display(" ... got methodID: " + testedMethodID);
+
+ // make request for BREAKPOINT event
+ log.display("Making request for BREAKPOINT event at: "
+ + TESTED_METHOD_NAME + ":" + BREAKPOINT_LINE);
+ eventRequestID = debugee.requestBreakpointEvent(JDWP.TypeTag.CLASS, testedClassID,
+ testedMethodID, BREAKPOINT_LINE,
+ JDWP.SuspendPolicy.ALL);
+ log.display(" ... got requestID: " + eventRequestID);
+ }
+
+ /**
+ * Hold events into debuggee.
+ */
+ void holdEvents() {
+ CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.HoldEvents);
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+ }
+
+ /**
+ * Release events into debuggee.
+ */
+ void releaseEvents() {
+ CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.ReleaseEvents);
+ ReplyPacket reply = debugee.receiveReplyFor(command);
+ }
+
+ /**
+ * Wait for requested BREAKPOINT event NOT occured.
+ */
+ void waitForBreakpointEvent() {
+
+ // receive event
+ EventPacket eventPacket = null;
+ try {
+ eventPacket = debugee.receiveEvent();
+ log.display("Event received after releasing events into debuggee");
+ } catch (Failure e) {
+ log.complain("No requested event received after releasing events into debuggee:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing event packet:");
+ eventPacket.resetPosition();
+
+ // get suspendPolicy value
+ byte suspendPolicy = 0;
+ try {
+ suspendPolicy = eventPacket.getByte();
+ log.display(" suspendPolicy: " + suspendPolicy);
+ } catch (BoundException e) {
+ log.complain("Unable to get suspendPolicy value from received event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // get events count
+ int events = 0;
+ try {
+ events = eventPacket.getInt();
+ log.display(" events: " + events);
+ } catch (BoundException e) {
+ log.complain("Unable to get events count from received event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check events count
+ if (events < 0) {
+ log.complain("Negative value of events number in received event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ } else if (events != 1) {
+ log.complain("Invalid number of events in received event packet: " +
+ events + " (expected: " + 1 + ")");
+ success = false;
+ }
+
+ // extract each event
+ long eventThreadID = 0;
+ for (int i = 0; i < events; i++) {
+ log.display(" event #" + i + ":");
+
+ // get eventKind
+ byte eventKind = 0;
+ try {
+ eventKind = eventPacket.getByte();
+ log.display(" eventKind: " + eventKind);
+ } catch (BoundException e) {
+ log.complain("Unable to get eventKind of event #" + i + " from received event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check eventKind
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ log.display("Unexpected VM_DEATH event received intead of BREAKPOINT event");
+ success = false;
+ dead = true;
+ return;
+ } else if (eventKind == JDWP.EventKind.BREAKPOINT) {
+ log.display("Expected BREAKPOINT event received in event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.BREAKPOINT + ")");
+ } else {
+ log.complain("Unexpected eventKind of event " + i + " in event packet: " +
+ eventKind + " (expected: " + JDWP.EventKind.BREAKPOINT + ")");
+ success = false;
+ return;
+ }
+
+ // get requestID
+ int requestID = 0;
+ try {
+ requestID = eventPacket.getInt();
+ log.display(" requestID: " + requestID);
+ } catch (BoundException e) {
+ log.complain("Unable to get requestID of event #" + i + " from BREAKPOINT event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // check requestID
+ if (requestID != eventRequestID) {
+ log.complain("Unexpected requestID of event " + i + " in BREAKPOINT event packet: " +
+ requestID + " (expected: " + eventRequestID + ")");
+ success = false;
+ }
+
+ // get threadID
+ long threadID = 0;
+ try {
+ threadID = eventPacket.getObjectID();
+ log.display(" threadID: " + threadID);
+ } catch (BoundException e) {
+ log.complain("Unable to get threadID of event #" + i + " from BREAKPOINT event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // get location
+ JDWP.Location location = null;
+ try {
+ location = eventPacket.getLocation();
+ log.display(" location: " + location);
+ } catch (BoundException e) {
+ log.complain("Unable to get location of event #" + i + " from BREAKPOINT event packet:\n\t"
+ + e.getMessage());
+ success = false;
+ return;
+ }
+ }
+
+ // check for extra data in event packet
+ if (!eventPacket.isParsed()) {
+ log.complain("Extra trailing bytes found in event packet at: "
+ + eventPacket.offsetString());
+ success = false;
+ }
+
+ log.display(" ... event packet parsed");
+ }
+
+ /**
+ * Disconnect debuggee and wait for it exited.
+ */
+ void quitDebugee() {
+ if (debugee == null)
+ return;
+
+ // disconnect debugee if not dead
+ if (!dead) {
+ try {
+ log.display("Disconnecting debuggee");
+ debugee.dispose();
+ log.display(" ... debuggee disconnected");
+ } catch (Failure e) {
+ log.display("Failed to finally disconnect debuggee:\n\t"
+ + e.getMessage());
+ }
+ }
+
+ // wait for debugee exited
+ log.display("Waiting for debuggee exit");
+ int code = debugee.waitFor();
+ log.display(" ... debuggee exited with exit code: " + code);
+
+ // analize debugee exit status code
+ if (code != JCK_STATUS_BASE + PASSED) {
+ log.complain("Debuggee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents002/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents002.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: VirtualMachine
+ * command: ReleaseEvents
+ * event kind: BREAKPOINT
+ * Test checks that requested BREAKPOINT event received from
+ * debuggee after holding and then releasing events.
+ * Test consists of two compoments:
+ * debugger: releaseevents002
+ * debuggee: releaseevents002a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Next, debugger waits for tested class loaded and requests an
+ * BREAKPOINT event for some location into tested class.
+ * Then, debugger holds events into debuggee, resumes debuggee to
+ * allow it to reach breakpoint, and then releases events using
+ * tested command VirtualMachine.ReleaseEvents. Debugger waits for
+ * an event packet is received and checks if this packet is for
+ * requested BREAKPOINT event.
+ * Finally, debugger disconnectes debuggee, waits for it exit
+ * and exits too with proper exit code.
+ * COMMENTS
+ * Test fixed according to test bug:
+ * 4954298 TEST_BUG: typo in nsk/jdwp/VirtualMachine/ReleaseEvents/<*> tests
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.ReleaseEvents.releaseevents002
+ * nsk.jdwp.VirtualMachine.ReleaseEvents.releaseevents002a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.ReleaseEvents.releaseevents002
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/ReleaseEvents/releaseevents002a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+// THIS TEST IS LINE NUMBER SENSITIVE
+
+package nsk.jdwp.VirtualMachine.ReleaseEvents;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class releaseevents002a {
+
+ static final int BREAKPOINT_LINE = 80;
+
+ static ArgumentHandler argumentHandler = null;
+ static Log log = null;
+
+ public static void main(String args[]) {
+ releaseevents002a _releaseevents002a = new releaseevents002a();
+ System.exit(releaseevents002.JCK_STATUS_BASE + _releaseevents002a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ argumentHandler = new ArgumentHandler(args);
+ log = new Log(out, argumentHandler);
+
+ // ensure tested class is loaded
+ log.display("Creating object of tested class");
+ TestedClass object = new TestedClass();
+ log.display(" ... object created");
+
+ // invoke method with breakpoint
+ log.display("Invoking method with breakpoint");
+ object.run();
+ log.display(" ... method invoked");
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return releaseevents002.PASSED;
+ }
+
+ // tested class
+ public static class TestedClass {
+ int foo = 0;
+
+ public TestedClass() {
+ foo = 1000;
+ }
+
+ public void run() {
+ log.display("Breakpoint line reached");
+ // next line is for breakpoint
+ foo = 0; // BREAKPOINT_LINE
+ log.display("Breakpoint line passed");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Resume/resume001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.Resume;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class resume001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.Resume";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "resume001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.Resume";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.Resume;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new resume001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ final Log log = new Log(out, argumentHandler);
+ long timeout = argumentHandler.getWaitTime() * 60 * 1000; // milliseconds
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ final IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // begin test of JDWP command
+
+ try {
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ if (! reply.isParsed()) {
+ log.complain("Extra bytes in reply packet at: " + reply.currentPosition());
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Caught exception: " + e);
+ success = false;
+ }
+
+ // check if debugee has been actually resumed
+
+ if (success) {
+ log.display("Waiting for debugee continues execution or timeout exceeds");
+
+ // separate thread for waiting for reply from debuggee
+ class TimeoutHandler extends Thread {
+ boolean success = false;
+ public void run() {
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+ if (cmd.equals("ready")) {
+ success = true;
+ log.display("Debugee was resumed successfully");
+ } else {
+ log.complain("Unexpected command received: " + cmd);
+ }
+ }
+ }
+
+ // start separate thread
+ TimeoutHandler timeoutHandler = new TimeoutHandler();
+ timeoutHandler.start();
+
+ // wait for thread finished or timeout exceeds
+ try {
+ timeoutHandler.join(timeout);
+ if (timeoutHandler.isAlive()) {
+ log.display("Interrupting thread because timeout exceeds");
+ timeoutHandler.interrupt();
+ }
+ } catch (InterruptedException e) {
+ throw new Failure("Main thread interrupted: " + e);
+ }
+
+ // check resuts
+ if (!timeoutHandler.success) {
+ log.complain("Debugee has not been resumed by command");
+ success = false;
+ }
+ }
+
+ // end test of JDWP command
+
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED: " + code);
+ } else {
+ log.complain("Debugee FAILED: " + code);
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Resume/resume001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/Resume/resume001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: VirtualMachine
+ * command: Resume
+ * Test checks that debugee accept command and replies
+ * with correct reply packet. Also test checks that
+ * debugee is actually resumed by the command.
+ * First, test launches debuggee VM using support classes
+ * and connects to it. Debugee is launched in the suspend
+ * mode by default.
+ * Then test sends Resume command and waits for a
+ * reply packet.
+ * When reply is received test checks if the reply packet
+ * has proper structure. Then test waits for a signal
+ * from the resumed debuggee. If signal has not received
+ * after specified by WAITTIME timeout, test complains
+ * about an error.
+ * Finally, test sends debugee VM signal to quit, waits
+ * for debugee VM exits and exits too with a proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.Resume.resume001
+ * nsk.jdwp.VirtualMachine.Resume.resume001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.Resume.resume001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Resume/resume001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.Resume;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class resume001a {
+
+ public static void main(String args[]) {
+ resume001a _resume001a = new resume001a();
+ System.exit(resume001.JCK_STATUS_BASE + _resume001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return resume001.PASSED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/SetDefaultStratum/setdefstrat001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.SetDefaultStratum;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+/**
+ * Test for JDWP command: VirtualMachine.SetDefaultStratum.
+ *
+ * See setdefstrat001.README for description of test execution.
+ *
+ * This class represents debugger part of the test.
+ * Test is executed by invoking method runIt().
+ * JDWP command is tested in the method testCommand().
+ *
+ * @see #runIt()
+ * @see #testCommand()
+ */
+public class setdefstrat001 {
+
+ // exit status constants
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+
+ // communication signals constants
+ static final String READY = "ready";
+ static final String QUIT = "quit";
+
+ // package and classes names constants
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.SetDefaultStratum";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "setdefstrat001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ // VM capability constatnts
+ static final int VM_CAPABILITY_NUMBER = JDWP.Capability.CAN_SET_DEFAULT_STRATUM;
+ static final String VM_CAPABILITY_NAME = "canSetDefaultStratum";
+
+ // tested JDWP command constants
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.SetDefaultStratum";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.SetDefaultStratum;
+
+ // new value for default startum
+ static final String NEW_DEFAULT_STRATUM = "test";
+
+ // usual scaffold objects
+ ArgumentHandler argumentHandler = null;
+ Log log = null;
+ Binder binder = null;
+ Debugee debugee = null;
+ Transport transport = null;
+ IOPipe pipe = null;
+
+ // test passed or not
+ boolean success = true;
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Start test from command line.
+ */
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ /**
+ * Start JCK-compilant test.
+ */
+ public static int run(String argv[], PrintStream out) {
+ return new setdefstrat001().runIt(argv, out);
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Perform test execution.
+ */
+ public int runIt(String argv[], PrintStream out) {
+
+ // make log for debugger messages
+ argumentHandler = new ArgumentHandler(argv);
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debuggee
+ binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ transport = debugee.getTransport();
+ pipe = debugee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ // work with prepared debuggee
+ try {
+ log.display("\n>>> Checking VM capability \n");
+
+ // check for VM capability
+ log.display("Checking VM capability: " + VM_CAPABILITY_NAME);
+ if (!debugee.getNewCapability(VM_CAPABILITY_NUMBER, VM_CAPABILITY_NAME)) {
+ out.println("TEST PASSED: unsupported VM capability: "
+ + VM_CAPABILITY_NAME);
+ return PASSED;
+ }
+
+ // perform testing JDWP command
+ log.display("\n>>> Testing JDWP command \n");
+ testCommand();
+
+ } finally {
+ // quit debugee
+ log.display("\n>>> Finishing test \n");
+ quitDebugee();
+ }
+
+ } catch (Failure e) {
+ log.complain("TEST FAILED: " + e.getMessage());
+ success = false;
+ } catch (Exception e) {
+ e.printStackTrace(out);
+ log.complain("Caught unexpected exception while running the test:\n\t" + e);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+ /**
+ * Prepare debugee for testing and waiting for ready signal.
+ */
+ void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debugee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + READY);
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+ if (! signal.equals(READY)) {
+ throw new TestBug("Unexpected signal received from debugee: " + signal
+ + " (expected: " + READY + ")");
+ }
+ }
+
+ /**
+ * Sending debugee signal to quit and waiting for it exits.
+ */
+ void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + QUIT);
+ pipe.println(QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+
+ // analize debugee exit status code
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ log.complain("Debugee FAILED with exit code: " + code);
+ success = false;
+ }
+ }
+
+ /**
+ * Perform testing JDWP command.
+ */
+ void testCommand() {
+ // create command packet and fill requred out data
+ log.display("Create command packet:");
+ log.display("Command: " + JDWP_COMMAND_NAME);
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ log.display(" stratumID: " + NEW_DEFAULT_STRATUM);
+ command.addString(NEW_DEFAULT_STRATUM);
+ command.setLength();
+
+ // send command packet to debugee
+ try {
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+ } catch (IOException e) {
+ log.complain("Unable to send command packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ ReplyPacket reply = new ReplyPacket();
+
+ // receive reply packet from debugee
+ try {
+ log.display("Waiting for reply packet");
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+ } catch (IOException e) {
+ log.complain("Unable to read reply packet:\n\t" + e);
+ success = false;
+ return;
+ }
+
+ // check reply packet header
+ try{
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ log.complain("Bad header of reply packet:\n\t" + e.getMessage());
+ success = false;
+ return;
+ }
+
+ // start parsing reply packet data
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ // no data in reply packet
+
+ // check for extra data in reply packet
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in reply packet at: "
+ + reply.offsetString());
+ success = false;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/SetDefaultStratum/setdefstrat001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/SetDefaultStratum/setdefstrat001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test performs checking for
+ * command set: VirtualMachine
+ * command: SetDefaultStratum
+ * Test checks that debugee accept the command packet and
+ * replies with correct reply packet.
+ * Test consists of two compoments:
+ * debugger: setdefstrat001
+ * debuggee: setdefstrat001a
+ * First, debugger uses nsk.share support classes to launch debuggee
+ * and obtain Transport object, that represents JDWP transport channel.
+ * Also communication channel (IOPipe) is established between
+ * debugger and debuggee to exchange with synchronization signals.
+ * Debugger uses VirtualMachine.CapabilitiesNew command to check
+ * VM capability canSetDefaultStratum before testing JDWP command.
+ * Then, debugger creates command packet for VirtualMachine.SetDefaultStratum
+ * command with new string value, writes packet to the transport
+ * channel, and waits for a reply packet.
+ * When reply packet is received, debugger parses the packet structure
+ * and checks that the received reply packet contains no data.
+ * Finally, debugger sends debuggee signal to quit, waits for it exits
+ * and exits too with the proper exit code.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.SetDefaultStratum.setdefstrat001
+ * nsk.jdwp.VirtualMachine.SetDefaultStratum.setdefstrat001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.SetDefaultStratum.setdefstrat001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/SetDefaultStratum/setdefstrat001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.SetDefaultStratum;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+/**
+ * This class represents debuggee part in the test.
+ */
+public class setdefstrat001a {
+
+ public static void main(String args[]) {
+ setdefstrat001a _setdefstrat001a = new setdefstrat001a();
+ System.exit(setdefstrat001.JCK_STATUS_BASE + _setdefstrat001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ //make log for debugee messages
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+
+ // make communication pipe to debugger
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+
+ // send debugger signal READY
+ log.display("Sending signal to debugger: " + setdefstrat001.READY);
+ pipe.println(setdefstrat001.READY);
+
+ // wait for signal QUIT from debugeer
+ log.display("Waiting for signal from debugger: " + setdefstrat001.QUIT);
+ String signal = pipe.readln();
+ log.display("Received signal from debugger: " + signal);
+
+ // check received signal
+ if (! signal.equals(setdefstrat001.QUIT)) {
+ log.complain("Unexpected communication signal from debugee: " + signal
+ + " (expected: " + setdefstrat001.QUIT + ")");
+ log.display("Debugee FAILED");
+ return setdefstrat001.FAILED;
+ }
+
+ // exit debugee
+ log.display("Debugee PASSED");
+ return setdefstrat001.PASSED;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/TopLevelThreadGroups/threadgroups001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.TopLevelThreadGroups;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class threadgroups001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.TopLevelThreadGroups";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "threadgroups001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.TopLevelThreadGroups";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.TopLevelThreadGroups;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new threadgroups001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ // begin test of JDWP command
+
+ try {
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ int groups = reply.getInt();
+ log.display(" groups: " + groups);
+
+ for (int i = 0; i < groups; i++) {
+ long threadGroupID = reply.getObjectID();
+ log.display(" " + i + " threadGroupID: " + threadGroupID);
+ }
+
+ if (! reply.isParsed()) {
+ log.complain("Extra bytes in reply packet at: " + reply.currentPosition());
+ success = false;
+ }
+
+ if (groups < 0) {
+ log.complain("Negative number of returned thread groups: " + groups);
+ success = false;
+ }
+
+ if (groups == 0) {
+ log.complain("No thread groups returned: " + groups);
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Exception catched: " + e);
+ success = false;
+ }
+
+ // end test of JDWP command
+
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED: " + code);
+ } else {
+ log.complain("Debugee FAILED: " + code);
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/TopLevelThreadGroups/threadgroups001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/TopLevelThreadGroups/threadgroups001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test perform checking for
+ * command set: VirtualMachine
+ * command: ClassPaths
+ * Test launches debuggee VM using support classes and sends
+ * ClassPaths command to it. Then test receives reply for this
+ * command and prints classpath and bootclasspath value
+ * from received reply.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.TopLevelThreadGroups.threadgroups001
+ * nsk.jdwp.VirtualMachine.TopLevelThreadGroups.threadgroups001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.TopLevelThreadGroups.threadgroups001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/TopLevelThreadGroups/threadgroups001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.TopLevelThreadGroups;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+import java.io.*;
+
+public class threadgroups001a {
+
+ public static void main(String args[]) {
+ threadgroups001a _threadgroups001a = new threadgroups001a();
+ System.exit(threadgroups001.JCK_STATUS_BASE + _threadgroups001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return threadgroups001.PASSED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version001.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.Version;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class version001 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.Version";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "version001";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.Version";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.Version;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new version001().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ // begin test of JDWP command
+
+ try {
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ String description = reply.getString();
+ log.display(" description: " + description);
+
+ int jdwpMajor = reply.getInt();
+ log.display(" jdwpMajor: " + jdwpMajor);
+
+ int jdwpMinor = reply.getInt();
+ log.display(" jdwpMinor: " + jdwpMinor);
+
+ String vmVersion = reply.getString();
+ log.display(" vmVersion: " + vmVersion);
+
+ String vmName = reply.getString();
+ log.display(" vmName: " + vmName);
+
+ if (! reply.isParsed()) {
+ log.complain("Extra bytes in reply packet at: " + reply.currentPosition());
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Exception catched: " + e);
+ success = false;
+ }
+
+ // end test of JDWP command
+
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED: " + code);
+ } else {
+ log.complain("Debugee FAILED: " + code);
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version001/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/Version/version001.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test perform checking for
+ * command set: VirtualMachine
+ * command: Version
+ * Test launches debuggee VM using support classes and sends
+ * Version command to it. Then test receives reply for this
+ * command and prints version information from that reply.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.Version.version001
+ * nsk.jdwp.VirtualMachine.Version.version001a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.Version.version001
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version001a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.Version;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class version001a {
+
+ public static void main(String args[]) {
+ version001a _version001a = new version001a();
+ System.exit(version001.JCK_STATUS_BASE + _version001a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return version001.PASSED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version002.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.Version;
+
+import java.io.*;
+import java.util.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class version002 {
+ static final int JCK_STATUS_BASE = 95;
+ static final int PASSED = 0;
+ static final int FAILED = 2;
+ static final String PACKAGE_NAME = "nsk.jdwp.VirtualMachine.Version";
+ static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "version002";
+ static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
+
+ static final String JDWP_COMMAND_NAME = "VirtualMachine.Version";
+ static final int JDWP_COMMAND_ID = JDWP.Command.VirtualMachine.Version;
+
+ public static void main (String argv[]) {
+ System.exit(run(argv,System.out) + JCK_STATUS_BASE);
+ }
+
+ public static int run(String argv[], PrintStream out) {
+ return new version002().runIt(argv, out);
+ }
+
+ public int runIt(String argv[], PrintStream out) {
+
+ boolean success = true;
+
+ try {
+ ArgumentHandler argumentHandler = new ArgumentHandler(argv);
+ Log log = new Log(out, argumentHandler);
+
+ try {
+
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Start debugee VM");
+ Debugee debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
+ Transport transport = debugee.getTransport();
+ IOPipe pipe = debugee.createIOPipe();
+
+ log.display("Waiting for VM_INIT event");
+ debugee.waitForVMInit();
+
+ log.display("Querying for IDSizes");
+ debugee.queryForIDSizes();
+
+ log.display("Resume debugee VM");
+ debugee.resume();
+
+ log.display("Waiting for command: " + "ready");
+ String cmd = pipe.readln();
+ log.display("Received command: " + cmd);
+
+ // begin test of JDWP command
+
+ try {
+ CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);
+ // A properly formed CommandPacket has JDWP.Flag.NONE
+ // for the 'flags' field. Set the 'flags' field to '!'
+ // simulate a bad value in the printable ASCII range.
+ // '!' == 0x21 which means the bad value also does not
+ // have the JDWP.Flag.REPLY_PACKET (0x80) set.
+ command.setFlags((byte) '!');
+
+ log.display("Sending command packet:\n" + command);
+ transport.write(command);
+
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+
+ if (true) {
+ // In this test (compared to version001), we
+ // should never reach here because the debuggee
+ // should have thrown an IOException and printed
+ // this error message:
+ // ERROR: Received jdwpPacket with flags != 0x0 (actual=0x21) when a jdwpCmdPacket was expected.
+
+ throw new Failure("Debuggee did not detect bad flags field.");
+ }
+ // The code below this point of the try-catch block is
+ // not reachable and could be deleted. It is left in
+ // place to ease porting of this test to earlier releases.
+
+ log.display("Reply packet received:\n" + reply);
+
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+
+ String description = reply.getString();
+ log.display(" description: " + description);
+
+ int jdwpMajor = reply.getInt();
+ log.display(" jdwpMajor: " + jdwpMajor);
+
+ int jdwpMinor = reply.getInt();
+ log.display(" jdwpMinor: " + jdwpMinor);
+
+ String vmVersion = reply.getString();
+ log.display(" vmVersion: " + vmVersion);
+
+ String vmName = reply.getString();
+ log.display(" vmName: " + vmName);
+
+ if (! reply.isParsed()) {
+ log.complain("Extra bytes in reply packet at: " + reply.currentPosition());
+ success = false;
+ }
+
+ } catch (IOException ie) {
+ // version001 expects to pass.
+ // This test expects to fail due to an IOException.
+ log.display("Expected IOException caught: " + ie);
+ success = true;
+ } catch (Exception e) {
+ log.complain("Exception catched: " + e);
+ success = false;
+ }
+
+ // end test of JDWP command
+
+ log.display("Sending command: " + "quit");
+ pipe.println("quit");
+
+ log.display("Waiting for debugee exits");
+ int code = debugee.waitFor();
+ if (code == JCK_STATUS_BASE + PASSED) {
+ log.display("Debugee PASSED: " + code);
+ } else {
+ log.complain("Debugee FAILED: " + code);
+ success = false;
+ }
+
+ } catch (Exception e) {
+ log.complain("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ success = false;
+ }
+
+ if (!success) {
+ log.complain("TEST FAILED");
+ return FAILED;
+ }
+
+ } catch (Exception e) {
+ out.println("Unexpected exception: " + e);
+ e.printStackTrace(out);
+ out.println("TEST FAILED");
+ return FAILED;
+ }
+
+ out.println("TEST PASSED");
+ return PASSED;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version002/TestDescription.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017, 2018, 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 converted from VM Testbase nsk/jdwp/VirtualMachine/Version/version002.
+ * VM Testbase keywords: [quick, jpda, jdwp]
+ * VM Testbase readme:
+ * DESCRIPTION
+ * This test was derived from the version001 test.
+ * This test perform checking for
+ * command set: VirtualMachine
+ * command: Version
+ * Test launches debuggee VM using support classes and sends
+ * a malformed Version command to it. Then test expect the
+ * command to fail and debuggee VM to exit with an error.
+ *
+ * @library /vmTestbase /test/hotspot/jtreg/vmTestbase
+ * /test/lib
+ * @run driver jdk.test.lib.FileInstaller . .
+ * @build nsk.jdwp.VirtualMachine.Version.version002
+ * nsk.jdwp.VirtualMachine.Version.version002a
+ * @run main/othervm PropertyResolvingWrapper
+ * nsk.jdwp.VirtualMachine.Version.version002
+ * -arch=${os.family}-${os.simpleArch}
+ * -verbose
+ * -waittime=5
+ * -debugee.vmkind=java
+ * -transport.address=dynamic
+ * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}"
+ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/Version/version002a.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.jdwp.VirtualMachine.Version;
+
+import java.io.*;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+import nsk.share.jdwp.*;
+
+public class version002a {
+
+ public static void main(String args[]) {
+ version002a _version002a = new version002a();
+ System.exit(version002.JCK_STATUS_BASE + _version002a.runIt(args, System.err));
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ ArgumentHandler argumentHandler = new ArgumentHandler(args);
+ Log log = new Log(out, argumentHandler);
+ log.display("Creating pipe");
+ IOPipe pipe = argumentHandler.createDebugeeIOPipe(log);
+ log.display("Sending command: " + "ready");
+ pipe.println("ready");
+ log.display("Waiting for command: " + "quit");
+ String command = pipe.readln();
+ log.display("Received command: " + command);
+ log.display("Debugee PASSED");
+ return version002.PASSED;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/AbstractJDWPDebuggee.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2007, 2018, 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.
+ */
+package nsk.share.jdwp;
+
+import nsk.share.jpda.AbstractDebuggeeTest;
+import nsk.share.jpda.DebugeeArgumentHandler;
+
+public class AbstractJDWPDebuggee extends AbstractDebuggeeTest {
+
+ /*
+ * Create argument handler handling options specific for JDWP tests
+ */
+ protected DebugeeArgumentHandler createArgumentHandler(String args[]) {
+ return new ArgumentHandler(args);
+ }
+
+ public static void main(String args[]) {
+ AbstractJDWPDebuggee debuggee = new AbstractJDWPDebuggee();
+ debuggee.init(args);
+ debuggee.doTest();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/ArgumentHandler.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.share.jdwp;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Parser for JDWP test's specific command-line arguments.
+ * <p>
+ * <code>ArgumentHandler</code> handles JDWP test's specific
+ * arguments related to launching debugee VM using JDWP features
+ * in addition to general arguments recognized by
+ * <code>DebugeeArgumentHandler</code> and <code>ArgumentParser</code>.
+ * <p>
+ * Following is the list of specific options recognized by
+ * <code>AgrumentHandler</code>:
+ * <ul>
+ * <li> <code>-connector=[attaching|listening]</code> -
+ * JDWP connection type
+ * <li> <code>-transport=[socket|shmem]</code> -
+ * JDWP transport kind
+ * </ul>
+ * <p>
+ * See also list of arguments recognized by the base <code>DebugeeArgumnethandler</code>
+ * and <code>ArgumentParser</code> classes.
+ * <p>
+ * See also description of <code>ArgumentParser</code> how to work with
+ * command line arguments and options.
+ *
+ * @see ArgumentParser
+ * @see DebugeeArgumentHandler
+ */
+public class ArgumentHandler extends DebugeeArgumentHandler {
+
+ /**
+ * Keep a copy of raw command-line arguments and parse them;
+ * but throw an exception on parsing error.
+ *
+ * @param args Array of the raw command-line arguments.
+ *
+ * @throws NullPointerException If <code>args==null</code>.
+ * @throws IllegalArgumentException If Binder or Log options
+ * are set incorrectly.
+ *
+ * @see #setRawArguments(String[])
+ */
+ public ArgumentHandler(String args[]) {
+ super(args);
+ }
+
+ /**
+ * Check if an option is admissible and has proper value.
+ * This method is invoked by <code>parseArguments()</code>
+ *
+ * @param option option name
+ * @param value string representation of value (could be an empty string)
+ * null if this option has no value
+ * @return <i>true</i> if option is admissible and has proper value
+ * <i>false</i> if otion is not admissible
+ *
+ * @throws <i>BadOption</i> if option has illegal value
+ *
+ * @see #parseArguments()
+ */
+ protected boolean checkOption(String option, String value) {
+ return super.checkOption(option, value);
+ }
+
+ /**
+ * Check options against inconcistence.
+ * This method is invoked by <code>parseArguments()</code>
+ *
+ * @see #parseArguments()
+ */
+ protected void checkOptions() {
+
+ if (isShmemTransport()) {
+ throw new BadOption("transport: shared memory transport is not supported yet");
+ }
+
+ super.checkOptions();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/Binder.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.share.jdwp;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+
+import java.io.*;
+
+/**
+ * This class provides debugger with connection to debugee VM
+ * using JDWP protocol.
+ * <p>
+ * This class provides abilities to launch and bind to debugee VM
+ * as described for base <code>DebugeeBinder</code> class,
+ * using raw JDWP protocol.
+ * <p>
+ * When <code>Binder</code> is asked to bind to debugee by invoking
+ * <code>bindToBebugee()</code> method it launches process
+ * with debugee VM and makes connection to it using JDWP transport
+ * corresponding to value of command line options <code>-connector</code>
+ * and <code>-transport</code>.
+ * After debugee is launched and connection is established
+ * <code>Binder</code> constructs <code>Debugee</code> object,
+ * that provides abilities to interact with debugee VM.
+ *
+ * @see Debugee
+ * @see DebugeeBinder
+ */
+final public class Binder extends DebugeeBinder {
+
+ /**
+ * Default message prefix for <code>Binder</code> object.
+ */
+ public static final String LOG_PREFIX = "binder> ";
+
+ /**
+ * Get version string.
+ */
+ public static String getVersion () {
+ return "@(#)Binder.java %I% %E%";
+ }
+
+ // -------------------------------------------------- //
+
+ /**
+ * Handler of command line arguments.
+ */
+ private ArgumentHandler argumentHandler = null;
+
+ /**
+ * Return <code>argumentHandler</code> of this binder.
+ */
+ public ArgumentHandler getArgumentHandler() {
+ return argumentHandler;
+ }
+
+ // -------------------------------------------------- //
+
+ /**
+ * Make new <code>Binder</code> object with specified
+ * <code>argumentHandler</code> and <code>log</code>.
+ */
+ public Binder (ArgumentHandler argumentHandler, Log log) {
+ super(argumentHandler, log);
+ this.argumentHandler = argumentHandler;
+ }
+
+ // -------------------------------------------------- //
+
+ /**
+ * Start debugee VM and establish JDWP connection to it.
+ */
+ public Debugee bindToDebugee (String classToExecute) {
+
+ Debugee debugee = null;
+
+ prepareForPipeConnection(argumentHandler);
+
+ if (argumentHandler.isLaunchedRemotely()) {
+ connectToBindServer(classToExecute);
+ debugee = launchDebugee(classToExecute);
+ } else {
+ debugee = launchDebugee(classToExecute);
+ debugee.redirectOutput(log);
+ }
+
+ Finalizer finalizer = new Finalizer(debugee);
+ finalizer.activate();
+
+ Transport transport = debugee.connect();
+
+ return debugee;
+ }
+
+ /**
+ * Launch debugee VM for specified class.
+ */
+ public Debugee launchDebugee (String classToExecute) {
+
+ try {
+
+ if (argumentHandler.isLaunchedLocally()) {
+ LocalLaunchedDebugee debugee = new LocalLaunchedDebugee(this);
+ String address = debugee.prepareTransport(argumentHandler);
+ if (address == null)
+ address = makeTransportAddress();
+ String[] argsArray = makeCommandLineArgs(classToExecute, address);
+ debugee.launch(argsArray);
+ return debugee;
+ }
+
+ if (argumentHandler.isLaunchedRemotely()) {
+ RemoteLaunchedDebugee debugee = new RemoteLaunchedDebugee(this);
+ String address = debugee.prepareTransport(argumentHandler);
+ if (address == null)
+ address = makeTransportAddress();
+ String[] argsArray = makeCommandLineArgs(classToExecute, address);
+ debugee.launch(argsArray);
+ return debugee;
+ }
+
+ if (argumentHandler.isLaunchedManually()) {
+ ManualLaunchedDebugee debugee = new ManualLaunchedDebugee(this);
+ String address = debugee.prepareTransport(argumentHandler);
+ if (address == null)
+ address = makeTransportAddress();
+ String cmdLine = makeCommandLineString(classToExecute, address, "\"");
+ debugee.launch(cmdLine);
+ return debugee;
+ }
+
+ throw new TestBug("Unexpected launching mode: "
+ + argumentHandler.getLaunchMode());
+ } catch (IOException e) {
+ e.printStackTrace(log.getOutStream());
+ throw new Failure("Caught exception while launching debugee:\n\t" + e);
+ }
+ }
+
+}
+
+/**
+ * Mirror of locally launched debugee.
+ */
+final class LocalLaunchedDebugee extends Debugee {
+
+ /** Enwrap the existing <code>VM</code> mirror. */
+ public LocalLaunchedDebugee (Binder binder) {
+ super(binder);
+ checkTermination = true;
+ }
+
+ // ---------------------------------------------- //
+
+ public void launch(String[] args) throws IOException {
+ String cmdLine = ArgumentHandler.joinArguments(args, "\"");
+ display("Starting java process:\n" + cmdLine);
+ process = binder.launchProcess(args);
+ }
+
+ /** Return exit status of the debugee VM. */
+ public int getStatus () {
+ return process.exitValue();
+ }
+
+ /** Check whether the debugee VM has been terminated. */
+ public boolean terminated () {
+ if (process == null)
+ return true;
+
+ try {
+ int value = process.exitValue();
+ return true;
+ } catch (IllegalThreadStateException e) {
+ return false;
+ }
+ }
+
+ // ---------------------------------------------- //
+
+ /** Kill the debugee VM. */
+ protected void killDebugee () {
+ super.killDebugee();
+ if (!terminated()) {
+ log.display("Killing debugee VM process");
+ process.destroy();
+ }
+ }
+
+ /** Wait until the debugee VM shutdown or crash. */
+ protected int waitForDebugee () throws InterruptedException {
+ return process.waitFor();
+ }
+
+ /** Get a pipe to write to the debugee's stdin stream. */
+ protected OutputStream getInPipe () {
+ return process.getOutputStream();
+ }
+
+ /** Get a pipe to read the debugee's stdout stream. */
+ protected InputStream getOutPipe () {
+ return process.getInputStream();
+ }
+
+ /** Get a pipe to read the debugee's stderr stream. */
+ protected InputStream getErrPipe () {
+ return process.getErrorStream();
+ }
+}
+
+
+/**
+ * Mirror of remotely launched debugee.
+ */
+final class RemoteLaunchedDebugee extends Debugee {
+
+ /** Enwrap the existing <code>VM</code> mirror. */
+ public RemoteLaunchedDebugee (Binder binder) {
+ super(binder);
+ }
+
+ // ---------------------------------------------- //
+
+ public void launch(String[] args) throws IOException {
+ String cmdLine = ArgumentHandler.joinArguments(args, "\"");
+ display("Starting remote java process:\n" + cmdLine);
+ binder.launchRemoteProcess(args);
+ }
+
+ /** Return exit status of the debugee VM. */
+ public int getStatus () {
+ return binder.getRemoteProcessStatus();
+ }
+
+ /** Check whether the debugee VM has been terminated. */
+ public boolean terminated () {
+ return binder.isRemoteProcessTerminated();
+ }
+
+ // ---------------------------------------------- //
+
+ /** Kill the debugee VM. */
+ protected void killDebugee () {
+ super.killDebugee();
+ if (!terminated()) {
+ log.display("Killing debugee VM process");
+ binder.killRemoteProcess();
+ }
+ }
+
+ /** Wait until the debugee VM shutdown or crash. */
+ protected int waitForDebugee () {
+ return binder.waitForRemoteProcess();
+ }
+
+ /** Get a pipe to write to the debugee's stdin stream. */
+ protected OutputStream getInPipe () {
+ return null;
+ }
+
+ /** Get a pipe to read the debugee's stdout stream. */
+ protected InputStream getOutPipe () {
+ return null;
+ }
+
+ /** Get a pipe to read the debugee's stderr stream. */
+ protected InputStream getErrPipe () {
+ return null;
+ }
+
+ public void redirectStdout(OutputStream out) {
+ }
+
+ public void redirectStdout(Log log, String prefix) {
+ }
+
+ public void redirectStderr(OutputStream out) {
+ }
+
+ public void redirectStderr(Log log, String prefix) {
+ }
+}
+
+
+/**
+ * Mirror of manually launched debugee.
+ */
+final class ManualLaunchedDebugee extends Debugee {
+
+ private int exitCode = 0;
+ private boolean finished = false;
+ private static BufferedReader bin = new BufferedReader(new InputStreamReader(System.in));
+
+ /** Enwrap the existing <code>VM</code> mirror. */
+ public ManualLaunchedDebugee (Binder binder) {
+ super(binder);
+ }
+
+ // ---------------------------------------------- //
+
+ public void launch(String commandLine) throws IOException {
+ putMessage("Launch target VM using such command line:\n"
+ + commandLine);
+ String answer = askQuestion("Has the VM successfully started? (yes/no)", "yes");
+ for ( ; ; ) {
+ if (answer.equals("yes"))
+ break;
+ if (answer.equals("no"))
+ throw new Failure ("Unable to manually launch debugee VM");
+ answer = askQuestion("Wrong answer. Please type yes or no", "yes");
+ }
+ }
+
+ private void putMessage(String msg) {
+ System.out.println("\n>>> " + msg);
+ }
+
+ private String askQuestion(String question, String defaultAnswer) {
+ try {
+ System.out.print("\n>>> " + question);
+ System.out.print(" [" + defaultAnswer + "] ");
+ System.out.flush();
+ String answer = bin.readLine();
+ if (answer.equals(""))
+ return defaultAnswer;
+ return answer;
+ } catch (IOException e) {
+ e.printStackTrace(log.getOutStream());
+ throw new Failure("Caught exception while reading answer:\n\t" + e);
+ }
+ }
+
+ /** Return exit status of the debugee VM. */
+ public int getStatus () {
+ if (! terminated()) {
+ throw new Failure("Unable to get status of debugee VM: process still alive");
+ }
+ return exitCode;
+ }
+
+ /** Check whether the debugee VM has been terminated. */
+ public boolean terminated () {
+ if(! finished) {
+ String answer = askQuestion("Has the VM exited?", "no");
+ for ( ; ; ) {
+ if (answer.equals("no"))
+ return false;
+ if (answer.equals("yes")) {
+ finished = true;
+ waitForDebugee();
+ break;
+ }
+ answer = askQuestion("Wrong answer. Please type yes or no", "yes");
+ }
+ }
+ return finished;
+ }
+
+ // ---------------------------------------------- //
+
+ /** Kill the debugee VM. */
+ protected void killDebugee () {
+ super.killDebugee();
+ if (!terminated()) {
+ putMessage("Kill launched VM");
+ String answer = askQuestion("Has the VM successfully terminated? (yes/no)", "yes");
+ for ( ; ; ) {
+ if (answer.equals("yes")) {
+ finished = true;
+ break;
+ }
+ if (answer.equals("no"))
+ throw new Failure ("Unable to manually kill debugee VM");
+ answer = askQuestion("Wrong answer. Please type yes or no", "yes");
+ }
+ }
+ }
+
+ /** Wait until the debugee VM shutdown or crash. */
+ protected int waitForDebugee () {
+ putMessage("Wait for launched VM to exit.");
+ String answer = askQuestion("What is VM exit code?", "95");
+ for ( ; ; ) {
+ try {
+ exitCode = Integer.parseInt(answer);
+ break;
+ } catch (NumberFormatException e) {
+ answer = askQuestion("Wrong answer. Please type integer value", "95");
+ }
+ }
+ finished = true;
+ return exitCode;
+ }
+
+ /** Get a pipe to write to the debugee's stdin stream. */
+ protected OutputStream getInPipe () {
+ return null;
+ }
+
+ /** Get a pipe to read the debugee's stdout stream. */
+ protected InputStream getOutPipe () {
+ return null;
+ }
+
+ /** Get a pipe to read the debugee's stderr stream. */
+ protected InputStream getErrPipe () {
+ return null;
+ }
+
+ public void redirectStdout(OutputStream out) {
+ }
+
+ public void redirectStdout(Log log, String prefix) {
+ }
+
+ public void redirectStderr(OutputStream out) {
+ }
+
+ public void redirectStderr(Log log, String prefix) {
+ }
+
+ public void close() {
+ try {
+ bin.close();
+ } catch (IOException e) {
+ log.display("WARNING: Caught IOException while closing InputStream");
+ }
+ bin = null;
+ super.close();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/BoundException.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.share.jdwp;
+
+/**
+ * This exception is thrown when ByteBuffer parse errors are encountered.
+ */
+public class BoundException extends Exception {
+ public BoundException(String message) {
+ super(message);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/ByteBuffer.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,1020 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.share.jdwp;
+
+import java.io.*;
+import nsk.share.*;
+
+/**
+ * This class represents a byte buffer of variable size.
+ */
+public class ByteBuffer {
+
+ /**
+ * Empty byte value (zero).
+ */
+ private static final byte EMPTY_BYTE = (byte)0;
+
+ /**
+ * Current number of bytes in the buffer.
+ */
+ private int CurrentSize;
+
+ /**
+ * Delta to increase buffer size.
+ */
+ private int Delta;
+
+ /**
+ * Current offset from the buffer begin during parsing packet.
+ */
+ int parseOffset;
+
+ /**
+ * Array of bytes in the buffer.
+ */
+ protected byte[] bytes;
+
+ /**
+ * Make an empty <code>ByteBuffer</code> object.
+ */
+ public ByteBuffer() {
+ this(128, 128);
+ }
+
+ /**
+ * Make an empty <code>ByteBuffer</code> object with given initial capacity.
+ * When there is no space for a new byte in a buffer it's capacity
+ * grows by Delta.
+ */
+ public ByteBuffer(int InitialSize, int Delta) {
+ if (Delta <= 0)
+ Delta = 16;
+ this.Delta = Delta;
+ CurrentSize = 0;
+ bytes = new byte[InitialSize];
+ parseOffset = 0;
+ }
+
+ /**
+ * Make a copy of specified byte buffer.
+ */
+ public ByteBuffer(ByteBuffer buffer) {
+ int InitialSize = buffer.bytes.length;
+ Delta = buffer.Delta;
+ CurrentSize = buffer.CurrentSize;
+ bytes = new byte[InitialSize];
+ for (int i = 0; i < CurrentSize; i++ ) {
+ bytes[i] = buffer.bytes[i];
+ }
+ parseOffset = 0;
+ }
+
+ /**
+ * Return number of bytes in this buffer.
+ */
+ public int length() {
+ return CurrentSize;
+ }
+
+ /**
+ * Return array of bytes in this buffer.
+ */
+ public byte[] getBytes() {
+ return bytes;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Replace the byte at the specified offset in this buffer with the
+ * less significant byte from the int value.
+ *
+ * @throws BoundException if specified offset is out of buffer bounds
+ */
+ public void putByte(int off, byte value) throws BoundException {
+
+ if ((off < 0) || (off >= CurrentSize))
+ throw new BoundException("Unable to put one byte at " + offsetString(off));
+
+ bytes[off] = value;
+ }
+
+ /**
+ * Replace len bytes starting at offset off with the bytes from the
+ * given byte array.
+ *
+ * @throws BoundException if offset and length are out of buffer bounds
+ */
+ public void putBytes(int off, byte[] value, int start, int len) throws BoundException {
+ if (len > (CurrentSize - off)) {
+ throw new BoundException("Unable to put " + len + " bytes at " + offsetString(off) +
+ " (available bytes: " + (CurrentSize - off) + ")" );
+ }
+ try {
+ for (int i = 0; i < len; i++)
+ putByte(off++, value[start++]);
+ } catch (BoundException e) {
+ throw new Failure("Caught unexpected bound exception while putting " + len +
+ "bytes at " + offsetString(off) + ":\n\t" + e);
+ }
+ }
+
+ /**
+ * Replace count (1 - 8) bytes starting at offset off with the less
+ * significant bytes from the specified ID value.
+ *
+ * @throws BoundException if offset and count are out of buffer bounds
+ */
+ public void putID(int off, long value, int count) throws BoundException {
+
+ if ((count <= 0) || (count > 8))
+ throw new TestBug("Illegal number of bytes of ID value to put: " + count);
+
+ if (count > CurrentSize - off) {
+ throw new BoundException("Unable to put " + count + " bytes of ID value at " +
+ offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );
+ }
+
+ try {
+ putValueBytes(off, value, count);
+ } catch (BoundException e) {
+ throw new Failure("Caught unexpected bound exception while putting " + count +
+ "bytes of ID value at " + offsetString(off) + ":\n\t" + e);
+ }
+ }
+
+ /**
+ * Replace four bytes starting at offset off with the bytes from the
+ * specified int value.
+ *
+ * @throws BoundException if offset is out of buffer bounds
+ */
+ public void putInt(int off, int value) throws BoundException {
+ final int count = JDWP.TypeSize.INT;
+
+ if (count > CurrentSize - off) {
+ throw new BoundException("Unable to put " + count + " bytes of int value at " +
+ offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );
+ }
+
+ try {
+ putValueBytes(off, value, count);
+ } catch (BoundException e) {
+ throw new Failure("Caught unexpected bound exception while putting " + count +
+ "bytes of int value at " + offsetString(off) + ":\n\t" + e);
+ }
+ }
+
+ /**
+ * Replace two bytes starting at offset off with the bytes
+ * from the specified short value.
+ *
+ * @throws BoundException if offset is out of buffer bounds
+ */
+ public void putShort(int off, short value) throws BoundException {
+ final int count = JDWP.TypeSize.SHORT;
+
+ if (count > CurrentSize - off) {
+ throw new BoundException("Unable to put " + count + " bytes of short value at " +
+ offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );
+ }
+
+ try {
+ putValueBytes(off, value, count);
+ } catch (BoundException e) {
+ throw new Failure("Caught unexpected bound exception while putting " + count +
+ "bytes of short value at " + offsetString(off) + ":\n\t" + e);
+ }
+ }
+
+ /**
+ * Replace eight bytes starting at offset off with the bytes
+ * from the specified long value.
+ *
+ * @throws BoundException if offset is out of buffer bounds
+ */
+ public void putLong(int off, long value) throws BoundException {
+ final int count = JDWP.TypeSize.LONG;
+
+ if (count > CurrentSize - off) {
+ throw new BoundException("Unable to put " + count + " bytes of long value at " +
+ offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );
+ }
+
+ try {
+ putValueBytes(off, value, count);
+ } catch (BoundException e) {
+ throw new Failure("Caught unexpected bound exception while putting " + count +
+ "bytes of long value at " + offsetString(off) + ":\n\t" + e);
+ }
+ }
+
+ /**
+ * Replace four bytes starting at offset off with the bytes
+ * from the specified float value.
+ *
+ * @throws BoundException if offset is out of buffer bounds
+ */
+ public void putFloat(int off, float value) throws BoundException {
+ final int count = JDWP.TypeSize.FLOAT;
+
+ if (count > CurrentSize - off) {
+ throw new BoundException("Unable to put " + count + " bytes of float value at " +
+ offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );
+ }
+
+ try {
+ long l = Float.floatToIntBits(value);
+ putValueBytes(off, l, count);
+ } catch (BoundException e) {
+ throw new Failure("Caught unexpected bound exception while putting " + count +
+ "bytes of float value at " + offsetString(off) + ":\n\t" + e);
+ }
+ }
+
+ /**
+ * Replace eight bytes starting at offset off with the bytes
+ * from the specified double value.
+ *
+ * @throws BoundException if offset is out of buffer bounds
+ */
+ public void putDouble(int off, double value) throws BoundException {
+ final int count = JDWP.TypeSize.DOUBLE;
+
+ if (count > CurrentSize - off) {
+ throw new BoundException("Unable to put " + count + " bytes of double value at " +
+ offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );
+ }
+
+ try {
+ long l = Double.doubleToLongBits(value);
+ putValueBytes(off, l, count);
+ } catch (BoundException e) {
+ throw new Failure("Caught unexpected bound exception while putting " + count +
+ "bytes of double value at " + offsetString(off) + ": \n\t" + e);
+ }
+ }
+
+ /**
+ * Replace two bytes starting at offset off with the bytes
+ * from the specified char value.
+ *
+ * @throws BoundException if offset is out of buffer bounds
+ */
+ public void putChar(int off, char value) throws BoundException {
+ final int count = JDWP.TypeSize.CHAR;
+
+ if (count > CurrentSize - off) {
+ throw new BoundException("Unable to put " + count + " bytes of char value at " +
+ offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );
+ }
+
+ try {
+ long l = (long)value;
+ putValueBytes(off, l, count);
+ } catch (BoundException e) {
+ throw new Failure("Caught unexpected bound exception while putting " + count +
+ "bytes of char value at " + offsetString(off) + ":\n\t" + e);
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Append the specified byte to the end of this buffer.
+ */
+ public void addByte(byte value) {
+ checkSpace(1);
+
+ int where = CurrentSize;
+ CurrentSize++;
+
+ try {
+ putByte(where, value);
+ }
+ catch (BoundException e) {
+ throw new TestBug("Caught unexpected bound exception while adding one byte:\n\t"
+ + e);
+ };
+ }
+
+ /**
+ * Append specified byte value repeated count to the end of this buffer.
+ */
+ public void addBytes(byte value, int count) {
+ checkSpace(count);
+ for (int i = 0; i < count; i++) {
+ addByte(value);
+ }
+ }
+
+ /**
+ * Append the bytes from the specified byte array to the end of this buffer.
+ */
+ public void addBytes(byte[] value, int start, int len) {
+ checkSpace(len);
+
+ int where = CurrentSize;
+ CurrentSize = CurrentSize + len;
+
+ try {
+ putBytes(where, value, start, len);
+ }
+ catch (BoundException e) {
+ throw new TestBug("Caught unexpected bound exception while adding " +
+ len + " bytes:\n\t" + e);
+ };
+ }
+
+ /**
+ * Appends the count (1 - 8) less significant bytes from the
+ * specified ID value to the end of this buffer.
+ */
+ public void addID(long value, int count) {
+ if ((count <= 0) || (count > 8))
+ throw new TestBug("Illegal number bytes of ID value to add: " + count);
+
+ final int where = CurrentSize;
+ addBytes(EMPTY_BYTE, count);
+
+ try {
+ putID(where, value, count);
+ }
+ catch (BoundException e) {
+ throw new TestBug("Caught unexpected bound exception while adding " +
+ count + " bytes of ID value:\n\t" + e);
+ };
+ }
+
+ /**
+ * Append four bytes from the specified int value to the
+ * end of this buffer.
+ */
+ public void addInt(int value) {
+ final int count = JDWP.TypeSize.INT;
+ final int where = CurrentSize;
+ addBytes(EMPTY_BYTE, count);
+
+ try {
+ putInt(where, value);
+ }
+ catch (BoundException e) {
+ throw new TestBug("Caught unexpected bound exception while adding " +
+ count + " bytes of int value:\n\t" + e);
+ };
+ }
+
+ /**
+ * Append two bytes from the specified int value to the
+ * end of this buffer.
+ */
+ public void addShort(short value) {
+ final int count = JDWP.TypeSize.SHORT;
+ final int where = CurrentSize;
+ addBytes(EMPTY_BYTE, count);
+ try {
+ putShort(where, value);
+ }
+ catch (BoundException e) {
+ throw new TestBug("Caught unexpected bound exception while adding " +
+ count + " bytes of short value:\n\t" + e);
+ };
+ }
+
+ /**
+ * Appends eight bytes from the specified long
+ * value to the end of this buffer.
+ */
+ public void addLong(long value) {
+ final int count = JDWP.TypeSize.LONG;
+ final int where = CurrentSize;
+ addBytes(EMPTY_BYTE, count);
+ try {
+ putLong(where, value);
+ }
+ catch (BoundException e) {
+ throw new TestBug("Caught unexpected bound exception while adding " +
+ count + " bytes of long value:\n\t" + e);
+ };
+ }
+
+ /**
+ * Appends four bytes from the specified float
+ * value to the end of this buffer.
+ */
+ public void addFloat(float value) {
+ final int count = JDWP.TypeSize.FLOAT;
+ final int where = CurrentSize;
+ addBytes(EMPTY_BYTE, count);
+ try {
+ putFloat(where, value);
+ }
+ catch (BoundException e) {
+ throw new TestBug("Caught unexpected bound exception while adding " +
+ count + " bytes of float value:\n\t" + e);
+ };
+ }
+
+ /**
+ * Appends eight bytes from the specified double
+ * value to the end of this buffer.
+ */
+ public void addDouble(double value) {
+ final int count = JDWP.TypeSize.DOUBLE;
+ final int where = CurrentSize;
+ addBytes(EMPTY_BYTE, count);
+ try {
+ putDouble(where, value);
+ }
+ catch (BoundException e) {
+ throw new TestBug("Caught unexpected bound exception while adding " +
+ count + " bytes of double value:\n\t" + e);
+ };
+ }
+
+ /**
+ * Appends four bytes from the specified char
+ * value to the end of this buffer.
+ */
+ public void addChar(char value) {
+ final int count = JDWP.TypeSize.CHAR;
+ final int where = CurrentSize;
+ addBytes(EMPTY_BYTE, count);
+ try {
+ putChar(where, value);
+ }
+ catch (BoundException e) {
+ throw new TestBug("Caught unexpected bound exception while adding " +
+ count + " bytes of float value:\n\t" + e);
+ };
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Read a byte value from this buffer at the specified position.
+ *
+ * @throws BoundException if there are no bytes at this position
+ */
+ public byte getByte(int off) throws BoundException {
+ if (off < 0 || off >= CurrentSize) {
+ throw new BoundException("Unable to get one byte at " + offsetString(off) +
+ ": no bytes available");
+ }
+ return bytes[off];
+ }
+
+ /**
+ * Read count bytes (1-8) from this buffer at the specified
+ * position and returns a long value composed of these bytes.
+ *
+ * @throws BoundException if there are no so many bytes at this position
+ */
+ public long getID(int off, int count) throws BoundException {
+ if ((count <= 0) || (count > 8))
+ throw new TestBug("Illegal number of bytes of ID value to get: " + count);
+
+ if (count > CurrentSize - off) {
+ throw new BoundException("Unable to get " + count + " bytes of ID value at " +
+ offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );
+ }
+
+ try {
+ return getValueBytes(off, count);
+ }
+ catch (BoundException e) {
+ throw new TestBug("Caught unexpected bound exception while getting " +
+ count + " bytes of ID value at " + offsetString(off) + ":\n\t" + e);
+ }
+ }
+
+ /**
+ * Read four bytes from this buffer at the specified
+ * position and returns an integer value composed of these bytes.
+ *
+ * @throws BoundException if there are no so many bytes at this position
+ */
+ public int getInt(int off) throws BoundException {
+ final int count = JDWP.TypeSize.INT;
+ if (count > CurrentSize - off) {
+ throw new BoundException("Unable to get " + count + " bytes of int value at " +
+ offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );
+ }
+
+ try {
+ return (int)getValueBytes(off, count);
+ }
+ catch (BoundException e) {
+ throw new TestBug("Caught unexpected bound exception while getting " +
+ count + " bytes of int value at " + offsetString(off) + ":\n\t" + e);
+ }
+ }
+
+ /**
+ * Read two bytes from this buffer at the specified
+ * position and returns a short value composed of these bytes.
+ *
+ * @throws BoundException if there are no so many bytes at this position
+ */
+ public short getShort(int off) throws BoundException {
+ final int count = JDWP.TypeSize.SHORT;
+ if (count > CurrentSize - off) {
+ throw new BoundException("Unable to get " + count + " bytes of short value at " +
+ offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );
+ }
+
+ try {
+ return (short)getValueBytes(off, count);
+ }
+ catch (BoundException e) {
+ throw new TestBug("Caught unexpected bound exception while getting " +
+ count + " bytes of short value at " + offsetString(off) + ":\n\t" + e);
+ }
+ }
+
+ /**
+ * Read eight bytes from this buffer at the specified
+ * position and returns a long value composed of these bytes.
+ *
+ * @throws BoundException if there are no so many bytes at this position
+ */
+ public long getLong(int off) throws BoundException {
+ final int count = JDWP.TypeSize.LONG;
+ if (count > CurrentSize - off) {
+ throw new BoundException("Unable to get " + count + " bytes of long value at " +
+ offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );
+ }
+
+ try {
+ return getValueBytes(off, count);
+ }
+ catch (BoundException e) {
+ throw new TestBug("Caught unexpected bound exception while getting " +
+ count + " bytes of long value at " + offsetString(off) + ":\n\t" + e);
+ }
+ }
+
+ /**
+ * Read eight bytes from this buffer at the specified
+ * position and returns a double value composed of these bytes.
+ *
+ * @throws BoundException if there are no so many bytes at this position
+ */
+ public double getDouble(int off) throws BoundException {
+ final int count = JDWP.TypeSize.DOUBLE;
+ if (count > CurrentSize - off) {
+ throw new BoundException("Unable to get " + count + " bytes of double value at " +
+ offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );
+ }
+
+ try {
+ long value = getValueBytes(off, count);
+ return Double.longBitsToDouble(value);
+ }
+ catch (BoundException e) {
+ throw new TestBug("Caught unexpected bound exception while getting " +
+ count + " bytes of long value at " + offsetString(off) + ":\n\t" + e);
+ }
+ }
+
+ /**
+ * Read four bytes from this buffer at the specified
+ * position and returns a float value composed of these bytes.
+ *
+ * @throws BoundException if there are no so many bytes at this position
+ */
+ public float getFloat(int off) throws BoundException {
+ final int count = JDWP.TypeSize.FLOAT;
+ if (count > CurrentSize - off) {
+ throw new BoundException("Unable to get " + count + " bytes of float value at " +
+ offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );
+ }
+
+ try {
+ int value = (int)getValueBytes(off, count);
+ return Float.intBitsToFloat(value);
+ }
+ catch (BoundException e) {
+ throw new TestBug("Caught unexpected bound exception while getting " +
+ count + " bytes of float value at " + offsetString(off) + ":\n\t" + e);
+ }
+ }
+
+ /**
+ * Read two bytes from this buffer at the specified
+ * position and returns a char value composed of these bytes.
+ *
+ * @throws BoundException if there are no so many bytes at this position
+ */
+ public char getChar(int off) throws BoundException {
+ final int count = JDWP.TypeSize.CHAR;
+ if (count > CurrentSize - off) {
+ throw new BoundException("Unable to get " + count + " bytes of char value at " +
+ offsetString(off) + " (available bytes: " + (CurrentSize - off) + ")" );
+ }
+
+ try {
+ int value = (int)getValueBytes(off, count);
+ return (char)value;
+ }
+ catch (BoundException e) {
+ throw new TestBug("Caught unexpected bound exception while getting " +
+ count + " bytes of char value at " + offsetString(off) + ":\n\t" + e);
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Set the current parser position to 0.
+ */
+ public void resetPosition() {
+ resetPosition(0);
+ }
+
+ /**
+ * Set the current parser position to the specified value.
+ */
+ public void resetPosition(int i) {
+ parseOffset = i;
+ }
+
+ /**
+ * Return current parser position.
+ */
+ public int currentPosition() {
+ return parseOffset;
+ }
+
+ /**
+ * Return true if the parser pointer is set to the end of buffer.
+ */
+ public boolean isParsed() {
+ return (parseOffset == CurrentSize);
+ }
+
+ /**
+ * Read a byte value from this buffer at the current parser position.
+ *
+ * @throws BoundException if there are no more bytes in the buffer
+ */
+ public byte getByte() throws BoundException {
+ return getByte(parseOffset++);
+ }
+
+ /**
+ * Read count bytes (1-8) from this buffer at the current parser
+ * position and returns a long value composed of these bytes.
+ *
+ * @throws BoundException if there are no so many bytes in the buffer
+ */
+ public long getID(int count) throws BoundException {
+ long value = getID(parseOffset, count);
+ parseOffset += count;
+ return value;
+ }
+
+ /**
+ * Read four bytes from this buffer at the current parser
+ * position and returns an integer value composed of these bytes.
+ *
+ * @throws BoundException if there are no so many bytes in the buffer
+ */
+ public int getInt() throws BoundException {
+ final int count = JDWP.TypeSize.INT;
+ int value = getInt(parseOffset);
+ parseOffset += count;
+ return value;
+ }
+
+ /**
+ * Read two bytes from this buffer at the current parser
+ * position and returns a short value composed of these bytes.
+ *
+ * @throws BoundException if there are no so many bytes in the buffer
+ */
+ public short getShort() throws BoundException {
+ final int count = JDWP.TypeSize.SHORT;
+ short value = getShort(parseOffset);
+ parseOffset += count;
+ return value;
+ }
+
+ /**
+ * Read eight bytes from this buffer at the current parser
+ * position and returns a long value composed of these bytes.
+ *
+ * @throws BoundException if there are no so many bytes in the buffer
+ */
+ public long getLong() throws BoundException {
+ final int count = JDWP.TypeSize.LONG;
+ long value = getLong(parseOffset);
+ parseOffset += count;
+ return value;
+ }
+
+ /**
+ * Read eight bytes from this buffer at the current parser
+ * position and returns a double value composed of these bytes.
+ *
+ * @throws BoundException if there are no so many bytes in the buffer
+ */
+ public double getDouble() throws BoundException {
+ final int count = JDWP.TypeSize.DOUBLE;
+ double value = getDouble(parseOffset);
+ parseOffset += count;
+ return value;
+ }
+
+ /**
+ * Read four bytes from this buffer at the current parser
+ * position and returns a float value composed of these bytes.
+ *
+ * @throws BoundException if there are no so many bytes in the buffer
+ */
+ public float getFloat() throws BoundException {
+ final int count = JDWP.TypeSize.FLOAT;
+ float value = getFloat(parseOffset);
+ parseOffset += count;
+ return value;
+ }
+
+ /**
+ * Read two bytes from this buffer at the current parser
+ * position and returns a char value composed of these bytes.
+ *
+ * @throws BoundException if there are no so many bytes in the buffer
+ */
+ public char getChar() throws BoundException {
+ final int count = JDWP.TypeSize.CHAR;
+ char value = getChar(parseOffset);
+ parseOffset += count;
+ return value;
+ }
+
+ /**
+ * Remove at least first count bytes from the buffer.
+ */
+
+ public void deleteBytes(int count) {
+ int j = 0;
+ while (count < CurrentSize)
+ bytes[j++] = bytes[count++];
+
+ CurrentSize = j;
+ }
+
+ /**
+ * Clear the buffer.
+ */
+ public void resetBuffer() {
+ CurrentSize = 0;
+ }
+
+ /**
+ * Return string representation of the buffer starting at given offset.
+ */
+ public String toString(int start) {
+
+ String Result = "", HexLine = "", DisplayLine = "";
+
+ int j = 0;
+
+ for (int i = start; i < length(); i++) {
+
+ HexLine = HexLine + toHexString(bytes[i], 2) + " ";
+
+ String ch = ".";
+ if (bytes[i] >= 0x20 && bytes[i] < 0x80) {
+ try {
+ ch = new String(bytes, i, 1, "US-ASCII");
+ } catch (UnsupportedEncodingException ignore) {
+ }
+ }
+ DisplayLine = DisplayLine + ch;
+
+ if ((i == length() - 1) || (((i - start) & 0x0F) == 0x0F)) {
+ Result = Result +
+ " " +
+ toHexString(j, 4) + ": " +
+ PadR(HexLine, 48) + " " +
+ DisplayLine + "\n";
+ HexLine = "";
+ DisplayLine = "";
+ j = j + 16;
+ }
+ }
+ return Result;
+ }
+
+ /**
+ * Return string representation of the buffer.
+ */
+ public String toString() {
+ return toString(0);
+ }
+
+ /**
+ * Return string with hexadecimal representation of bytes.
+ */
+ public static String toHexString(long b, int length) {
+ return Right(Long.toHexString(b), length).replace(' ', '0');
+ }
+
+ /**
+ * Return string with hexadecimal representation of bytes.
+ */
+ public static String toHexDecString(long b, int length) {
+ return toHexString(b, length) + " (" + b + ")";
+ }
+
+ // -----
+
+ /**
+ * Return string with hexadecimal representation of offset.
+ */
+ public static String offsetString(int off) {
+ return "0x" + toHexString(off, 4);
+ }
+
+ /**
+ * Return string with hexadecimal representation of the current offset.
+ */
+ public String offsetString() {
+ return offsetString(currentPosition());
+ }
+
+ // -----
+
+ /**
+ * Check if there space for new bytes in the buffer.
+ */
+ protected void checkSpace(int space) {
+
+ int newSize = CurrentSize + space;
+
+ if (bytes.length >= newSize)
+ return;
+
+ byte[] newBytes = new byte[newSize];
+
+ for (int i = 0; i < CurrentSize; i++)
+ newBytes[i] = bytes[i];
+
+ bytes = newBytes;
+ }
+
+ /**
+ * Replace count (1 - 8) bytes starting at offset off with the less
+ * significant bytes from the specified long value.
+ *
+ * @throws BoundException if offset and count are out of buffer bounds
+ */
+ protected void putValueBytes(int off, long value, int count) throws BoundException {
+ if ((count <= 0) || (count > 8))
+ throw new TestBug("Illegal number of bytes of value to put: " + count);
+
+ if (count > CurrentSize - off) {
+ throw new BoundException("Unable to put " + count + " bytes of value at " +
+ off + " (available bytes: " + (CurrentSize - off) + ")" );
+ }
+
+ int shift = (count - 1) * 8;
+ for (int i = 0; i < count; i++) {
+ putByte(off++, (byte) ((value >>> shift) & 0xFF));
+ shift = shift - 8;
+ }
+ }
+ /**
+ * Appends the count (1 - 8) less significant bytes from the
+ * specified long value to the end of this buffer.
+ */
+ protected void addValueBytes(long value, int count) throws BoundException {
+ if ((count <= 0) || (count > 8))
+ throw new TestBug("Illegal number of bytes of value to add: " + count);
+
+ checkSpace(count);
+
+ int where = CurrentSize;
+ CurrentSize += count;
+
+ putValueBytes(where, value, count);
+ }
+
+ /**
+ * Read count bytes (1-8) from this buffer at the specified
+ * position and returns a long value composed of these bytes.
+ *
+ * @throws BoundException if there are no so many bytes in the buffer
+ */
+ public long getValueBytes(int off, int count) throws BoundException {
+ if ((count <= 0) || (count > 8))
+ throw new TestBug("Illegal number of bytes of value to get: " + count);
+
+ long l = 0;
+
+ for (int i = 0; i < count; i++) {
+ l = (l * 0x100) + ((long) getByte(off + i) & 0xFF);
+ }
+
+ return l;
+ }
+
+ /**
+ * Read count bytes (1-8) from this buffer at the current parser
+ * position and returns a long value composed of these bytes.
+ *
+ * @throws BoundException if there are no so many bytes in the buffer
+ */
+/*
+ protected long getValueBytes(int count) throws BoundException {
+ long value = getValueBytes(parseOffset);
+ parseOffset += count;
+ return value;
+ }
+ */
+
+ // ---
+
+ private static String PadL(String source, int length, String what) {
+
+ if (length <= 0)
+ return "";
+
+ if (source.length() > length)
+ return PadL("", length, "*");
+
+ while (source.length() < length)
+ source = what + source;
+
+ return source;
+ }
+
+
+ private static String PadL(String source, int length) {
+ return PadL(source, length, " ");
+ }
+
+ private static String PadR(String source, int length, String what) {
+
+ if (length <= 0)
+ return "";
+
+ if (source.length() > length)
+ return PadR("", length, "*");
+
+ while (source.length() < length)
+ source = source + what;
+
+ return source;
+ }
+
+ private static String PadR(String source, int length) {
+ return PadR(source, length, " ");
+ }
+
+ private static String Left(String source, int length) {
+
+ if (length <= 0)
+ return "";
+
+ if (length <= source.length())
+ return source.substring(0, length);
+ else
+ return PadR(source, length);
+ }
+
+ private static String Right(String source, int length) {
+
+ if (length <= 0)
+ return "";
+
+ if (length <= source.length())
+ return source.substring(source.length() - length, source.length());
+ else
+ return PadL(source, length);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/CommandPacket.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.share.jdwp;
+
+import nsk.share.*;
+
+/**
+ * This class represents a JDWP command packet.
+ */
+public class CommandPacket extends Packet {
+
+ /**
+ * Static counter for enumeration of the command packets.
+ */
+ private static int nextID = 1;
+
+ /**
+ * Return next free number for enumeration of the command packets.
+ */
+ public static int getLastID() {
+ return (nextID - 1);
+ }
+
+ /**
+ * Make JDWP command packet for specified command.
+ */
+ public CommandPacket(int fullCommand) {
+ super();
+
+ setPacketID(nextID++);
+ setFlags(JDWP.Flag.NONE);
+ setFullCommand(fullCommand);
+ }
+
+ /**
+ * Make JDWP command packet for specified command.
+ */
+ public CommandPacket(int fullCommand, int id) {
+ super();
+
+ setPacketID(id);
+ setFlags(JDWP.Flag.NONE);
+ setFullCommand(fullCommand);
+ }
+
+ /**
+ * Make command packet with data from the specified byte buffer.
+ */
+// public CommandPacket(ByteBuffer packet) {
+ public CommandPacket(Packet packet) {
+ super(packet);
+ }
+
+ /**
+ * Return full command number for this packet.
+ */
+ public int getFullCommand() {
+ int id = 0;
+
+ try {
+ id = (int) getID(FullCommandOffset, 2);
+ }
+ catch (BoundException e) {
+ throw new Failure("Caught unexpected exception while getting command number from header:\n\t"
+ + e);
+ }
+
+ return id;
+ }
+
+ /**
+ * Return short command number for this packet.
+ */
+ public byte getCommand() {
+ byte id = 0;
+
+ try {
+ id = getByte(CommandOffset);
+ }
+ catch (BoundException e) {
+ throw new Failure("Caught unexpected exception while getting command number from header:\n\t"
+ + e);
+ }
+
+ return id;
+ }
+
+ /**
+ * Return command set number for this packet.
+ */
+ public byte getCommandSet() {
+ byte id = 0;
+
+ try {
+ id = getByte(CommandSetOffset);
+ }
+ catch (BoundException e) {
+ throw new Failure("Caught unexpected exception while getting command number from header:\n\t"
+ + e);
+ }
+
+ return id;
+ }
+
+ /**
+ * Assign command number for this packet.
+ */
+ public void setFullCommand(int fullCommand) {
+ try {
+ putID(FullCommandOffset, fullCommand, 2);
+ }
+ catch (BoundException e) {
+ throw new Failure("Caught unexpected exception while setting command number into header: "
+ + e);
+ }
+ }
+
+ /**
+ * Return string representation of the command packet header.
+ */
+ public String headerToString() {
+ return super.headerToString()
+ + " " + toHexString(CommandSetOffset, 4) + " (cmd set): 0x" + toHexDecString(getCommandSet(), 2) + "\n"
+ + " " + toHexString(CommandOffset, 4) + " (command): 0x" + toHexDecString(getCommand(), 2) + "\n";
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/Debugee.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,1659 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.share.jdwp;
+
+import nsk.share.*;
+import nsk.share.jpda.*;
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * This class is used to interact with debugee VM using JDWP features.
+ * <p>
+ * This class is an mirror of debugee VM that is constructed by
+ * <code>Binder</code> and uses <code>Transport</code> object
+ * to interact with debugee VM.
+ * <p>
+ * In addition to the general abities to control of debugee VM process,
+ * provided by the base class <code>DebugeeProcess</code>, this class
+ * adds some service methods that uses JDWP protocol to simplify interaction
+ * with debugee VM (such as finding classes, setting breakpoints,
+ * handling events, and so on.).
+ *
+ * @see Binder
+ * @see Transport
+ * @see DebugeeProcess
+ */
+abstract public class Debugee extends DebugeeProcess {
+
+ /** Binder that creates this debugee. */
+ protected Binder binder = null;
+
+ protected LinkedList<EventPacket> eventQueue = new LinkedList<EventPacket>();
+
+ protected Transport transport = null;
+
+ /** Make new <code>Debugee</code> object for the given binder. */
+ protected Debugee (Binder binder) {
+ super(binder);
+ this.argumentHandler = binder.getArgumentHandler();
+ this.binder = binder;
+ prefix = "Debugee> ";
+ }
+
+ /** Return <code>Binder</code> of the debugee object. */
+ public Binder getBinder() {
+ return binder;
+ }
+
+ /** Return <code>Transport</code> of the debugee object. */
+ public Transport getTransport() {
+ return transport;
+ }
+
+ /**
+ * Prepare transport object for establishing connection.
+ * This may change connection options in <code>argumentHandler</code>.
+ *
+ * @return specific address string if listening has started or null otherwise
+ */
+ public String prepareTransport(ArgumentHandler argumentHandler) {
+ String address = null;
+ try {
+ if (argumentHandler.isSocketTransport()) {
+ SocketTransport socket_transport = new SocketTransport(log);
+ if (argumentHandler.isListeningConnector()) {
+ int port = 0;
+ if (argumentHandler.isTransportAddressDynamic()) {
+ port = socket_transport.bind(0);
+// argumentHandler.setTransportPortNumber(port);
+ } else {
+ port = argumentHandler.getTransportPortNumber();
+ socket_transport.bind(port);
+ }
+ address = argumentHandler.getTestHost() + ":" + port;
+ }
+ transport = socket_transport;
+/*
+ } else if (argumentHandler.isShmemTransport()) {
+ ShmemTransport shmem_transport = new ShmemTransport(log);
+ if (argumentHandler.isListeningConnector()) {
+ String sharedName = agrHandler.getTransportSharedName();
+ shmem_transport.bind(sharedName);
+ address = sharedName;
+ }
+ transport = shmem_transport;
+ */
+ } else {
+ throw new TestBug("Unexpected transport type: "
+ + argumentHandler.getTransportType());
+ }
+
+ } catch (IOException e) {
+ e.printStackTrace(log.getOutStream());
+ throw new Failure("Caught IOException while preparing for JDWP transport connection:\n\t"
+ + e);
+ }
+
+ return address;
+ }
+
+ /**
+ * Establish connection to debugee VM.
+ */
+ public Transport connect() {
+ if (transport == null) {
+ throw new Failure("Attemt to establish JDWP connection for not prepared transport");
+ }
+
+ try {
+ if (argumentHandler.isSocketTransport()) {
+ display("Establishing JDWP socket connection");
+ SocketTransport socket_transport = (SocketTransport)transport;
+ int transportPort = argumentHandler.getTransportPortNumber();
+ if (argumentHandler.isAttachingConnector()) {
+ String debugeeHost = argumentHandler.getDebugeeHost();
+ display("Attaching to debugee: " + debugeeHost + ":" + transportPort);
+ socket_transport.attach(debugeeHost, transportPort);
+ } else if (argumentHandler.isListeningConnector()) {
+ display("Listening from debugee");
+ socket_transport.accept();
+ } else {
+ throw new TestBug("Unexpected connector type: "
+ + argumentHandler.getConnectorType());
+ }
+/*
+ } else if (argumentHandler.isShmemTransport()) {
+ display("Establishing JDWP shared-memory connection");
+ ShmemTransport shmem_transport = (ShmemTransport)transport;
+ String sharedName = argumentHandler.getTransportSharedName();
+ if (argumentHandler.isAttachingConnector()) {
+ display("Attaching to debugee: " + sharedName);
+ shmem_transport.attach(sharedName);
+ } else if (argumentHandler.isListeningConnector()) {
+ display("Listening from debugee");
+ shmem_transport.accept();
+ } else {
+ throw new TestBug("Unexpected connector type: "
+ + argumentHandler.getConnectorType());
+ }
+ */
+ } else {
+ throw new TestBug("Unexpected transport type: "
+ + argumentHandler.getTransportType());
+ }
+
+ transport.handshake();
+
+ } catch (IOException e) {
+ e.printStackTrace(log.getOutStream());
+ throw new Failure("Caught IOException while establishing JDWP transport connection:\n\t"
+ + e);
+ }
+ return transport;
+ }
+
+ // --------------------------------------------------- //
+
+ /**
+ * Waits for VM_INIT event from debugee VM.
+ */
+ public void waitForVMInit() {
+ String eventName = "VirtualMachine.VM_START";
+ EventPacket packet = receiveEventFor(JDWP.EventKind.VM_START, eventName);
+// String versionInfo = getVersionInfo();
+// display("Target VM started:\n" + versionInfo);
+ }
+
+ /**
+ * Waits for VM_DEATH event from debugee VM.
+ */
+ public void waitForVMDeath() {
+ String eventName = "VirtualMachine.VM_DEATH";
+ EventPacket packet = receiveEventFor(JDWP.EventKind.VM_DEATH, eventName);
+ }
+
+ /**
+ * Wait for class loaded on debugee start up and return its classID.
+ * Debuggee should be initially suspended and it will also left suspended
+ * by the CLASS_PREPARE event request.
+ */
+ public long waitForClassLoaded(String className, byte suspendPolicy) {
+ // make request for CLASS_PREPARE_EVENT for this class name
+ int requestID = requestClassPrepareEvent(className, suspendPolicy);
+ // resume initially suspended debugee
+ resume();
+ // wait for CLASS_PREPARE_EVENT
+ return waitForClassPrepareEvent(requestID, className);
+ }
+
+ /**
+ * Wait for classes loaded on debugee start up and return their classIDs.
+ * Debuggee should be initially suspended and it will also left suspended
+ * by the CLASS_PREPARE event request.
+ */
+ public long[] waitForClassesLoaded(String classNames[], byte suspendPolicy) {
+ int count = classNames.length;
+
+ // make requests for CLASS_PREPARE_EVENT for these class names
+ int[] requestIDs = new int[count];
+ for (int i = 0; i < count; i++) {
+ requestIDs[i] = requestClassPrepareEvent(classNames[i], suspendPolicy);
+ }
+
+ // resume initially suspended debugee
+ resume();
+
+ return waitForClassPrepareEvents(requestIDs, classNames);
+ }
+
+ /**
+ * Wait for breakpoint reached and return threadIDs.
+ * Debuggee should be initially suspended and it will also left suspended
+ * by the BREAKPOINT event request.
+ */
+ public long waitForBreakpointReached(long classID, String methodName,
+ int line, byte suspendPolicy) {
+ // query debuggee for methodID
+ long methodID = getMethodID(classID, methodName, true);
+ // create BREAKPOINT event request
+ int requestID = requestBreakpointEvent(JDWP.TypeTag.CLASS, classID, methodID,
+ line, suspendPolicy);
+ // resume initially suspended debugee
+ resume();
+ // wait for BREAKPOINT event
+ return waitForBreakpointEvent(requestID);
+ }
+
+ // --------------------------------------------------- //
+
+ /**
+ * Wait for CLASS_PREPARE event made by given request received
+ * and return classID.
+ * Debuggee will be left suspended by the CLASS_PREPARE event.
+ */
+ public long waitForClassPrepareEvent(int requestID, String className) {
+ String error = "Error occured while waiting for CLASS_PREPARE event for class:\n\t"
+ + className;
+
+ String signature = "L" + className.replace('.', '/') + ";";
+ long classID = 0;
+
+ // wait for CLASS_PREPARE event
+ for(;;) {
+ EventPacket event = receiveEvent();
+ byte eventSuspendPolicy = 0;
+ long eventThreadID = 0;
+ try {
+ eventSuspendPolicy = event.getByte();
+ int events = event.getInt();
+ for (int i = 0; i < events; i++) {
+ // check event kind
+ byte eventKind = event.getByte();
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ complain("Unexpected VM_DEATH event received: " + eventKind
+ + " (expected: " + JDWP.EventKind.CLASS_PREPARE +")");
+ throw new Failure(error);
+ } else if (eventKind != JDWP.EventKind.CLASS_PREPARE) {
+ complain("Unexpected event kind received: " + eventKind
+ + " (expected: " + JDWP.EventKind.CLASS_PREPARE +")");
+ throw new Failure(error);
+ }
+
+ // extract CLASS_PREPARE event specific data
+ int eventRequestID = event.getInt();
+ eventThreadID = event.getObjectID();
+ byte eventRefTypeTag = event.getByte();
+ long eventClassID = event.getReferenceTypeID();
+ String eventClassSignature = event.getString();
+ int eventClassStatus = event.getInt();
+
+ // check if event was single
+ if (events > 1) {
+ complain("Not single CLASS_PREPARE event received for class:\n\t"
+ + eventClassSignature);
+ throw new Failure(error);
+ }
+
+ // check if event is for expected class
+ if (eventClassSignature.equals(signature)) {
+
+ // check if event is because of expected request
+ if (eventRequestID != requestID) {
+ complain("CLASS_PREPARE event with unexpected requestID ("
+ + eventRequestID + ") received for class:\n\t"
+ + eventClassSignature);
+ throw new Failure(error);
+ }
+
+ // remove event request
+ clearEventRequest(JDWP.EventKind.CLASS_PREPARE, requestID);
+
+ return eventClassID;
+ } else {
+ complain("Unexpected CLASS_PREPARE event received with class signature:\n"
+ + " " + eventClassSignature);
+ }
+
+ }
+
+ } catch (BoundException e) {
+ complain("Unable to extract data from event packet while waiting for CLASS_PREPARE event:\n\t"
+ + e.getMessage() + "\n" + event);
+ throw new Failure(error);
+ }
+
+ // resume debuggee according to event suspend policy
+ resumeEvent(eventSuspendPolicy, eventThreadID);
+ }
+ }
+
+ /**
+ * Wait for CLASS_PREPARE events made by given requests received
+ * and return classIDs.
+ * Debuggee will be left suspended by the CLASS_PREPARE event.
+ */
+ public long[] waitForClassPrepareEvents(int requestIDs[], String classNames[]) {
+ int count = classNames.length;
+ String error = "Error occured while waiting for " + count + " CLASS_PREPARE events";
+
+ // prepare expected class signatures
+ String[] signatures = new String[count];
+ for (int i = 0; i < count; i++) {
+ signatures[i] = "L" + classNames[i].replace('.', '/') + ";";
+ }
+
+ // clear list of classIDs
+ long[] classIDs = new long[count];
+ for (int i = 0; i < count; i++) {
+ classIDs[i] = 0;
+ }
+
+ // wait for all expected CLASS_PREPARE events
+ int received = 0;
+ for(;;) {
+ EventPacket event = receiveEvent();
+ byte eventSuspendPolicy = 0;
+ long eventThreadID = 0;
+ try {
+ eventSuspendPolicy = event.getByte();
+ int events = event.getInt();
+ for (int i = 0; i < events; i++) {
+ // check event kind
+ byte eventKind = event.getByte();
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ complain("Unexpected VM_DEATH event received: " + eventKind
+ + " (expected: " + JDWP.EventKind.CLASS_PREPARE +")");
+ throw new Failure(error);
+ } else if (eventKind != JDWP.EventKind.CLASS_PREPARE) {
+ complain("Unexpected event kind received: " + eventKind
+ + " (expected: " + JDWP.EventKind.CLASS_PREPARE +")");
+ throw new Failure(error);
+ }
+
+ // extracy CLASS_PREPARE event specific data
+ int eventRequestID = event.getInt();
+ eventThreadID = event.getObjectID();
+ byte eventRefTypeTag = event.getByte();
+ long eventClassID = event.getReferenceTypeID();
+ String eventClassSignature = event.getString();
+ int eventClassStatus = event.getInt();
+
+ // check if event was single
+ if (events > 1) {
+ complain("Not single CLASS_PREPARE event received for class:\n\t"
+ + eventClassSignature);
+ }
+
+ // find appropriate class by signature
+ boolean found = false;
+ for (int j = 0; j < count; j++) {
+ if (eventClassSignature.equals(signatures[j])) {
+ found = true;
+
+ // check if event is not duplicated
+ if (classIDs[j] != 0) {
+ complain("Extra CLASS_PREPARE event recieved for class:\n\t"
+ + eventClassSignature);
+ } else {
+ classIDs[j] = eventClassID;
+ received ++;
+ }
+
+ // check if event is because of expected request
+ if (eventRequestID != requestIDs[j]) {
+ complain("CLASS_PREPARE event with unexpected requestID ("
+ + requestIDs[j] + ") received for class:\n\t"
+ + eventClassSignature);
+ } else {
+ clearEventRequest(JDWP.EventKind.CLASS_PREPARE, requestIDs[j]);
+ }
+ }
+ }
+ if (!found) {
+ log.complain("Unexpected CLASS_PREPARE event received with class signature:\n"
+ + " " + eventClassSignature);
+ }
+ }
+ } catch (BoundException e) {
+ complain("Unable to extract data from event packet while waiting for CLASS_PREPARE event:\n\t"
+ + e.getMessage() + "\n" + event);
+ throw new Failure(error);
+ }
+
+ // if all events received return without resuming
+ if (received >= count)
+ return classIDs;
+
+ // resume debuggee according to events suspend policy
+ resumeEvent(eventSuspendPolicy, eventThreadID);
+ }
+ }
+
+ /**
+ * Wait for BREAKPOINT event made by the given request and return threadID.
+ * Debuggee will be left suspended by the BREAKPOINT event.
+ */
+ public long waitForBreakpointEvent(int requestID) {
+ String error = "Error occured while waiting for BREAKPOINT event for ";
+
+ for(;;) {
+ EventPacket event = receiveEvent();
+ byte eventSuspendPolicy = 0;
+ long eventThreadID = 0;
+ try {
+ eventSuspendPolicy = event.getByte();
+ int events = event.getInt();
+ for (int i = 0; i < events; i++) {
+ // check event kind
+ byte eventKind = event.getByte();
+ if (eventKind == JDWP.EventKind.VM_DEATH) {
+ complain("Unexpected VM_DEATH event received: " + eventKind
+ + " (expected: " + JDWP.EventKind.BREAKPOINT +")");
+ throw new Failure(error);
+ } else if (eventKind != JDWP.EventKind.BREAKPOINT) {
+ complain("Unexpected event kind received: " + eventKind
+ + " (expected: " + JDWP.EventKind.BREAKPOINT +")");
+ throw new Failure(error);
+ }
+
+ // extrack specific BREAKPOINT event data
+ int eventRequestID = event.getInt();
+ eventThreadID = event.getObjectID();
+ JDWP.Location eventLocation = event.getLocation();
+
+ if (eventRequestID == requestID) {
+ clearEventRequest(JDWP.EventKind.BREAKPOINT, requestID);
+ return eventThreadID;
+ } else {
+ complain("Unexpected BREAKPOINT event received with requestID: "
+ + eventRequestID + " (expected: " + requestID + ")");
+ }
+ }
+ } catch (BoundException e) {
+ complain("Unable to extract data from event packet while waiting for BREAKPOINT event:\n\t"
+ + e.getMessage() + "\n" + event);
+ throw new Failure(error);
+ }
+
+ resumeEvent(eventSuspendPolicy, eventThreadID);
+ }
+ }
+
+ /**
+ * Resume debuggee according given event suspend policy.
+ */
+ public void resumeEvent(byte suspendPolicy, long threadID) {
+ if (suspendPolicy == JDWP.SuspendPolicy.NONE) {
+ // do nothing
+ } else if (suspendPolicy == JDWP.SuspendPolicy.EVENT_THREAD) {
+ resumeThread(threadID);
+ } else if (suspendPolicy == JDWP.SuspendPolicy.ALL) {
+ resume();
+ } else {
+ throw new Failure("Unexpected event suspend policy while resuming debuggee: "
+ + suspendPolicy);
+ }
+ }
+
+ // --------------------------------------------------- //
+
+ /**
+ * Query target VM for version info.
+ */
+ public String getVersionInfo() {
+ String commandName = "VirtualMachine.Version";
+ CommandPacket command =
+ new CommandPacket(JDWP.Command.VirtualMachine.Version);
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+
+ try {
+ String description = reply.getString();
+ int jdwpMajor = reply.getInt();
+ int jdwpMinor = reply.getInt();
+ String vmVersion = reply.getString();
+ String vmName = reply.getString();
+ return description;
+ } catch (BoundException e) {
+ complain("Unable to parse reply packet for " + commandName + " command:\n\t"
+ + e.getMessage());
+ display("Reply packet:\n" + reply);
+ throw new Failure("Error occured while getting JDWP and VM version info");
+ }
+ }
+
+ /**
+ * Query target VM about VM dependent ID sizes.
+ */
+ public void queryForIDSizes() {
+ String commandName = "VirtualMachine.IDSizes";
+ CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.IDSizes);
+ ReplyPacket reply = receiveReplyFor(command);
+ try {
+ reply.resetPosition();
+ JDWP.TypeSize.FIELD_ID = reply.getInt();
+ JDWP.TypeSize.METHOD_ID = reply.getInt();
+ JDWP.TypeSize.OBJECT_ID = reply.getInt();
+ JDWP.TypeSize.REFERENCE_TYPE_ID = reply.getInt();
+ JDWP.TypeSize.FRAME_ID = reply.getInt();
+ } catch (BoundException e) {
+ complain("Unable to parse reply packet for " + commandName + " command:\n\t"
+ + e.getMessage());
+ display("Reply packet:\n" + reply);
+ throw new Failure("Error occured while getting VM dependent ID sizes");
+ }
+ JDWP.TypeSize.CalculateSizes();
+ }
+
+ // --------------------------------------------------- //
+
+ /**
+ * Suspend the debugee VM by sending VirtualMachine.Suspend command.
+ */
+ public void suspend() {
+ String commandName = "VirtualMachine.Suspend";
+ CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.Suspend);
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+ }
+
+ /**
+ * Resume the debugee VM by sending VirtualMachine.Resume command.
+ */
+ public void resume() {
+ String commandName = "VirtualMachine.Resume";
+ CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.Resume);
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+ }
+
+ /**
+ * Dispose the debugee VM by sending VirtualMachine.Dispose command.
+ */
+ public void dispose() {
+ String commandName = "VirtualMachine.Dispose";
+ CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.Dispose);
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+ }
+
+ // --------------------------------------------------- //
+
+ /**
+ * Sends JDWP command packet.
+ */
+ public void sendCommand(CommandPacket packet, String commandName) {
+ try {
+ transport.write(packet);
+ } catch (IOException e) {
+ e.printStackTrace(log.getOutStream());
+ complain("Caught IOException while sending command packet for "
+ + commandName + ":\n\t" + e);
+ display("Command packet:\n" + packet);
+ throw new Failure("Error occured while sending command: " + commandName);
+ }
+ }
+
+ /**
+ * Receive next JDWP packet.
+ */
+/*
+ public Packet receivePacket() {
+ try {
+ ReplyPacket packet = new ReplyPacket();
+ transport.read(packet);
+ return packet;
+ } catch (IOException e) {
+ e.printStackTrace(log.getOutStream());
+ throw new Failure("Caught IOException while receiving reply packet:\n\t" + e);
+ }
+ }
+ */
+ /**
+ * Receive next JDWP reply packet.
+ */
+ public ReplyPacket receiveReply() {
+ try {
+ for (;;) {
+ Packet packet = new Packet();
+ transport.read(packet);
+
+ if (packet.getFlags() == JDWP.Flag.REPLY_PACKET) {
+ ReplyPacket reply = new ReplyPacket(packet);
+ return reply;
+ }
+
+ EventPacket event = new EventPacket(packet);
+ display("Placing received event packet into queue");
+ eventQueue.add(event);
+ }
+ } catch (IOException e) {
+ e.printStackTrace(log.getOutStream());
+ throw new Failure("Caught IOException while receiving reply packet:\n\t" + e);
+ }
+ }
+
+ /**
+ * Get next JDWP event packet by reading from transport or getting stored
+ * event in the event queue.
+ */
+ public EventPacket getEventPacket() throws IOException {
+ // check events queue first
+ if (!eventQueue.isEmpty()) {
+ EventPacket event = (EventPacket)(eventQueue.removeFirst());
+ return event;
+ }
+
+ // read from transport
+ Packet packet = new Packet();
+ transport.read(packet);
+
+ EventPacket event = new EventPacket(packet);
+ return event;
+ }
+
+ /**
+ * Get next JDWP event packet by reading from transport for specified timeout
+ * or getting stored event in the event queue.
+ */
+ public EventPacket getEventPacket(long timeout) throws IOException {
+ transport.setReadTimeout(timeout);
+ return getEventPacket();
+ }
+
+ /**
+ * Receive next JDWP event packet.
+ */
+ public EventPacket receiveEvent() {
+ EventPacket packet = null;
+ try {
+ packet = getEventPacket();
+ } catch (IOException e) {
+ e.printStackTrace(log.getOutStream());
+ throw new Failure("Caught IOException while receiving event packet:\n\t" + e);
+ }
+
+ if (packet.getFlags() == JDWP.Flag.REPLY_PACKET) {
+ ReplyPacket reply = new ReplyPacket(packet);
+ log.complain("Unexpected reply packet received with id: "
+ + reply.getPacketID());
+ log.display("Reply packet:\n" + reply);
+ throw new Failure("Unexpected reply packet received instead of event packet");
+ }
+
+ return packet;
+ }
+
+ /**
+ * Send specified command packet, receive and check reply packet.
+ *
+ * @throws Failure if exception caught in sending and reading packets
+ */
+ public ReplyPacket receiveReplyFor(CommandPacket command) {
+ return receiveReplyFor(command, Packet.toHexString(command.getCommand(), 4));
+ }
+
+ /**
+ * Send specified command packet, receive and check reply packet.
+ *
+ * @throws Failure if exception caught in sending and reading packets
+ */
+ public ReplyPacket receiveReplyFor(CommandPacket command, String commandName) {
+ ReplyPacket reply = null;
+ sendCommand(command, commandName);
+ reply = receiveReply();
+ try {
+ reply.checkHeader(command.getPacketID());
+ } catch (BoundException e) {
+ complain("Wrong header of reply packet for command "+ commandName + ":\n\t"
+ + e.getMessage());
+ display("Reply packet:\n" + reply);
+ throw new Failure("Wrong reply packet received for command: " + commandName);
+ }
+ return reply;
+ }
+
+ /**
+ * Receive and check event packet for specified event kind.
+ *
+ * @throws Failure if exception caught in sending and reading packets
+ */
+ public EventPacket receiveEventFor(int eventKind, String eventName) {
+ EventPacket event = null;
+ event = receiveEvent();
+ try {
+ event.checkHeader(eventKind);
+ } catch (BoundException e) {
+ complain("Wrong header of event packet for expected "+ eventName + " event:\n\t"
+ + e.getMessage());
+ display("Event packet:\n" + event);
+ throw new Failure("Wrong event packet received for expected event: " + eventName);
+ }
+ return event;
+ }
+
+ // --------------------------------------------------- //
+
+ /**
+ * Check common VM capability.
+ */
+ public boolean getCapability(int capability, String name) {
+ String commandName = "VirtualMachine.Capabilities";
+
+ int count = JDWP.Capability.CAN_GET_MONITOR_INFO + 1;
+ if (capability < 0 || capability >= count) {
+ throw new TestBug("Illegal capability number (" + capability
+ + ") while checking for VM capability: " + name);
+ }
+
+ CommandPacket command =
+ new CommandPacket(JDWP.Command.VirtualMachine.Capabilities);
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+
+ try {
+ reply.resetPosition();
+
+ for (int i = 0; i < count; i++) {
+ byte value = reply.getByte();
+ if (i == capability) {
+ return (value != 0);
+ }
+ }
+
+ } catch (BoundException e) {
+ complain("Unable to parse reply packet for " + commandName + " command:\n\t"
+ + e.getMessage());
+ display("Reply packet:\n" + reply);
+ throw new Failure("Error occured while getting VM capability: "
+ + name);
+ }
+
+ throw new TestBug("Illegal capability number (" + capability
+ + ") while checking for VM capability: " + name);
+ }
+
+ /**
+ * Check new VM capability (since JDWP version 1.4).
+ */
+ public boolean getNewCapability(int capability, String name) {
+ String commandName = "VirtualMachine.CapabilitiesNew";
+ int count = JDWP.Capability.CAN_SET_DEFAULT_STRATUM + 1;
+
+ if (capability < 0 || capability >= count) {
+ throw new TestBug("Illegal capability number (" + capability
+ + ") while checking for VM new capability: " + name);
+ }
+
+ CommandPacket command =
+ new CommandPacket(JDWP.Command.VirtualMachine.CapabilitiesNew);
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+
+ try {
+ reply.resetPosition();
+
+ for (int i = 0; i < count; i++) {
+ byte value = reply.getByte();
+ if (i == capability) {
+ return (value != 0);
+ }
+ }
+ } catch (BoundException e) {
+ complain("Unable to parse reply packet for " + commandName + " command:\n\t"
+ + e.getMessage());
+ display("Reply packet:\n" + reply);
+ throw new Failure("Error occured while getting VM new capability: "
+ + name);
+ }
+
+ throw new TestBug("Illegal capability number (" + capability
+ + ") while checking for VM new capability: " + name);
+ }
+
+ // --------------------------------------------------- //
+
+ /**
+ * Return ReferenceTypeID for requested class by given signature.
+ */
+ public long getReferenceTypeID(String classSignature) {
+ String commandName = "VirtualMachine.ClassesBySignature";
+ CommandPacket command =
+ new CommandPacket(JDWP.Command.VirtualMachine.ClassesBySignature);
+ command.addString(classSignature);
+ command.setLength();
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+
+ long typeID = 0;
+
+ try {
+ reply.resetPosition();
+
+ int classes = reply.getInt();
+ for (int i = 0; i < classes; i++) {
+ byte refTypeTag = reply.getByte();
+ typeID = reply.getReferenceTypeID();
+ int status = reply.getInt();
+ }
+
+ if (classes < 0) {
+ throw new Failure("Negative number (" + classes
+ + ") of referenceTypeIDs received for signature: "
+ + classSignature);
+ }
+
+ if (classes == 0) {
+ throw new Failure("No any referenceTypeID received for signature: "
+ + classSignature);
+ }
+
+ if (classes > 1) {
+ throw new Failure("Too many (" + classes
+ + ") referenceTypeIDs received for signature: "
+ + classSignature);
+ }
+
+ } catch (BoundException e) {
+ complain("Unable to parse reply packet for " + commandName + " command:\n\t"
+ + e.getMessage());
+ display("Reply packet:\n" + reply);
+ throw new Failure("Error occured while getting referenceTypeID for signature: "
+ + classSignature);
+ }
+
+ return typeID;
+ }
+
+ // --------------------------------------------------- //
+
+
+ /**
+ * Get list of IDs of supertypes (interfaces and classes) for given class.
+ */
+ public long[] getSupertypes(long classID, boolean declared) {
+ Vector<Long> vector = new Vector<Long>();
+ addSupertypes(classID, vector, null, null, false, declared);
+ return makeListOfLongValues(vector);
+ }
+
+ /**
+ * Get list of IDs of superclasses for given class.
+ */
+ public long[] getSuperclasses(long classID, boolean declared) {
+ Vector<Long> vector = new Vector<Long>();
+ addSupertypes(classID, null, null, vector, false, declared);
+ return makeListOfLongValues(vector);
+ }
+
+ /**
+ * Get list of IDs of implemented interfaces for given class.
+ */
+ public long[] getImplementedInterfaces(long classID, boolean declared) {
+ Vector<Long> vector = new Vector<Long>();
+ addSupertypes(classID, null, vector, null, false, declared);
+ return makeListOfLongValues(vector);
+ }
+
+ /**
+ * Get list of IDs of superinterfaces for given interface.
+ */
+ public long[] getSuperinterfaces(long interfaceID, boolean declared) {
+ Vector<Long> vector = new Vector<Long>();
+ addSupertypes(interfaceID, null, vector, null, true, declared);
+ return makeListOfLongValues(vector);
+ }
+
+ // --------------------------------------------------- //
+
+ /**
+ * Get list of IDs of methods of given class.
+ */
+ public long[] getMethodIDs(long classID, boolean declared) {
+ Vector<Long> list = new Vector<Long>();
+ addMethods(classID, list, null, null, null, false, declared);
+ return makeListOfLongValues(list);
+ }
+
+ /**
+ * Get list of names of methods of given class.
+ */
+ public String[] getMethodNames(long classID, boolean declared) {
+ Vector<String> list = new Vector<String>();
+ addMethods(classID, null, list, null, null, false, declared);
+ return makeListOfStringValues(list);
+ }
+
+ /**
+ * Get list of signatures of methods of given class.
+ */
+ public String[] getMethodSignatures(long classID, boolean declared) {
+ Vector<String> list = new Vector<String>();
+ addMethods(classID, null, null, list, null, false, declared);
+ return makeListOfStringValues(list);
+ }
+
+ /**
+ * Get ID of a method of given class by name.
+ */
+ public long getMethodID(long classID, String name, boolean declared) {
+ Vector<Long> IDs = new Vector<Long>();
+ Vector<String> names = new Vector<String>();
+ addMethods(classID, IDs, names, null, null, false, declared);
+ int count = names.size();
+ for (int i = 0; i < count; i++) {
+ if (name.equals(names.elementAt(i))) {
+ return (IDs.elementAt(i)).longValue();
+ }
+ }
+ throw new Failure("Method \"" + name + "\" not found for classID: " + classID);
+ }
+
+ // --------------------------------------------------- //
+
+ /**
+ * Get list of IDs of static fields of given class.
+ */
+ public long[] getClassFieldIDs(long classID, boolean declared) {
+ Vector<Long> list = new Vector<Long>();
+ addFields(classID, list, null, null, null, false, declared);
+ return makeListOfLongValues(list);
+ }
+
+ /**
+ * Get list of names of static fields of given class.
+ */
+ public String[] getClassFieldNames(long classID, boolean declared) {
+ Vector<String> list = new Vector<String>();
+ addFields(classID, null, list, null, null, false, declared);
+ return makeListOfStringValues(list);
+ }
+
+ /**
+ * Get list of signatures of static fields of given class.
+ */
+ public String[] getClassFieldSignatures(long classID, boolean declared) {
+ Vector<String> list = new Vector<String>();
+ addFields(classID, null, null, list, null, false, declared);
+ return makeListOfStringValues(list);
+ }
+
+ /**
+ * Get ID of a static field of given class by name.
+ */
+ public long getClassFieldID(long classID, String name, boolean declared) {
+ Vector<Long> IDs = new Vector<Long>();
+ Vector<String> names = new Vector<String>();
+ addFields(classID, IDs, names, null, null, false, declared);
+ int count = names.size();
+ for (int i = 0; i < count; i++) {
+ if (name.equals((String)names.elementAt(i))) {
+ return ((Long)IDs.elementAt(i)).longValue();
+ }
+ }
+ throw new Failure("Static field \"" + name + "\" not found for classID: " + classID);
+ }
+
+ // --------------------------------------------------- //
+
+ /**
+ * Get value of a static field of given class.
+ */
+ public JDWP.Value getStaticFieldValue(long typeID, long fieldID) {
+ String commandName = "ReferenceType.GetValues";
+ CommandPacket command =
+ new CommandPacket(JDWP.Command.ReferenceType.GetValues);
+ command.addReferenceTypeID(typeID);
+ command.addInt(1);
+ command.addFieldID(fieldID);
+
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+ JDWP.Value value = null;
+
+ try {
+ reply.resetPosition();
+
+ int count = reply.getInt();
+ if (count < 1) {
+ throw new Failure("No values returned for static fieldID: " + fieldID);
+ }
+ value = reply.getValue();
+
+ } catch (BoundException e) {
+ complain("Unable to parse reply packet for " + commandName +" command:\n\t"
+ + e.getMessage());
+ display("Reply packet:\n" + reply);
+ throw new Failure("Error occured while getting value of static field: " +
+ + fieldID);
+ }
+ return value;
+ }
+
+ /**
+ * Get value of particular type from a static field of given class.
+ */
+ public JDWP.Value getStaticFieldValue(long typeID, String fieldName, byte tag) {
+ long fieldID = getClassFieldID(typeID, fieldName, true);
+ JDWP.Value value = getStaticFieldValue(typeID, fieldID);
+
+ if (value.getTag() != tag) {
+ complain("unexpedted value tag returned from debuggee: " + value.getTag()
+ + " (expected: " + tag + ")");
+ throw new Failure("Error occured while getting value from static field: "
+ + fieldName);
+ }
+ return value;
+ }
+
+ /**
+ * Set value of a static field of given class.
+ */
+ public void setStaticFieldValue(long typeID, long fieldID, JDWP.Value value) {
+ String commandName = "ClassType.SetValues";
+ CommandPacket command =
+ new CommandPacket(JDWP.Command.ClassType.SetValues);
+ command.addReferenceTypeID(typeID);
+ command.addInt(1);
+ command.addFieldID(fieldID);
+ command.addUntaggedValue(value, value.getTag());
+
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+ }
+
+ /**
+ * Get value of a field of given object.
+ */
+ public JDWP.Value getObjectFieldValue(long objectID, long fieldID) {
+ String commandName = "ObjectReference.GetValues";
+ CommandPacket command =
+ new CommandPacket(JDWP.Command.ObjectReference.GetValues);
+ command.addObjectID(objectID);
+ command.addInt(1);
+ command.addFieldID(fieldID);
+
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+ JDWP.Value value = null;
+
+ try {
+ reply.resetPosition();
+
+ int count = reply.getInt();
+ if (count < 1) {
+ throw new Failure("No values returned for object fieldID: " + fieldID);
+ }
+ value = reply.getValue();
+
+ } catch (BoundException e) {
+ complain("Unable to parse reply packet for " + commandName + " command:\n\t"
+ + e.getMessage());
+ display("Reply packet:\n" + reply);
+ throw new Failure("Error occured while getting value of object field: " +
+ + fieldID);
+ }
+ return value;
+ }
+
+ /**
+ * Set value of a static field of given class.
+ */
+ public void setObjectFieldValue(long objectID, long fieldID, JDWP.Value value) {
+ String commandName = "ObjectReference.SetValues";
+ CommandPacket command =
+ new CommandPacket(JDWP.Command.ObjectReference.SetValues);
+ command.addObjectID(objectID);
+ command.addInt(1);
+ command.addFieldID(fieldID);
+ command.addUntaggedValue(value, value.getTag());
+
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+ }
+
+ // --------------------------------------------------- //
+
+ /**
+ * Find threadID for given thread name among all active threads.
+ */
+ public long getThreadID(String name) {
+ // request list of all threadIDs
+ int threads = 0;
+ long threadIDs[] = null;
+ {
+ String commandName = "VirtualMachine.AllThreads";
+ CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.AllThreads);
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+ reply.resetPosition();
+ try {
+ threads = reply.getInt();
+ threadIDs = new long[threads];
+
+ for (int i = 0; i < threads; i++) {
+ threadIDs[i] = reply.getObjectID();
+ }
+ } catch (BoundException e) {
+ complain("Unable to parse reply packet for " + commandName + " command:\n\t"
+ + e.getMessage());
+ display("Reply packet:\n" + reply);
+ throw new Failure("Error occured while getting threadID for thread name: "
+ + name);
+ }
+ }
+
+ // request name for each threadID
+ for (int i = 0; i < threads; i++) {
+ String commandName = "ThreadReference.Name";
+ CommandPacket command = new CommandPacket(JDWP.Command.ThreadReference.Name);
+ command.addObjectID(threadIDs[i]);
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+ try {
+ reply.resetPosition();
+ String threadName = reply.getString();
+ if (threadName.equals(name)) {
+ return threadIDs[i];
+ }
+ } catch (BoundException e) {
+ complain("Unable to parse reply packet for " + commandName + " command:\n\t"
+ + e.getMessage());
+ display("Reply packet:\n" + reply);
+ throw new Failure("Error occured while getting name for threadID: "
+ + threadIDs[i]);
+ }
+ }
+
+ throw new Failure("No threadID found for thread name: " + name);
+ }
+
+ /**
+ * Return thread name for the given threadID.
+ */
+ public String getThreadName(long threadID) {
+ String commandName = "ThreadReference.Name";
+ CommandPacket command = new CommandPacket(JDWP.Command.ThreadReference.Name);
+ command.addObjectID(threadID);
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+ try {
+ reply.resetPosition();
+ String threadName = reply.getString();
+ return threadName;
+ } catch (BoundException e) {
+ complain("Unable to parse reply packet for " + commandName + " command:\n\t"
+ + e.getMessage());
+ display("Reply packet:\n" + reply);
+ throw new Failure("Error occured while getting name for threadID: "
+ + threadID);
+ }
+ }
+
+ /**
+ * Suspend thread for the given threadID.
+ */
+ public void suspendThread(long threadID) {
+ String commandName = "ThreadReference.Suspend";
+ CommandPacket command = new CommandPacket(JDWP.Command.ThreadReference.Suspend);
+ command.addObjectID(threadID);
+
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+ }
+
+ /**
+ * Resume thread for the given threadID.
+ */
+ public void resumeThread(long threadID) {
+ String commandName = "ThreadReference.resume";
+ CommandPacket command = new CommandPacket(JDWP.Command.ThreadReference.Resume);
+ command.addObjectID(threadID);
+
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+ }
+
+ /**
+ * Return frameID for the current frame of the thread.
+ * Thread must be suspended.
+ */
+ public long getCurrentFrameID(long threadID) {
+ String commandName = "ThreadReference.Frames";
+ CommandPacket command = new CommandPacket(JDWP.Command.ThreadReference.Frames);
+ command.addObjectID(threadID); // threadID
+ command.addInt(0); // startFrame
+ command.addInt(1); // length
+
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+ try {
+ reply.resetPosition();
+ int frames = reply.getInt();
+ if (frames != 1) {
+ throw new Failure("Not only one current frame returned for threadID "
+ + threadID + ": " + frames);
+ }
+ long frameID = reply.getFrameID();
+ JDWP.Location location = reply.getLocation();
+ return frameID;
+ } catch (BoundException e) {
+ complain("Unable to parse reply packet for " + commandName + " command:\n\t"
+ + e.getMessage());
+ display("Reply packet:\n" + reply);
+ throw new Failure("Error occured while getting current frame for threadID: "
+ + threadID);
+ }
+ }
+
+ // --------------------------------------------------- //
+
+ /**
+ * Find line number for the given location from the method line table.
+ * If <code>approximate</code> is <it>true</i> the found line should begin
+ * with code index of the given location. Otherwise, the found line will
+ * just cover code index of the given location.
+ */
+ public int getLineNumber(JDWP.Location location, boolean approximate) {
+ String commandName = "Method.LineTable";
+ CommandPacket command = new CommandPacket(JDWP.Command.Method.LineTable);
+ command.addReferenceTypeID(location.getClassID());
+ command.addMethodID(location.getMethodID());
+ long index = location.getIndex();
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+ String msg = "Error occured while getting line number for location: " + location;
+ try {
+ reply.resetPosition();
+ long start = reply.getLong();
+ if (index < start) {
+ complain("Location index (" + index
+ + ") is less than start method index (" + start);
+ throw new Failure(msg);
+ }
+ long end = reply.getLong();
+ if (index > end) {
+ complain("Location index (" + index
+ + ") is greater than end method index (" + end);
+ throw new Failure(msg);
+ }
+ int lines = reply.getInt();
+ if (!approximate) {
+ for (int i = 0; i < lines; i++) {
+ long lineCodeIndex = reply.getLong();
+ int lineNumber = reply.getInt();
+ if (lineCodeIndex == index) {
+ return lineNumber;
+ }
+ }
+ throw new Failure("No exact line number exactly for location: " + location);
+ } else {
+ int prevLine = -1;
+ for (int i = 0; i < lines; i++) {
+ long lineCodeIndex = reply.getLong();
+ int lineNumber = reply.getInt();
+ if (lineCodeIndex == index) {
+ return lineNumber;
+ } else if (lineCodeIndex > index) {
+ break;
+ }
+ prevLine = lineNumber;
+ }
+ if (prevLine < 0)
+ throw new Failure("No approximate line number found for location: " + location);
+ return prevLine;
+ }
+ } catch (BoundException e) {
+ complain("Unable to parse reply packet for " + commandName + " command:\n\t"
+ + e.getMessage());
+ display("Reply packet:\n" + reply);
+ throw new Failure(msg);
+ }
+ }
+
+ /**
+ * Find line index for the given line number from the method line table.
+ */
+ public long getCodeIndex(long classID, long methodID, int lineNumber) {
+ String commandName = "Method.LineTable";
+ CommandPacket command = new CommandPacket(JDWP.Command.Method.LineTable);
+ command.addReferenceTypeID(classID);
+ command.addMethodID(methodID);
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+ String msg = "Error occured while getting code index for line number: " + lineNumber;
+ try {
+ reply.resetPosition();
+ long start = reply.getLong();
+ long end = reply.getLong();
+ int lines = reply.getInt();
+ for (int i = 0; i < lines; i++) {
+ long lineCodeIndex = reply.getLong();
+ int line = reply.getInt();
+ if (lineNumber == line) {
+ return lineCodeIndex;
+ }
+ }
+ } catch (BoundException e) {
+ complain("Unable to parse reply packet for " + commandName + " command:\n\t"
+ + e.getMessage());
+ display("Reply packet:\n" + reply);
+ throw new Failure(msg);
+ }
+
+ throw new Failure("No code index found for line number: " + lineNumber);
+ }
+
+ // --------------------------------------------------- //
+
+ /**
+ * Make the specified event request into debuggee.
+ */
+ public int requestEvent(CommandPacket requestCommand, String name) {
+ String commandName = "EventRequest.Set";
+ ReplyPacket reply = receiveReplyFor(requestCommand, name);
+
+ try {
+ reply.resetPosition();
+
+ int requestID = reply.getInt();
+ return requestID;
+
+ } catch (BoundException e) {
+ complain("Unable to parse reply packet for " + commandName + " command:\n\t"
+ + e.getMessage());
+ display("Request command packet:\n" + requestCommand);
+ display("Reply packet:\n" + reply);
+ throw new Failure("Error occured while making event request: " + name);
+ }
+ }
+
+ /**
+ * Remove existing event request from debuggee.
+ */
+ public void clearEventRequest(byte eventKind, int requestID) {
+ String commandName = "EventRequest.Clear";
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear);
+ command.addByte(eventKind);
+ command.addInt(requestID);
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+ }
+
+ /**
+ * Make request for CLASS_PREPARE event for specified class into debuggee.
+ */
+ public int requestClassPrepareEvent(String className, byte suspendPolicy) {
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set);
+ command.addByte(JDWP.EventKind.CLASS_PREPARE);
+ command.addByte(suspendPolicy);
+ command.addInt(1);
+ command.addByte(JDWP.EventModifierKind.CLASS_MATCH);
+ command.addString(className);
+
+ return requestEvent(command, "CLASS_PREPARE");
+ }
+
+ /**
+ * Make request for BREAKPOINT event for the specified location into debuggee.
+ */
+ public int requestBreakpointEvent(JDWP.Location location, byte suspendPolicy) {
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set);
+ command.addByte(JDWP.EventKind.BREAKPOINT);
+ command.addByte(suspendPolicy);
+ command.addInt(1);
+ command.addByte(JDWP.EventModifierKind.LOCATION_ONLY);
+ command.addLocation(location);
+ return requestEvent(command, "BREAKPOINT");
+ }
+
+ /**
+ * Make request for BREAKPOINT event for the specified line of the given method.
+ */
+ public int requestBreakpointEvent(byte typeTag, long classID, long methodID,
+ int lineNumber, byte suspendPolicy) {
+ long codeIndex = getCodeIndex(classID, methodID, lineNumber);
+ JDWP.Location location = new JDWP.Location(typeTag, classID, methodID, codeIndex);
+ return requestBreakpointEvent(location, suspendPolicy);
+ }
+
+ /**
+ * Remove all existing BREAKPOINT event requests from debuggee.
+ */
+ public void clearAllBreakpoints() {
+ String commandName = "EventRequest.ClearAllBreakpoints";
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.ClearAllBreakpoints);
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+ }
+
+ // --------------------------------------------------- //
+
+ /**
+ * Add IDs of supertypes (interfaces and classes) for given class to the lists.
+ */
+ private void addSupertypes(long referenceTypeID, Vector<Long> supertypes,
+ Vector<Long> interfaces, Vector<Long> superclasses,
+ boolean interfaceOnly, boolean declared) {
+
+ if (supertypes != null || interfaces != null) {
+
+ // obtain list of direct implemented interfaces
+ String commandName = "ReferenceType.Interfaces";
+ CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.Interfaces);
+ command.addReferenceTypeID(referenceTypeID);
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+
+ try {
+ reply.resetPosition();
+
+ int count = reply.getInt();
+ if (count < 0) {
+ throw new Failure("Negative number (" + count
+ + ") of declared interfaces received for referenceTypeID: "
+ + referenceTypeID);
+ }
+
+ for (int i = 0; i < count; i++) {
+ long typeID = reply.getReferenceTypeID();
+ if (!declared) {
+ addSupertypes(typeID, supertypes, interfaces, superclasses,
+ true, declared);
+ }
+ Long value = new Long(typeID);
+ if (supertypes != null) {
+ supertypes.add(value);
+ }
+ if (interfaces != null) {
+ interfaces.add(value);
+ }
+ }
+
+ } catch (BoundException e) {
+ complain("Unable to parse reply packet for " + commandName + " command:\n\t"
+ + e.getMessage());
+ display("Reply packet:\n" + reply);
+ throw new Failure("Error occured while getting interfeceIDs for referenceTypeID: " +
+ + referenceTypeID);
+ }
+
+ }
+
+ if (!interfaceOnly) {
+
+ String commandName = "ClassType.Superclasses";
+ CommandPacket command = new CommandPacket(JDWP.Command.ClassType.Superclass);
+ command.addReferenceTypeID(referenceTypeID);
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+
+ try {
+ reply.resetPosition();
+
+ long typeID = reply.getReferenceTypeID();
+ if (typeID != 0) {
+ if (!declared) {
+ addSupertypes(typeID, supertypes, interfaces, superclasses,
+ false, declared);
+ }
+ Long value = new Long(typeID);
+ if (supertypes != null) {
+ supertypes.add(value);
+ }
+ if (superclasses != null) {
+ superclasses.add(value);
+ }
+ }
+ } catch (BoundException e) {
+ complain("Unable to parse reply packet for " + commandName + " command:\n\t"
+ + e.getMessage());
+ display("Reply packet:\n" + reply);
+ throw new Failure("Error occured while getting superclass ID for classID: " +
+ + referenceTypeID);
+ }
+
+ }
+ }
+
+ /**
+ * Add attributes of fields of given class to the lists.
+ */
+ private void addFields(long referenceTypeID, Vector<Long> IDs, Vector<String> names,
+ Vector<String> signatures, Vector<Integer> modifiers,
+ boolean interfaceOnly, boolean declared) {
+
+ if (!declared) {
+ Vector<Long> supertypes = new Vector<Long>();
+ addSupertypes(referenceTypeID, supertypes, null, null, interfaceOnly, declared);
+ int count = supertypes.size();
+ for (int i = 0; i < count; i++) {
+ long typeID = (supertypes.elementAt(i)).longValue();
+ addFields(typeID, IDs, names, signatures, modifiers,
+ interfaceOnly, declared);
+ }
+ }
+
+ String commandName = "ReferenceType.Fields";
+ CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.Fields);
+ command.addReferenceTypeID(referenceTypeID);
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+
+ try {
+ reply.resetPosition();
+
+ int count = reply.getInt();
+ if (count < 0) {
+ throw new Failure("Negative number (" + count
+ + ") of declared fields received for referenceTypeID: "
+ + referenceTypeID);
+ }
+
+ for (int i = 0; i < count; i++) {
+ long id = reply.getFieldID();
+ String name = reply.getString();
+ String signature = reply.getString();
+ int modBits = reply.getInt();
+
+ if (IDs != null)
+ IDs.add(new Long(id));
+ if (names != null)
+ names.add(name);
+ if (signatures != null)
+ signatures.add(signature);
+ if (modifiers != null)
+ modifiers.add(new Integer(modBits));
+ }
+
+ } catch (BoundException e) {
+ complain("Unable to parse reply packet for " + commandName + " command:\n\t"
+ + e.getMessage());
+ display("Reply packet:\n" + reply);
+ throw new Failure("Error occured while getting fieldIDs for referenceTypeID: " +
+ + referenceTypeID);
+ }
+ }
+
+ /**
+ * Add attributes of methods of given class to the lists.
+ */
+ private void addMethods(long referenceTypeID, Vector<Long> IDs, Vector<String> names,
+ Vector<String> signatures, Vector<Integer> modifiers,
+ boolean interfaceOnly, boolean declared) {
+
+ if (!declared) {
+ Vector<Long> supertypes = new Vector<Long>();
+ addSupertypes(referenceTypeID, supertypes, null, null, interfaceOnly, declared);
+ int count = supertypes.size();
+ for (int i = 0; i < count; i++) {
+ long typeID = (supertypes.elementAt(i)).longValue();
+ addMethods(typeID, IDs, names, signatures, modifiers,
+ interfaceOnly, declared);
+ }
+ }
+
+ String commandName = "ReferenceType.Methods";
+ CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.Methods);
+ command.addReferenceTypeID(referenceTypeID);
+ ReplyPacket reply = receiveReplyFor(command, commandName);
+
+ try {
+ reply.resetPosition();
+
+ int count = reply.getInt();
+ if (count < 0) {
+ throw new Failure("Negative number (" + count
+ + ") of declared fields received for referenceTypeID: "
+ + referenceTypeID);
+ }
+
+ for (int i = 0; i < count; i++) {
+ long id = reply.getMethodID();
+ String name = reply.getString();
+ String signature = reply.getString();
+ int modBits = reply.getInt();
+
+ if (IDs != null)
+ IDs.add(new Long(id));
+ if (names != null)
+ names.add(name);
+ if (signatures != null)
+ signatures.add(signature);
+ if (modifiers != null)
+ modifiers.add(new Integer(modBits));
+ }
+
+ } catch (BoundException e) {
+ complain("Unable to parse reply packet for " + commandName + " command:\n\t"
+ + e.getMessage());
+ display("Reply packet:\n" + reply);
+ throw new Failure("Error occured while getting methodIDs for referenceTypeID: " +
+ + referenceTypeID);
+ }
+ }
+
+ // --------------------------------------------------- //
+
+ private static long[] makeListOfLongValues(Vector<Long> vector) {
+ int count = vector.size();
+ long[] list = new long[count];
+ for (int i = 0; i < count; i++) {
+ list[i] = (vector.elementAt(i)).longValue();
+ }
+ return list;
+ }
+
+ private static String[] makeListOfStringValues(Vector<String> vector) {
+ int count = vector.size();
+ String[] list = new String[count];
+ for (int i = 0; i < count; i++) {
+ list[i] = vector.elementAt(i);
+ }
+ return list;
+ }
+
+ // --------------------------------------------------- //
+
+ /**
+ * Force debugge VM to exit using JDWP connection if possible.
+ */
+ protected void killDebugee() {
+ // ignore
+ }
+
+ /**
+ * Close transport channel and kill the debugee VM if it is not terminated yet.
+ */
+ public void close() {
+ if (transport != null) {
+ try {
+ transport.close();
+ } catch (IOException e) {
+ log.display("WARNING: Caught IOException while closing JDWP connection:\n\t"
+ + e);
+ }
+ }
+ super.close();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/EventPacket.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.share.jdwp;
+
+import nsk.share.*;
+
+import java.util.Vector;
+
+/**
+ * This class represents a JDWP event packet.
+ */
+public class EventPacket extends CommandPacket {
+
+ /** Offset of the "suspendPolicy" field in a JDWP event packet. */
+ public final static int SuspendPolicyOffset = DataOffset;
+
+ /** Offset of the "eventsCount" field in a JDWP event packet. */
+ public final static int EventsCountOffset = SuspendPolicyOffset + JDWP.TypeSize.BYTE;
+
+ /** Offset of the first "eventKind" field in a JDWP event packet. */
+ public final static int FirstEventKindOffset = EventsCountOffset + JDWP.TypeSize.INT;
+
+ /**
+ * Make an empty event packet.
+ */
+ public EventPacket() {
+ super(JDWP.Command.Event.Composite, 0);
+ }
+
+ /**
+ * Make event packet with data from the specified byte buffer.
+ */
+// public EventPacket(ByteBuffer packet) {
+ public EventPacket(Packet packet) {
+ super(packet);
+ }
+
+ /**
+ * Return suspend policy of the events in the packet.
+ *
+ * throws BoundException if event packet structure is not valid
+ */
+ public byte getSuspendPolicy() {
+ try {
+ return getByte(SuspendPolicyOffset);
+ }
+ catch (BoundException e) {
+ throw new Failure("Caught unexpected exception while getting event kind from header:\n\t"
+ + e);
+ }
+ }
+
+ /**
+ * Return number of events in the packet.
+ *
+ * throws BoundException if event packet structure is not valid
+ */
+ public int getEventsCount() {
+ try {
+ return getInt(EventsCountOffset);
+ }
+ catch (BoundException e) {
+ throw new Failure("Caught unexpected exception while getting event kind from header:\n\t"
+ + e);
+ }
+ }
+
+ /**
+ * Return constant indicates kind of the first event in the packet.
+ *
+ * throws BoundException if event packet structure is not valid
+ */
+ public int getEventKind() {
+ try {
+ return getByte(FirstEventKindOffset);
+ }
+ catch (BoundException e) {
+ throw new Failure("Caught unexpected exception while getting event kind from header:\n\t"
+ + e);
+ }
+ }
+
+ /**
+ * Check event packet header.
+ * This method check if event packet has valid values in the header fields.
+ *
+ * @throws PacketFormatException if packet header fields have error or invalid values
+ */
+ public void checkHeader() throws PacketFormatException {
+ super.checkHeader();
+ if (getFullCommand() != JDWP.Command.Event.Composite) {
+ throw new PacketFormatException("Not Event.Composite command in the event packet header: "
+ + "0x" + toHexDecString(getFullCommand(), 4) );
+ }
+ if (getFlags() != JDWP.Flag.EVENT_PACKET) {
+ throw new PacketFormatException("Unexpected flags in the event packet header: "
+ + "0x" + toHexDecString(getFlags(), 2));
+ }
+/*
+ if (getPacketID() != 0) {
+ throw new PacketFormatException("Non-zero packet ID in the event packet header: "
+ + getPacketID());
+ }
+ */
+ }
+
+ /**
+ * Check event packet header for only one event of specified kind.
+ * This method check if event packet has valid values in the header fields.
+ *
+ * @throws PacketFormatException if packet header fields have error or invalid values
+ */
+ public void checkHeader(int eventKind) throws PacketFormatException {
+ checkHeader();
+ if (getEventsCount() != 1) {
+ throw new PacketFormatException("Not a single event in the event packet: "
+ + getEventsCount() + " events");
+ }
+ if (getEventKind() != eventKind) {
+ throw new PacketFormatException("Unexpected event kind in the event packet: "
+ + "0x" + toHexDecString(getEventKind(), 2));
+ }
+ }
+
+ /**
+ * Return string representation of the event packet header.
+ */
+ public String headerToString() {
+ return super.headerToString()
+ + " " + toHexString(SuspendPolicyOffset, 4) + " (policy): 0x" + toHexDecString(getSuspendPolicy(), 2) + "\n"
+ + " " + toHexString(EventsCountOffset, 4) + " (events): 0x" + toHexDecString(getEventsCount(), 8) + "\n"
+ + " " + toHexString(FirstEventKindOffset, 4) + " (kind): 0x" + toHexDecString(getEventKind(), 2) + "\n";
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/JDWP.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,971 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.share.jdwp;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+
+import nsk.share.Failure;
+
+/**
+ * This class contains JDWP constants, types and parameters.
+ */
+public class JDWP {
+
+ public static class Error {
+
+ public static final int NONE = 0;
+ public static final int INVALID_THREAD = 10;
+ public static final int INVALID_THREAD_GROUP = 11;
+ public static final int INVALID_PRIORITY = 12;
+ public static final int THREAD_NOT_SUSPENDED = 13;
+ public static final int THREAD_SUSPENDED = 14;
+ public static final int INVALID_OBJECT = 20;
+ public static final int INVALID_CLASS = 21;
+ public static final int CLASS_NOT_PREPARED = 22;
+ public static final int INVALID_METHODID = 23;
+ public static final int INVALID_LOCATION = 24;
+ public static final int INVALID_FIELDID = 25;
+ public static final int INVALID_FRAMEID = 30;
+ public static final int NO_MORE_FRAMES = 31;
+ public static final int OPAQUE_FRAME = 32;
+ public static final int NOT_CURRENT_FRAME = 33;
+ public static final int TYPE_MISMATCH = 34;
+ public static final int INVALID_SLOT = 35;
+ public static final int DUPLICATE = 40;
+ public static final int NOT_FOUND = 41;
+ public static final int INVALID_MONITOR = 50;
+ public static final int NOT_MONITOR_OWNER = 51;
+ public static final int INTERRUPT = 52;
+ public static final int INVALID_CLASS_FORMAT = 60;
+ public static final int CIRCULAR_CLASS_DEFINITION = 61;
+ public static final int FAILS_VERIFICATION = 62;
+ public static final int ADD_METHOD_NOT_IMPLEMENTED = 63;
+ public static final int SCHEMA_CHANGE_NOT_IMPLEMENTED = 64;
+ public static final int INVALID_TYPESTATE = 65;
+ public static final int HIERARCHY_CHANGE_NOT_IMPLEMENTED= 66;
+ public static final int DELETE_METHOD_NOT_IMPLEMENTED = 67;
+ public static final int UNSUPPORTED_VERSION = 68;
+ public static final int NAMES_DONT_MATCH = 69;
+ public static final int CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED = 70;
+ public static final int METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED = 71;
+ public static final int NOT_IMPLEMENTED = 99;
+ public static final int NULL_POINTER = 100;
+ public static final int ABSENT_INFORMATION = 101;
+ public static final int INVALID_EVENT_TYPE = 102;
+ public static final int ILLEGAL_ARGUMENT = 103;
+ public static final int OUT_OF_MEMORY = 110;
+ public static final int ACCESS_DENIED = 111;
+ public static final int VM_DEATH = 112;
+ public static final int INTERNAL = 113;
+ public static final int UNATTACHED_THREAD = 115;
+ public static final int INVALID_TAG = 500;
+ public static final int ALREADY_INVOKING = 502;
+ public static final int INVALID_INDEX = 503;
+ public static final int INVALID_LENGTH = 504;
+ public static final int INVALID_STRING = 506;
+ public static final int INVALID_CLASS_LOADER = 507;
+ public static final int INVALID_ARRAY = 508;
+ public static final int TRANSPORT_LOAD = 509;
+ public static final int TRANSPORT_INIT = 510;
+ public static final int NATIVE_METHOD = 511;
+ public static final int INVALID_COUNT = 512;
+
+ }
+
+ public static class Flag {
+
+ public static final byte NONE = (byte)0;
+ public static final byte REPLY_PACKET = (byte)0x80;
+ public static final byte EVENT_PACKET = NONE;
+
+ }
+
+ public static class EventKind {
+
+ public static final byte VM_INIT = (byte)90;
+ public static final byte VM_START = VM_INIT;
+ public static final byte VM_DISCONNECTED = (byte)100;
+ public static final byte VM_DEATH = (byte)99;
+
+ public static final byte THREAD_START = (byte)6;
+ public static final byte THREAD_END = (byte)7;
+ public static final byte THREAD_DEATH = THREAD_END;
+
+ public static final byte CLASS_PREPARE = (byte)8;
+ public static final byte CLASS_LOAD = (byte)10;
+ public static final byte CLASS_UNLOAD = (byte)9;
+
+ public static final byte METHOD_ENTRY = (byte)40;
+ public static final byte METHOD_EXIT = (byte)41;
+
+ public static final byte FIELD_ACCESS = (byte)20;
+ public static final byte FIELD_MODIFICATION = (byte)21;
+
+ public static final byte EXCEPTION = (byte)4;
+ public static final byte EXCEPTION_CATCH = (byte)30;
+
+ public static final byte FRAME_POP = (byte)3;
+
+ public static final byte BREAKPOINT = (byte)2;
+
+ public static final byte SINGLE_STEP = (byte)1;
+
+ public static final byte USER_DEFINED = (byte)5;
+
+ }
+
+ public static class EventModifierKind {
+
+ public static final byte COUNT = (byte)1;
+ public static final byte CONDITIONAL = (byte)2;
+ public static final byte THREAD_ONLY = (byte)3;
+ public static final byte CLASS_ONLY = (byte)4;
+ public static final byte CLASS_MATCH = (byte)5;
+ public static final byte CLASS_EXCLUDE = (byte)6;
+ public static final byte LOCATION_ONLY = (byte)7;
+ public static final byte EXCEPTION_ONLY = (byte)8;
+ public static final byte FIELD_ONLY = (byte)9;
+ public static final byte STEP = (byte)10;
+ public static final byte INSTANCE_ONLY = (byte)11;
+ };
+
+ public static class ThreadStatus {
+
+ public static final int ZOMBIE = 0;
+ public static final int RUNNING = 1;
+ public static final int SLEEPING = 2;
+ public static final int MONITOR = 3;
+ public static final int WAIT = 4;
+
+ }
+
+ public static class SuspendStatus {
+
+ public static final int SUSPEND_STATUS_SUSPENDED = 0x1;
+
+ }
+
+ public static class ClassStatus {
+
+ public static final int PREPARED = 2;
+ public static final int VERIFIED = 1;
+ public static final int INITIALIZED = 4;
+ public static final int ERROR = 8;
+
+ }
+
+ public static class TypeTag {
+
+ public static final byte CLASS = (byte)1;
+ public static final byte INTERFACE = (byte)2;
+ public static final byte ARRAY = (byte)3;
+
+ }
+
+ public static class Tag {
+
+ public static final byte ARRAY = (byte)91;
+ public static final byte BYTE = (byte)66;
+ public static final byte CHAR = (byte)67;
+ public static final byte OBJECT = (byte)76;
+ public static final byte FLOAT = (byte)70;
+ public static final byte DOUBLE = (byte)68;
+ public static final byte INT = (byte)73;
+ public static final byte LONG = (byte)74;
+ public static final byte SHORT = (byte)83;
+ public static final byte VOID = (byte)86;
+ public static final byte BOOLEAN = (byte)90;
+ public static final byte STRING = (byte)115;
+ public static final byte THREAD = (byte)116;
+ public static final byte THREAD_GROUP = (byte)103;
+ public static final byte CLASS_LOADER = (byte)108;
+ public static final byte CLASS_OBJECT = (byte)99;
+
+ }
+
+ public static class StepDepth {
+
+ public static final int INTO = 0;
+ public static final int OVER = 1;
+ public static final int OUT = 2;
+
+ }
+
+ public static class StepSize {
+
+ public static final int MIN = 0;
+ public static final int LINE = 1;
+
+ }
+
+ public static class SuspendPolicy {
+
+ public static final byte NONE = (byte)0;
+ public static final byte EVENT_THREAD = (byte)1;
+ public static final byte ALL = (byte)2;
+
+ }
+
+ public static class InvokeOptions {
+
+ public static final int INVOKE_SINGLE_THREADED = 0x01;
+ public static final int INVOKE_NONVIRTUAL = 0x02;
+
+ }
+
+ public static class TypeSize {
+
+ // VM independent type sizes
+
+ public static final int BYTE = 1;
+ public static final int BOOLEAN = 1;
+ public static final int CHAR = 2;
+ public static final int SHORT = 2;
+ public static final int FLOAT = 4;
+ public static final int INT = 4;
+ public static final int LONG = 8;
+ public static final int DOUBLE = 8;
+
+ public static final int TAG = 1;
+ public static final int LOCATION_INDEX = 8;
+
+ // basic VM specific type sizes
+
+ public static int OBJECT_ID = 8;
+ public static int METHOD_ID = 4;
+ public static int FIELD_ID = 4;
+ public static int FRAME_ID = 4;
+
+ // derivative VM specific type sizes
+
+ public static int TAGGED_OBJECT_ID = TAG + OBJECT_ID;
+
+ public static int THREAD_ID = OBJECT_ID;
+ public static int THREAD_GROUP_ID = OBJECT_ID;
+ public static int STRING_ID = OBJECT_ID;
+ public static int CLASS_LOADER_ID = OBJECT_ID;
+ public static int CLASS_OBJECT_ID = OBJECT_ID;
+ public static int REFERENCE_TYPE_ID = OBJECT_ID;
+
+ public static int CLASS_ID = REFERENCE_TYPE_ID;
+ public static int INTERFACE_ID = REFERENCE_TYPE_ID;
+ public static int ARRAY_ID = REFERENCE_TYPE_ID;
+
+ public static int LOCATION = TAG + CLASS_ID + METHOD_ID + LOCATION_INDEX;
+
+ /**
+ * Calculate type sizes based on VM dependent basic type sizes.
+ */
+ public static void CalculateSizes() {
+
+ TAGGED_OBJECT_ID = TAG + OBJECT_ID;
+
+ THREAD_ID = OBJECT_ID;
+ THREAD_GROUP_ID = OBJECT_ID;
+ STRING_ID = OBJECT_ID;
+ CLASS_LOADER_ID = OBJECT_ID;
+ CLASS_OBJECT_ID = OBJECT_ID;
+ REFERENCE_TYPE_ID = OBJECT_ID;
+
+ CLASS_ID = REFERENCE_TYPE_ID;
+ INTERFACE_ID = REFERENCE_TYPE_ID;
+ ARRAY_ID = REFERENCE_TYPE_ID;
+
+ LOCATION = TAG + CLASS_ID + METHOD_ID + LOCATION_INDEX;
+ }
+
+ }
+
+ public static class ModifierFlag {
+
+ public static final int PUBLIC = 0x0001;
+ public static final int PRIVATE = 0x0002;
+ public static final int PROTECTED = 0x0004;
+ public static final int STATIC = 0x0008;
+ public static final int FINAL = 0x0010;
+ public static final int SUPER = 0x0020;
+ public static final int VOLATILE = 0x0040;
+ public static final int TRANSIENT = 0x0080;
+ public static final int SYNCHRONIZED = 0x0020;
+ public static final int NATIVE = 0x0100;
+ public static final int INTERFACE = 0x0200;
+ public static final int ABSTRACT = 0x0400;
+ public static final int SYNTHETIC = 0xF0000000;
+
+ public static final int CLASS_MASK = PUBLIC | FINAL | SUPER | INTERFACE | ABSTRACT;
+ public static final int FIELD_MASK = PUBLIC | PRIVATE | PROTECTED | STATIC | FINAL | VOLATILE | TRANSIENT;
+ public static final int METHOD_MASK = PUBLIC | PRIVATE | PROTECTED | STATIC | FINAL | SYNCHRONIZED | NATIVE | ABSTRACT;
+
+ }
+
+ public static class CommandSet {
+
+ public static final byte VirtualMachine = (byte)0x01;
+ public static final byte ReferenceType = (byte)0x02;
+ public static final byte ClassType = (byte)0x03;
+ public static final byte ArrayType = (byte)0x04;
+ public static final byte InterfaceType = (byte)0x05;
+ public static final byte Method = (byte)0x06;
+ public static final byte Field = (byte)0x08;
+ public static final byte ObjectReference = (byte)0x09;
+ public static final byte StringReference = (byte)0x0A;
+ public static final byte ThreadReference = (byte)0x0B;
+ public static final byte ThreadGroupReference = (byte)0x0C;
+ public static final byte ArrayReferemce = (byte)0x0D;
+ public static final byte ClassLoaderReference = (byte)0x0E;
+ public static final byte EventRequest = (byte)0x0F;
+ public static final byte StackFrame = (byte)0x10;
+ public static final byte ClassObjectReference = (byte)0x11;
+ public static final byte Event = (byte)0x40;
+
+ }
+
+ // command names, used only for debug output
+ public static HashMap<Integer, String> commandNames = new HashMap<Integer, String>();
+
+ static
+ {
+ commandNames.put(Command.ObjectReference.ReferringObjects, "ObjectReference.ReferringObjects");
+ commandNames.put(Command.ReferenceType.Instances, "ReferenceType.Instances");
+ commandNames.put(Command.ReferenceType.ClassFileVersion, "ReferenceType.ClassFileVersion");
+ commandNames.put(Command.ReferenceType.ConstantPool, "ReferenceType.ConstantPool");
+ commandNames.put(Command.ThreadReference.OwnedMonitorsStackDepthInfo, "ThreadReference.OwnedMonitorsStackDepthInfo");
+ commandNames.put(Command.ThreadReference.ForceEarlyReturn, "ThreadReference.ForceEarlyReturn");
+ commandNames.put(Command.VirtualMachine.InstanceCounts, "VirtualMachine.InstanceCounts");
+ }
+
+ public static class Command {
+
+ public static class VirtualMachine {
+
+ public static final int Version = 0x0101;
+ public static final int ClassesBySignature = 0x0102;
+ public static final int AllClasses = 0x0103;
+ public static final int AllThreads = 0x0104;
+ public static final int TopLevelThreadGroups = 0x0105;
+ public static final int Dispose = 0x0106;
+ public static final int IDSizes = 0x0107;
+ public static final int Suspend = 0x0108;
+ public static final int Resume = 0x0109;
+ public static final int Exit = 0x010A;
+ public static final int CreateString = 0x010B;
+ public static final int Capabilities = 0x010C;
+ public static final int ClassPaths = 0x010D;
+ public static final int DisposeObjects = 0x010E;
+ public static final int HoldEvents = 0x010F;
+ public static final int ReleaseEvents = 0x0110;
+
+ // since JDK-1.4
+ public static final int CapabilitiesNew = 0x0111;
+ public static final int RedefineClasses = 0x0112;
+ public static final int SetDefaultStratum = 0x0113;
+
+ // since JDK-1.5
+ public static final int AllClassesWithGeneric = 0x0114;
+
+ // since JDK-1.6
+ public static final int InstanceCounts = 0x0115;
+ }
+
+ public static class ReferenceType {
+
+ public static final int Signature = 0x0201;
+ public static final int ClassLoader = 0x0202;
+ public static final int Modifiers = 0x0203;
+ public static final int Fields = 0x0204;
+ public static final int Methods = 0x0205;
+ public static final int GetValues = 0x0206;
+ public static final int SourceFile = 0x0207;
+ public static final int NestedTypes = 0x0208;
+ public static final int Status = 0x0209;
+ public static final int Interfaces = 0x020A;
+ public static final int ClassObject = 0x020B;
+
+ // since JDK-1.4
+ public static final int SourceDebugExtension = 0x020C;
+
+ // since JDK-1.5
+ public static final int SignatureWithGeneric = 0x020D;
+ public static final int FieldsWithGeneric = 0x020E;
+ public static final int MethodsWithGeneric = 0x020F;
+
+ // since JDK-1.6
+ public static final int Instances = 0x0210;
+ public static final int ClassFileVersion = 0x0211;
+ public static final int ConstantPool = 0x0212;
+ }
+
+ public static class ClassType {
+
+ public static final int Superclass = 0x0301;
+ public static final int SetValues = 0x0302;
+ public static final int InvokeMethod = 0x0303;
+ public static final int NewInstance = 0x0304;
+
+ }
+
+ public static class ArrayType {
+
+ public static final int NewInstance = 0x0401;
+
+ }
+
+ public static class InterfaceType {
+
+ }
+
+ public static class Method {
+
+ public static final int LineTable = 0x0601;
+ public static final int VariableTable = 0x0602;
+ public static final int Bytecodes = 0x0603;
+
+ // since JDK-1.4
+ public static final int IsObsolete = 0x0604;
+
+ // since JDK-1.5
+ public static final int VariableTableWithGeneric = 0x0605;
+
+ }
+
+ public static class Field {
+
+ }
+
+ public static class ObjectReference {
+
+ public static final int ReferenceType = 0x0901;
+ public static final int GetValues = 0x0902;
+ public static final int SetValues = 0x0903;
+ public static final int MonitorInfo = 0x0905;
+ public static final int InvokeMethod = 0x0906;
+ public static final int DisableCollection = 0x0907;
+ public static final int EnableCollection = 0x0908;
+ public static final int IsCollected = 0x0909;
+
+ // since JDK-1.6
+ public static final int ReferringObjects = 0x090A;
+ }
+
+ public static class StringReference {
+
+ public static final int Value = 0x0A01;
+
+ }
+
+ public static class ThreadReference {
+
+ public static final int Name = 0x0B01;
+ public static final int Suspend = 0x0B02;
+ public static final int Resume = 0x0B03;
+ public static final int Status = 0x0B04;
+ public static final int ThreadGroup = 0x0B05;
+ public static final int Frames = 0x0B06;
+ public static final int FrameCount = 0x0B07;
+ public static final int OwnedMonitors = 0x0B08;
+ public static final int CurrentContendedMonitor = 0x0B09;
+ public static final int Stop = 0x0B0A;
+ public static final int Interrupt = 0x0B0B;
+ public static final int SuspendCount = 0x0B0C;
+ public static final int PopTopFrame = 0x0B0D;
+
+ // since JDK-1.6
+ public static final int OwnedMonitorsStackDepthInfo = 0x0B0D;
+ public static final int ForceEarlyReturn = 0x0B0E;
+ }
+
+ public static class ThreadGroupReference {
+
+ public static final int Name = 0x0C01;
+ public static final int Parent = 0x0C02;
+ public static final int Children = 0x0C03;
+
+ }
+
+ public static class ArrayReference {
+
+ public static final int Length = 0x0D01;
+ public static final int GetValues = 0x0D02;
+ public static final int SetValues = 0x0D03;
+
+ }
+
+ public static class ClassLoaderReference {
+
+ public static final int VisibleClasses = 0x0E01;
+
+ }
+
+ public static class EventRequest {
+
+ public static final int Set = 0x0F01;
+ public static final int Clear = 0x0F02;
+ public static final int ClearAllBreakpoints = 0x0F03;
+
+ }
+
+ public static class StackFrame {
+
+ public static final int GetValues = 0x1001;
+ public static final int SetValues = 0x1002;
+ public static final int ThisObject = 0x1003;
+
+ // since JDK-1.4
+ public static final int PopFrames = 0x1004;
+
+ }
+
+ public static class ClassObjectReference {
+
+ public static final int ReflectedType = 0x1101;
+
+ }
+
+ public static class Event {
+
+ public static final int Composite = 0x4064;
+
+ }
+
+ } // end of class Command
+
+ public static class Capability {
+
+ // common capabilities
+ public static final int CAN_WATCH_FIELD_MODIFICATION = 0;
+ public static final int CAN_WATCH_FIELD_ACCESS = 1;
+ public static final int CAN_GET_BYTECODES = 2;
+ public static final int CAN_GET_SYNTHETIC_ATTRIBUTE = 3;
+ public static final int CAN_GET_OWNED_MONITOR_INFO = 4;
+ public static final int CAN_GET_CURRENT_CONTENDED_MONITOR = 5;
+ public static final int CAN_GET_MONITOR_INFO = 6;
+
+ // new capabilities (since JDWP version 1.4)
+ public static final int CAN_REDEFINE_CLASSES = 7;
+ public static final int CAN_ADD_METHODR_INFO = 8;
+ public static final int CAN_UNRESTRICTEDLY_REDEFINE_CLASSES = 9;
+ public static final int CAN_POP_FRAMES = 10;
+ public static final int CAN_USE_INSTANCE_FILTER = 11;
+ public static final int CAN_GET_SOURCE_DEBUG_EXTENSION = 12;
+ public static final int CAN_REQUEST_VMDEATH_EVENT = 13;
+ public static final int CAN_SET_DEFAULT_STRATUM = 14;
+ }
+
+ public static class Location extends ByteBuffer {
+
+ public static int TAG_OFFSET = 0;
+ public static int CLASS_ID_OFFSET = TAG_OFFSET + JDWP.TypeSize.TAG;
+ public static int METHOD_ID_OFFSET = CLASS_ID_OFFSET + JDWP.TypeSize.CLASS_ID;
+ public static int INDEX_OFFSET = METHOD_ID_OFFSET + JDWP.TypeSize.METHOD_ID;
+
+ private static void calculateOffsets() {
+ CLASS_ID_OFFSET = TAG_OFFSET + JDWP.TypeSize.TAG;
+ METHOD_ID_OFFSET = CLASS_ID_OFFSET + JDWP.TypeSize.CLASS_ID;
+ INDEX_OFFSET = METHOD_ID_OFFSET + JDWP.TypeSize.METHOD_ID;
+ }
+
+ public Location(byte typeTag, long classID, long methodID, long index) {
+ this();
+ // 1 byte type tag
+ putTag(typeTag);
+ // classID
+ putClassID(classID);
+ // methodID
+ putMethodID(methodID);
+ // 8 bytes index
+ putIndex(index);
+ }
+
+ public Location() {
+ super(JDWP.TypeSize.LOCATION, 0);
+ addBytes((byte)0, TypeSize.LOCATION);
+
+ // calculate offsets for VM-dependent type sizes
+ calculateOffsets();
+ }
+
+ public final byte getTag() {
+ try {
+ return getByte(TAG_OFFSET);
+ } catch (BoundException e) {
+ throw new Failure("Unable to get tag from location:\n\t" + e);
+ }
+ }
+
+ public final long getClassID() {
+ try {
+ return getID(CLASS_ID_OFFSET, JDWP.TypeSize.CLASS_ID);
+ } catch (BoundException e) {
+ throw new Failure("Unable to get classID from location:\n\t" + e);
+ }
+ }
+
+ public final long getMethodID() {
+ try {
+ return getID(METHOD_ID_OFFSET, JDWP.TypeSize.METHOD_ID);
+ } catch (BoundException e) {
+ throw new Failure("Unable to get methodID from location:\n\t" + e);
+ }
+ }
+
+ public final long getIndex() {
+ try {
+ return getID(INDEX_OFFSET, JDWP.TypeSize.LOCATION_INDEX);
+ } catch (BoundException e) {
+ throw new Failure("Unable to get code index from location:\n\t" + e);
+ }
+ }
+
+ public final void putTag(byte tag) {
+ try {
+ putByte(TAG_OFFSET, tag);
+ } catch (BoundException e) {
+ throw new Failure("Unable to put tag into location:\n\t" + e);
+ }
+ }
+
+ public final void putClassID(long classID) {
+ try {
+ putID(CLASS_ID_OFFSET, classID, JDWP.TypeSize.CLASS_ID);
+ } catch (BoundException e) {
+ throw new Failure("Unable to put classID into location:\n\t" + e);
+ }
+ }
+
+ public final void putMethodID(long methodID) {
+ try {
+ putID(METHOD_ID_OFFSET, methodID, JDWP.TypeSize.METHOD_ID);
+ } catch (BoundException e) {
+ throw new Failure("Unable to put methodID into location:\n\t" + e);
+ }
+ }
+
+ public final void putIndex(long index) {
+ try {
+ putID(INDEX_OFFSET, index, JDWP.TypeSize.LOCATION_INDEX);
+ } catch (BoundException e) {
+ throw new Failure("Unable to put code index into location:\n\t" + e);
+ }
+ }
+
+ public String toString() {
+ return "Location("
+ + "tag=" + getTag() + ", "
+ + "classID=" + getClassID() + ", "
+ + "methodID=" + getMethodID() + ", "
+ + "index=" + getIndex()
+ + ")";
+ }
+
+ } // end of class Location
+
+ public static class UntaggedValue {
+
+ public Object value = null;
+
+ public UntaggedValue() {
+ }
+
+ public UntaggedValue(Object value) {
+ this.value = value;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ public int length(byte tag) {
+ int valueSize = 0;
+ try {
+ switch (tag) {
+ case JDWP.Tag.BYTE: {
+ valueSize = JDWP.TypeSize.BYTE;
+ } break;
+ case JDWP.Tag.CHAR: {
+ valueSize = JDWP.TypeSize.CHAR;
+ } break;
+ case JDWP.Tag.FLOAT: {
+ valueSize = JDWP.TypeSize.FLOAT;
+ } break;
+ case JDWP.Tag.DOUBLE: {
+ valueSize = JDWP.TypeSize.DOUBLE;
+ } break;
+ case JDWP.Tag.INT: {
+ valueSize = JDWP.TypeSize.INT;
+ } break;
+ case JDWP.Tag.SHORT: {
+ valueSize = JDWP.TypeSize.SHORT;
+ } break;
+ case JDWP.Tag.BOOLEAN: {
+ valueSize = JDWP.TypeSize.BYTE;
+ } break;
+ case JDWP.Tag.LONG: {
+ valueSize = JDWP.TypeSize.LONG;
+ } break;
+ case JDWP.Tag.VOID: {
+ valueSize = 0;
+ } break;
+ case JDWP.Tag.ARRAY:
+ case JDWP.Tag.OBJECT:
+ case JDWP.Tag.STRING:
+ case JDWP.Tag.THREAD:
+ case JDWP.Tag.THREAD_GROUP:
+ case JDWP.Tag.CLASS_LOADER:
+ case JDWP.Tag.CLASS_OBJECT: {
+ valueSize = JDWP.TypeSize.OBJECT_ID;
+ } break;
+ default: {
+ throw new Failure("Unknown tag found while putting value into packet: " + tag);
+ }
+ }
+ } catch (ClassCastException e) {
+ throw new Failure("Wrong tag " + tag + " found while putting value to packet: " + value);
+ }
+ return JDWP.TypeSize.TAG + valueSize;
+ }
+
+ public void addValueTo(Packet packet, byte tag) {
+ if (value == null) {
+ throw new Failure("Unable to put null value into packet: " + this);
+ }
+ try {
+ switch (tag) {
+ case JDWP.Tag.BYTE: {
+ byte castedValue = ((Byte)value).byteValue();
+ packet.addByte(castedValue);
+ } break;
+ case JDWP.Tag.CHAR: {
+ char castedValue = ((Character)value).charValue();
+ packet.addChar(castedValue);
+ } break;
+ case JDWP.Tag.FLOAT: {
+ float castedValue = ((Float)value).floatValue();
+ packet.addFloat(castedValue);
+ } break;
+ case JDWP.Tag.DOUBLE: {
+ double castedValue = ((Double)value).doubleValue();
+ packet.addDouble(castedValue);
+ } break;
+ case JDWP.Tag.INT: {
+ int castedValue = ((Integer)value).intValue();
+ packet.addInt(castedValue);
+ } break;
+ case JDWP.Tag.SHORT: {
+ short castedValue = ((Short)value).shortValue();
+ packet.addShort(castedValue);
+ } break;
+ case JDWP.Tag.BOOLEAN: {
+ boolean castedValue = ((Boolean)value).booleanValue();
+ packet.addByte((byte)(castedValue? 1 : 0));
+ } break;
+ case JDWP.Tag.LONG: {
+ long castedValue = ((Long)value).longValue();
+ packet.addLong(castedValue);
+ } break;
+ case JDWP.Tag.VOID: {
+ } break;
+ case JDWP.Tag.ARRAY:
+ case JDWP.Tag.OBJECT:
+ case JDWP.Tag.STRING:
+ case JDWP.Tag.THREAD:
+ case JDWP.Tag.THREAD_GROUP:
+ case JDWP.Tag.CLASS_LOADER:
+ case JDWP.Tag.CLASS_OBJECT: {
+ long castedValue = ((Long)value).longValue();
+ packet.addObjectID(castedValue);
+ } break;
+ default: {
+ throw new Failure("Unknown tag found while putting value into packet: " + tag);
+ }
+ }
+ } catch (ClassCastException e) {
+ throw new Failure("Wrong tag " + tag + " found while putting value to packet: " + value);
+ }
+ }
+
+ public void getValueFrom(Packet packet, byte tag) throws BoundException {
+ switch (tag) {
+ case JDWP.Tag.BYTE: {
+ byte castedValue = packet.getByte();
+ value = new Byte(castedValue);
+ } break;
+ case JDWP.Tag.CHAR: {
+ char castedValue = packet.getChar();
+ value = new Character(castedValue);
+ } break;
+ case JDWP.Tag.FLOAT: {
+ float castedValue = packet.getFloat();
+ value = new Float(castedValue);
+ } break;
+ case JDWP.Tag.DOUBLE: {
+ double castedValue = packet.getDouble();
+ value = new Double(castedValue);
+ } break;
+ case JDWP.Tag.INT: {
+ int castedValue = packet.getInt();
+ value = new Integer(castedValue);
+ } break;
+ case JDWP.Tag.SHORT: {
+ short castedValue = packet.getShort();
+ value = new Short(castedValue);
+ } break;
+ case JDWP.Tag.BOOLEAN: {
+ byte castedValue = packet.getByte();
+ value = new Boolean(castedValue != 0);
+ } break;
+ case JDWP.Tag.LONG: {
+ long castedValue = packet.getLong();
+ value = new Long(castedValue);
+ } break;
+ case JDWP.Tag.VOID: {
+ value = new Long(0);
+ } break;
+ case JDWP.Tag.ARRAY:
+ case JDWP.Tag.OBJECT:
+ case JDWP.Tag.STRING:
+ case JDWP.Tag.THREAD:
+ case JDWP.Tag.THREAD_GROUP:
+ case JDWP.Tag.CLASS_LOADER:
+ case JDWP.Tag.CLASS_OBJECT: {
+ long castedValue = packet.getObjectID();
+ value = new Long(castedValue);
+ } break;
+ default: {
+ throw new Failure("Unknown tag found while reading value from packet: " + tag);
+ }
+ }
+ }
+
+ public String toString(byte tag) {
+ if (value == null) {
+ return "null";
+ }
+ String type = null;
+ try {
+ switch (tag) {
+ case JDWP.Tag.BYTE: {
+ type = "BYTE";
+ } break;
+ case JDWP.Tag.CHAR: {
+ type = "CHAR";
+ } break;
+ case JDWP.Tag.FLOAT: {
+ type = "FLOAT";
+ } break;
+ case JDWP.Tag.DOUBLE: {
+ type = "DOUBLE";
+ } break;
+ case JDWP.Tag.INT: {
+ type = "INT";
+ } break;
+ case JDWP.Tag.SHORT: {
+ type = "SHORT";
+ } break;
+ case JDWP.Tag.BOOLEAN: {
+ type = "BOOLEAN";
+ } break;
+ case JDWP.Tag.LONG: {
+ type = "LONG";
+ } break;
+ case JDWP.Tag.VOID: {
+ type = "VOID";
+ } break;
+ case JDWP.Tag.ARRAY: {
+ type = "ARRAY_ID";
+ } break;
+ case JDWP.Tag.OBJECT: {
+ type = "OBJECT_ID";
+ } break;
+ case JDWP.Tag.STRING: {
+ type = "STRING_ID";
+ } break;
+ case JDWP.Tag.THREAD: {
+ type = "THREAD_ID";
+ } break;
+ case JDWP.Tag.THREAD_GROUP: {
+ type = "THREAD_GROUP_ID";
+ } break;
+ case JDWP.Tag.CLASS_LOADER: {
+ type = "CLASS_LOADER_ID";
+ } break;
+ case JDWP.Tag.CLASS_OBJECT: {
+ type = "CLASS_OBJECT_ID";
+ } break;
+ default: {
+ throw new Failure("Unknown tag found while converting value into string: " + tag);
+ }
+ }
+ return "(" + type + ")" + value;
+ } catch (ClassCastException e) {
+ throw new Failure("Wrong tag " + tag + " found while putting value to packet: " + value);
+ }
+ }
+
+ } // end of class Value
+
+ public static class Value extends UntaggedValue {
+
+ public static final int TAG_OFFSET = 0;
+ public static final int VALUE_OFFSET = TAG_OFFSET + TypeSize.TAG;
+
+ public byte tag = 0;
+
+ public Value() {
+ }
+
+ public Value(byte tag, Object value) {
+ super(value);
+ this.tag = tag;
+ }
+
+ public byte getTag() {
+ return tag;
+ }
+
+ public int length() {
+ return super.length(tag);
+ }
+
+ public void addValueTo(Packet packet) {
+ if (value == null) {
+ throw new Failure("Unable to put null value into packet: " + this);
+ }
+ packet.addByte(tag);
+ super.addValueTo(packet, tag);
+ }
+
+ public void getValueFrom(Packet packet) throws BoundException {
+ tag = packet.getByte();
+ super.getValueFrom(packet, tag);
+ }
+
+ public String toString() {
+ return super.toString(tag);
+ }
+
+ } // end of class Value
+
+} // end of class JDWP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/Packet.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,522 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.share.jdwp;
+
+import nsk.share.*;
+
+import java.util.Vector;
+import java.io.*;
+
+/**
+ * This class represents a JDWP packet.
+ */
+public class Packet extends ByteBuffer {
+
+ /** JDWP packet flags constant. */
+// public final static byte flNoFlags = (byte)0x0;
+ /** JDWP packet flags constant. */
+// public final static byte flReply = (byte)0x80;
+
+ /** Offset of "length" field of JDWP packet. */
+ public final static int LengthOffset = 0;
+ /** Offset of "id" field of JDWP packet. */
+ public final static int IdOffset = LengthOffset + 4;
+ /** Offset of "flags" field of JDWP packet. */
+ public final static int FlagsOffset = IdOffset + 4;
+ /** Offset of full "command" field of JDWP packet. */
+ public final static int FullCommandOffset = FlagsOffset + 1;
+ /** Offset of "command" field of JDWP command packet. */
+ public final static int CommandSetOffset = FullCommandOffset;
+ /** Offset of "command" field of JDWP command packet. */
+ public final static int CommandOffset = CommandSetOffset + 1;
+ /** Offset of "error" field of JDWP reply packet. */
+ public final static int ErrorCodeOffset = FlagsOffset + 1;
+ /** Offset of "data" section of JDWP packet. */
+ public final static int DataOffset = FullCommandOffset + 2;
+
+ /** Size of JDWP packet header. */
+ public final static int PacketHeaderSize = DataOffset;
+
+ /**
+ * Makes empty JDWP packet.
+ */
+ public Packet() {
+ super();
+ resetBuffer();
+ }
+
+ /**
+ * Makes JDWP packet with data from the specified byte buffer.
+ */
+// public Packet(ByteBuffer packet) {
+ public Packet(Packet packet) {
+ super(packet);
+ resetPosition();
+ }
+
+ /**
+ * Clear buffer of the packet.
+ */
+ public void resetBuffer() {
+ super.resetBuffer();
+ while (length() < PacketHeaderSize)
+ addByte((byte) 0);
+ setLength();
+ resetPosition();
+ }
+
+ /**
+ * Return current position from begin of packet data area.
+ */
+ public int currentDataPosition() {
+ return currentPosition() - PacketHeaderSize;
+ }
+
+ /**
+ * Return value to the "length" field of JDWP packet.
+ */
+ public int getLength() {
+ try {
+ return getInt(LengthOffset);
+ }
+ catch (BoundException e) {
+ throw new Failure("Caught unexpected exception while getting packet length value from header:\n\t"
+ + e);
+ }
+ }
+
+ /**
+ * Assign specified value to the "length" field of JDWP packet.
+ */
+ public void setLength(int length) {
+ try {
+ putInt(LengthOffset, length);
+ }
+ catch (BoundException e) {
+ throw new Failure("Caught unexpected exception while setting packet length value into header:\n\t"
+ + e);
+ }
+ }
+
+ /**
+ * Assign packet length value to the "length" field of JDWP packet.
+ */
+ public void setLength() {
+ setLength(length());
+ }
+
+ /**
+ * Return value of the "id" field of JDWP packet.
+ */
+ public int getPacketID() {
+ try {
+ return getInt(IdOffset);
+ }
+ catch (BoundException e) {
+ throw new Failure("Caught unexpected exception while getting packet ID value from header:\n\t"
+ + e);
+ }
+ }
+
+ /**
+ * Assign value to the "id" field of JDWP packet.
+ */
+ public void setPacketID(int Id) {
+ try {
+ putInt(IdOffset, Id);
+ }
+ catch (BoundException e) {
+ throw new Failure("Caught unexpected exception while setting packet ID value into header:\n\t"
+ + e);
+ }
+ }
+
+ /**
+ * Return value of the "flags" field of JDWP packet.
+ */
+ public byte getFlags() {
+ try {
+ return getByte(FlagsOffset);
+ }
+ catch (BoundException e) {
+ throw new Failure("Caught unexpected exception while getting packet flags value from header:\n\t"
+ + e);
+ }
+ }
+
+ /**
+ * Assign value to the "flags" field of JDWP packet.
+ */
+ public void setFlags(byte flags) {
+ try {
+ putByte(FlagsOffset, flags);
+ }
+ catch (BoundException e) {
+ throw new Failure("Caught unexpected exception while setting packet flags value into header:\n\t"
+ + e);
+ }
+ }
+
+ /**
+ * Sets the current parser position to "data" field of JDWP packet.
+ */
+ public void resetPosition() {
+ resetPosition(PacketHeaderSize);
+ }
+
+ /**
+ * Return size of the "data" part of JDWP packet.
+ */
+ public int getDataSize() {
+ return length() - PacketHeaderSize;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Append fieldID to the end of this buffer.
+ */
+ public void addFieldID(long b) {
+ addID(b, JDWP.TypeSize.FIELD_ID);
+ }
+
+ /**
+ * Append methodID to the end of this buffer.
+ */
+ public void addMethodID(long b) {
+ addID(b, JDWP.TypeSize.METHOD_ID);
+ }
+
+ /**
+ * Append objectID to the end of this buffer.
+ */
+ public void addObjectID(long b) {
+ addID(b, JDWP.TypeSize.OBJECT_ID);
+ }
+
+ /**
+ * Append referenceID to the end of this buffer.
+ */
+ public void addReferenceTypeID(long b) {
+ addID(b, JDWP.TypeSize.REFERENCE_TYPE_ID);
+ }
+
+ /**
+ * Append frameID to the end of this buffer.
+ */
+ public void addFrameID(long b) {
+ addID(b, JDWP.TypeSize.FRAME_ID);
+ }
+
+ /**
+ * Append string value (an UTF-8 encoded string, not zero terminated,
+ * preceded by a four-byte integer length) to the end of this buffer.
+ */
+ public void addString(String value) {
+ final int count = JDWP.TypeSize.INT + value.length();
+ addInt(value.length());
+ try {
+ addBytes(value.getBytes("UTF-8"), 0, value.length());
+ } catch (UnsupportedEncodingException e) {
+ throw new Failure("Unsupported UTF-8 ecnoding while adding string value to JDWP packet:\n\t"
+ + e);
+ }
+ }
+
+ /**
+ * Append location value to the end of this buffer.
+ */
+ public void addLocation(JDWP.Location location) {
+ addBytes(location.getBytes(), 0, location.length());
+ }
+
+ /**
+ * Append untagged value to the end of this buffer.
+ */
+ public void addUntaggedValue(JDWP.UntaggedValue value, byte tag) {
+ value.addValueTo(this, tag);
+ }
+
+ /**
+ * Append tagged value to the end of this buffer.
+ */
+ public void addValue(JDWP.Value value) {
+ value.addValueTo(this);
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // get packet data
+ //////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Read a fieldID value from byte buffer at the current parser position.
+ *
+ * @throws BoundException if there is no valid value bytes at the given position
+ */
+ public long getFieldID() throws BoundException {
+ return getID(JDWP.TypeSize.FIELD_ID);
+ }
+
+ /**
+ * Read a methodID value from byte buffer at the current parser position.
+ *
+ * @throws BoundException if there is no valid value bytes at the given position
+ */
+ public long getMethodID() throws BoundException {
+ return getID(JDWP.TypeSize.METHOD_ID);
+ }
+
+ /**
+ * Read an objectID value from byte buffer at the current parser position.
+ *
+ * @throws BoundException if there is no valid value bytes at the given position
+ */
+ public long getObjectID() throws BoundException {
+ return getID(JDWP.TypeSize.OBJECT_ID);
+ }
+
+ /**
+ * Read a referenceTypeID value from byte buffer at the current parser position.
+ *
+ * @throws BoundException if there is no valid value bytes at the given position
+ */
+ public long getReferenceTypeID() throws BoundException {
+ return getID(JDWP.TypeSize.REFERENCE_TYPE_ID);
+ }
+
+ /**
+ * Read a frameID value from byte buffer at the current parser position.
+ *
+ * @throws BoundException if there is no valid value bytes at the given position
+ */
+ public long getFrameID() throws BoundException {
+ return getID(JDWP.TypeSize.FRAME_ID);
+ }
+
+ /**
+ * Read from this buffer a string value at the current parser
+ * position and returns this value.
+ *
+ * @throws BoundException if there are no valid string bytes in the buffer
+ */
+ public String getString() throws BoundException {
+ final int count = JDWP.TypeSize.INT;
+ int available = length() - currentPosition();
+ if (count > available) {
+ throw new BoundException("Unable to get " + count + " bytes of string length value at " +
+ offsetString() + " (available bytes: " + available + ")" );
+ }
+
+ int len = getInt();
+
+ if (len < 0)
+ throw new BoundException("Negative length of string to get: " + len);
+
+ if (len == 0)
+ return "";
+
+ available = length() - currentPosition();
+ if (len > available) {
+ throw new BoundException("Unable to get " + len + " bytes of string value at " +
+ offsetString() + " (available bytes: " + available + ")" );
+ }
+
+ byte[] s = new byte[len];
+ for (int i = 0; i < len; i++)
+ s[i] = getByte();
+
+ try {
+ return new String(s, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new Failure("Unsupported UTF-8 ecnoding while extracting string value from JDWP packet:\n\t"
+ + e);
+ }
+ }
+
+ /**
+ * Reads from this buffer an location value at the current parser
+ * position and returns this value.
+ *
+ * @throws BoundException if there are no enough bytes in the buffer
+ */
+ public JDWP.Location getLocation() throws BoundException {
+ final int count = JDWP.TypeSize.LOCATION;
+ final int available = length() - currentPosition();
+ if (count > available) {
+ throw new BoundException("Unable to get " + count + " bytes of location value at " +
+ offsetString() + " (available bytes: " + available + ")" );
+ }
+
+ JDWP.Location location = new JDWP.Location();
+ try {
+ for (int i = 0; i < JDWP.TypeSize.LOCATION; i++) {
+ location.putByte(i, getByte());
+ }
+ }
+ catch (BoundException e) {
+ throw new TestBug("Caught unexpected bound exception while getting " +
+ count + " bytes of location value:\n\t" + e);
+ };
+
+ return location;
+ }
+
+ /**
+ * Reads from this buffer an untagged value at the current parser
+ * position and returns this value.
+ *
+ * @throws BoundException if there are no enough bytes in the buffer
+ */
+ public JDWP.UntaggedValue getUntaggedValue(byte tag) throws BoundException {
+ JDWP.UntaggedValue value = new JDWP.UntaggedValue();
+ try {
+ value.getValueFrom(this, tag);
+ }
+ catch (BoundException e) {
+ throw new TestBug("Caught unexpected bound exception while getting " +
+ " bytes of a value:\n\t" + e);
+ };
+
+ return value;
+ }
+
+ /**
+ * Reads from this buffer a tagged value at the current parser
+ * position and returns this value.
+ *
+ * @throws BoundException if there are no enough bytes in the buffer
+ */
+ public JDWP.Value getValue() throws BoundException {
+ JDWP.Value value = new JDWP.Value();
+ try {
+ value.getValueFrom(this);
+ }
+ catch (BoundException e) {
+ throw new TestBug("Caught unexpected bound exception while getting " +
+ " bytes of a value:\n\t" + e);
+ };
+
+ return value;
+ }
+
+
+ ////////////////////////////////////////////////////////////////
+
+ /**
+ * Read packet bytes from the stream.
+ *
+ * @throws IOException if error occured when reading bytes
+ */
+ public void readFrom(Transport transport) throws IOException {
+ resetBuffer();
+
+// System.err.println("Reading packet header");
+ try {
+ for (int i = 0; i < PacketHeaderSize; i++) {
+ byte b = transport.read();
+ putByte(i, b);
+ }
+ }
+ catch (BoundException e) {
+ throw new TestBug(e);
+ }
+
+ int length = getLength();
+
+ checkSpace(length - PacketHeaderSize);
+
+// System.err.println("Packet size: " + length);
+ for (int i = PacketHeaderSize; i < length; i++) {
+ byte b = transport.read();
+ addByte(b);
+ }
+// System.err.println("Packet read successfully");
+ }
+
+ /**
+ * Write packet bytes to the stream.
+ *
+ * @throws IOException if error occured when reading bytes
+ */
+ public void writeTo(Transport transport) throws IOException {
+ setLength();
+// System.err.println("Writing packet bytes: " + length());
+ transport.write(bytes, 0, length());
+ }
+
+ /**
+ * Check packet header.
+ * This method check if packet has valid values in header fields.
+ *
+ * @throws PacketFormatException if packet header fields has error or invalid values
+ */
+ public void checkHeader() throws PacketFormatException {
+ if (getLength() != length()) {
+ throw new PacketFormatException("Unexpected packet length value in the header:"
+ + getLength());
+ }
+ }
+
+ /**
+ * Check if packet is parsed totally and no trailing bytes left unparsed.
+ * This method check if packet has valid values in header fields.
+ *
+ * @throws PacketFormatException if there are trailing bytes left unparsed
+ */
+ public void checkParsed() throws PacketFormatException {
+ if (! isParsed()) {
+ throw new PacketFormatException("Extra trailing bytes found in the packet at: "
+ + offsetString());
+ }
+ }
+
+ /**
+ * Return string representation of the packet header.
+ */
+ public String headerToString() {
+ return "Packet header (" + PacketHeaderSize + " bytes):" + "\n"
+ + " " + toHexString(LengthOffset, 4) + " (length) : 0x" + toHexDecString(getLength(), 8) + "\n"
+ + " " + toHexString(IdOffset, 4) + " (id) : 0x" + toHexDecString(getPacketID(), 8) + "\n"
+ + " " + toHexString(FlagsOffset, 4) + " (flags) : 0x" + toHexDecString(getFlags(), 2) + "\n";
+ }
+
+ /**
+ * Return string representation of the packet.
+ */
+ public String toString() {
+ return headerToString()
+ + "Entire packet (" + length() + " bytes): " + "\n"
+ + super.toString(0)
+ + "Packet end";
+ }
+
+ /**
+ * Exception indicated that packet has an ivnalid structure.
+ */
+ class PacketFormatException extends BoundException {
+ PacketFormatException(String message) {
+ super(message);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/ReplyPacket.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.share.jdwp;
+
+import nsk.share.*;
+import java.util.Vector;
+
+/**
+ * This class represents a JDWP reply packet.
+ */
+public class ReplyPacket extends Packet {
+
+ /** Error code constant. */
+// public final static int errOk = JDWP.Error.NONE;
+ /** Error code constant. */
+// public final static int errWrongPacketSize = 0x400;
+ /** Error code constant. */
+// public final static int errNotAvailable = 0x401;
+ /** Error code constant. */
+// public final static int errEvent = 0x4064;
+
+ /**
+ * Make empty reply packet.
+ */
+ public ReplyPacket() {
+ super();
+ }
+
+ /**
+ * Make reply packet with data from the specified byte buffer.
+ */
+// public ReplyPacket(ByteBuffer packet) {
+ public ReplyPacket(Packet packet) {
+ super(packet);
+ }
+
+ /**
+ * Return value of the "error code" field of JDWP reply packet.
+ */
+ public int getErrorCode() {
+
+ int err = 0;
+ try {
+ err = (int) getID(ErrorCodeOffset, 2);
+ }
+ catch (BoundException e) {
+ throw new Failure("Caught unexpected exception while getting error code from header:\n\t"
+ + e);
+ }
+
+ return err;
+ }
+
+ /**
+ * Set value of the "error code" field of JDWP reply packet.
+ */
+ public void setErrorCode(long err) {
+ try {
+ putID(ErrorCodeOffset, err, 2);
+ }
+ catch (BoundException e) {
+ throw new Failure("Caught unexpected exception while setting error code into header:\n\t"
+ + e);
+ }
+ }
+
+ /**
+ * Check reply packet header.
+ * This method check if reply packet has valid values in the header fields.
+ *
+ * @throws PacketFormatException if packet header fields have error or invalid values
+ */
+/*
+ protected void checkHeaderForReplyOrEvent() throws PacketFormatException {
+ super.checkHeader();
+ }
+ */
+
+ /**
+ * Check reply packet header.
+ * This method check if reply packet has valid values in the header fields.
+ *
+ * @throws PacketFormatException if packet header fields have error or invalid values
+ */
+ public void checkHeader() throws PacketFormatException {
+// checkHeaderForReplyOrEvent();
+ super.checkHeader();
+ if (getFlags() != JDWP.Flag.REPLY_PACKET) {
+ throw new PacketFormatException("Unexpected flags in reply packet header: "
+ + "0x" + toHexDecString(getFlags(), 2));
+ }
+ if (getErrorCode() != JDWP.Error.NONE) {
+ throw new PacketFormatException("Unexpected error code in reply packet header: "
+ + "0x" + toHexDecString(getErrorCode(), 4));
+ }
+ }
+
+ /**
+ * Check reply packet header for specified reply ID.
+ * This method check if reply packet has valid values in the header fields.
+ *
+ * @throws PacketFormatException if packet header fields have error or invalid values
+ */
+ public void checkHeader(int id) throws PacketFormatException {
+ checkHeader();
+ if (getPacketID() != id) {
+ throw new PacketFormatException("Unexpected ID in reply packet header: "
+ + getPacketID());
+ }
+ }
+
+ /**
+ * Return string representation of the reply packet header.
+ */
+ public String headerToString() {
+ String s;
+
+ if (getFlags() == 0)
+ s = " (command)";
+ else
+ s = " (error) ";
+
+ return super.headerToString()
+ + " " + toHexString(CommandOffset, 4) + s + ": 0x" + toHexDecString(getErrorCode(), 4) + "\n";
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/SocketTransport.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.share.jdwp;
+
+import nsk.share.*;
+
+import java.io.*;
+import java.net.*;
+
+/**
+ * This class represents a socket transport for JDWP.
+ */
+public class SocketTransport extends Transport {
+
+ /**
+ * Socket for established JDWP connection.
+ */
+ private Socket socket = null;
+
+ /**
+ * ServerSocket for listening JDWP connection.
+ */
+ private ServerSocket serverSocket = null;
+
+ /**
+ * Input stream of socket.
+ */
+ private InputStream in = null;
+
+ /**
+ * Output stream of socket.
+ */
+ private OutputStream out = null;
+
+ /**
+ * Port to listen to.
+ */
+ int listenPort = 0;
+
+ /**
+ * Make <code>SocketTransport</cose> object with providing specified Log.
+ */
+ public SocketTransport(Log log) {
+ super(log);
+ }
+
+ /**
+ * Bind for connection from target VM to specified port number.
+ * If given port number is 0 then bind to any free port number.
+ *
+ * @return port number which this transport is listening for
+ */
+ public int bind(int port)
+ throws IOException {
+ serverSocket = new ServerSocket();
+ if (port == 0) {
+ // Only need SO_REUSEADDR if we're using a fixed port. If we
+ // start seeing EADDRINUSE due to collisions in free ports
+ // then we should retry the bind() a few times.
+ display("port == 0, disabling SO_REUSEADDR");
+ serverSocket.setReuseAddress(false);
+ }
+ serverSocket.bind(new InetSocketAddress(port));
+ listenPort = serverSocket.getLocalPort();
+ return listenPort;
+ }
+
+ /**
+ * Attach to the target VM for specified host name and port number.
+ */
+ public void attach(String ServerName, int PortNumber)
+ throws UnknownHostException, IOException {
+ for (int i = 0; i < Binder.CONNECT_TRIES; i++ ) {
+ try {
+ socket = new Socket(ServerName, PortNumber);
+ display("JDWP socket connection established");
+// socket.setTcpNoDelay(true);
+ in = socket.getInputStream();
+ out = socket.getOutputStream();
+ return;
+ } catch (IOException e) {
+ display("Attempt #" + i + " to establish JDWP socket connection failed:\n\t" + e);
+ try {
+ Thread.currentThread().sleep(Binder.CONNECT_TRY_DELAY);
+ } catch (InterruptedException ie) {
+ ie.printStackTrace(log.getOutStream());
+ throw new Failure("Thread interrupted while establishing JDWP connection: \n\t"
+ + ie);
+ }
+ }
+ }
+ throw new IOException("Timeout exceeded while establishing JDWP socket connection to "
+ + ServerName + ":" + PortNumber);
+ }
+
+ /**
+ * Accept connection from target VM for already boud port.
+ */
+ public void accept()
+ throws IOException {
+
+ if (serverSocket == null)
+ throw new Failure("Attempt to accept JDWP socket connection from unbound port");
+
+ socket = serverSocket.accept();
+ serverSocket.close();
+ serverSocket = null;
+
+ in = socket.getInputStream();
+ out = socket.getOutputStream();
+ }
+
+ /**
+ * Close socket and streams.
+ */
+ public void close() throws IOException {
+
+ if (socket == null)
+ return;
+
+ if (out != null) {
+ flush();
+ out.close();
+ }
+
+ if (in != null) {
+ in.close();
+ }
+
+ if (socket != null) {
+ socket.close();
+ socket = null;
+ }
+
+ if (serverSocket != null) {
+ serverSocket.close();
+ serverSocket = null;
+ }
+ }
+
+ /**
+ * Return number of bytes that can be read.
+ */
+ public int available() throws IOException {
+ return in.available();
+ };
+
+ /**
+ * Flush bytes being buffered for writing if any.
+ */
+ public void flush() throws IOException {
+ out.flush();
+ }
+
+ /**
+ * Set timeout for reading data in milliseconds.
+ */
+ public void setReadTimeout(long millisecs) throws IOException {
+ socket.setSoTimeout((int)millisecs);
+ }
+
+ /**
+ * Read the next byte of data from the socket.
+ * The value byte is returned as an int in the range 0 to 255.
+ * If no byte is available, the value -1 is returned.
+ */
+ public byte read() throws IOException {
+ int b = in.read();
+ if (b < 0) {
+ throw new IOException("JDWP socket connection closed by remote host");
+ }
+ return (byte) b;
+ };
+
+ /**
+ * Write the specified byte to the socket.
+ */
+ public void write(int b) throws IOException {
+ out.write(b);
+ };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/TestDebuggerType1.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,321 @@
+/*
+ * Copyright (c) 2006, 2018, 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.
+ */
+package nsk.share.jdwp;
+
+import java.io.*;
+import nsk.share.*;
+import nsk.share.jpda.*;
+
+/*
+ * This class can be used as base for debugger.
+ * Class initialize log, pipe, debuggee, transport.
+ *
+ * Subclasses should implement method doTest() and provide debugee class name via method getDebugeeClassName()
+ */
+abstract public class TestDebuggerType1 {
+ protected ArgumentHandler argumentHandler;
+
+ protected Log log;
+
+ protected IOPipe pipe;
+
+ protected Debugee debuggee;
+
+ protected Transport transport;
+
+ private boolean success = true;
+
+ public static String createTypeSignature(String name) {
+ return "L" + name.replace('.', '/') + ";";
+ }
+
+ protected void setSuccess(boolean value) {
+ success = value;
+ }
+
+ protected boolean getSuccess() {
+ return success;
+ }
+
+ protected String getDebugeeClassName() {
+ return AbstractJDWPDebuggee.class.getName();
+ }
+
+ abstract protected void doTest();
+
+ // receive reply for given command
+ protected ReplyPacket getReply(CommandPacket command, boolean expectError, int errorCode) throws IOException,
+ BoundException {
+ log.display("Waiting for reply packet");
+ ReplyPacket reply = new ReplyPacket();
+ transport.read(reply);
+ log.display("Reply packet received:\n" + reply);
+
+ if (expectError) {
+ if (reply.getErrorCode() != errorCode) {
+ setSuccess(false);
+ log.complain("Reply doesn't contain expected error " + errorCode + ", error code = "
+ + reply.getErrorCode());
+ } else {
+ log.display("Expected error: " + errorCode);
+ }
+ } else {
+ log.display("Checking reply packet header");
+ reply.checkHeader(command.getPacketID());
+ log.display("Parsing reply packet:");
+ reply.resetPosition();
+ }
+
+ return reply;
+ }
+
+ // receive reply for given command
+ protected ReplyPacket getReply(CommandPacket command) throws IOException, BoundException {
+ return getReply(command, false, 0);
+ }
+
+ // initialize test and remove unsupported by nsk.share.jdwp.ArgumentHandler
+ // arguments
+ // (ArgumentHandler constructor throws BadOption exception if command line
+ // contains unrecognized by ArgumentHandler options)
+ protected String[] doInit(String args[]) {
+ return args;
+ }
+
+ public int runIt(String args[], PrintStream out) {
+ argumentHandler = new ArgumentHandler(doInit(args));
+ // make log for debugger messages
+ log = new Log(out, argumentHandler);
+
+ // execute test and display results
+ try {
+ log.display("\n>>> Preparing debugee for testing \n");
+
+ // launch debugee
+ Binder binder = new Binder(argumentHandler, log);
+ log.display("Launching debugee");
+ debuggee = binder.bindToDebugee(getDebugeeClassName());
+ transport = debuggee.getTransport();
+ pipe = debuggee.createIOPipe();
+
+ // make debuggee ready for testing
+ prepareDebugee();
+
+ doTest();
+ } catch (Throwable t) {
+ setSuccess(false);
+ log.complain("Caught unexpected exception:\n" + t);
+ t.printStackTrace(log.getOutStream());
+ } finally {
+ if (pipe != null)
+ quitDebugee();
+ }
+
+ if (getSuccess()) {
+ log.display("TEST PASSED");
+ return Consts.TEST_PASSED;
+ } else {
+ log.display("TEST FAILED");
+ return Consts.TEST_FAILED;
+ }
+ }
+
+ protected void prepareDebugee() {
+ // wait for VM_INIT event from debugee
+ log.display("Waiting for VM_INIT event");
+ debuggee.waitForVMInit();
+
+ // query debugee for VM-dependent ID sizes
+ log.display("Querying for IDSizes");
+ debuggee.queryForIDSizes();
+
+ // resume initially suspended debugee
+ log.display("Resuming debugee VM");
+ debuggee.resume();
+
+ // wait for READY signal from debugee
+ log.display("Waiting for signal from debugee: " + AbstractDebuggeeTest.COMMAND_READY);
+
+ if (!isDebuggeeReady())
+ return;
+ }
+
+ protected boolean isDebuggeeReady() {
+ String signal = pipe.readln();
+ log.display("Received signal from debugee: " + signal);
+
+ if (!signal.equals(AbstractDebuggeeTest.COMMAND_READY)) {
+ setSuccess(false);
+ log.complain("Unexpected signal received form debugee: " + signal + " (expected: "
+ + AbstractDebuggeeTest.COMMAND_READY + ")");
+ return false;
+ }
+
+ return true;
+ }
+
+ protected void quitDebugee() {
+ // send debugee signal to quit
+ log.display("Sending signal to debugee: " + AbstractDebuggeeTest.COMMAND_QUIT);
+ pipe.println(AbstractDebuggeeTest.COMMAND_QUIT);
+
+ // wait for debugee exits
+ log.display("Waiting for debugee exits");
+ int code = debuggee.waitFor();
+
+ // analize debugee exit status code
+ if (code == (Consts.JCK_STATUS_BASE + Consts.TEST_PASSED)) {
+ log.display("Debugee PASSED with exit code: " + code);
+ } else {
+ setSuccess(false);
+ log.complain("Debugee FAILED with exit code: " + code);
+ }
+ }
+
+ protected int defaultBreakpointRequestID;
+
+ // query debuggee for objectID value of static class field
+ protected long queryObjectID(long classID, String fieldName, byte tag) {
+ // get fieledID for static field (declared in the class)
+ long fieldID = debuggee.getClassFieldID(classID, fieldName, true);
+
+ // get value of the field
+ JDWP.Value value = debuggee.getStaticFieldValue(classID, fieldID);
+
+ // check that value has correct tag
+ if (value.getTag() != tag) {
+ throw new Failure("Wrong objectID tag received from field \"" + fieldName + "\": " + value.getTag()
+ + " (expected: " + tag + ")");
+ }
+
+ // extract objectID from the value
+ long objectID = ((Long) value.getValue()).longValue();
+
+ return objectID;
+ }
+
+ // query debuggee for objectID value of static class field
+ protected long queryObjectID(long classID, String fieldName) {
+
+ // get fieledID for static field (declared in the class)
+ long fieldID = debuggee.getClassFieldID(classID, fieldName, true);
+
+ // get value of the field
+ JDWP.Value value = debuggee.getStaticFieldValue(classID, fieldID);
+
+ // extract objectID from the value
+ long objectID = ((Long) value.getValue()).longValue();
+
+ return objectID;
+ }
+
+ protected void clearRequest(byte eventKind, int requestID) {
+ try {
+ CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear);
+ command.addByte(eventKind);
+ command.addInt(requestID);
+ command.setLength();
+ transport.write(command);
+ ReplyPacket reply;
+
+ reply = getReply(command);
+
+ if (!reply.isParsed()) {
+ log.complain("Extra trailing bytes found in request reply packet at: " + reply.offsetString());
+ }
+ } catch (Exception e) {
+ setSuccess(false);
+ log.complain("Caught exception while testing JDWP command: " + e);
+ e.printStackTrace(log.getOutStream());
+ }
+ }
+
+ // receives JDWP event, checks that only one event was received and checks
+ // event kind and event's request id
+ protected EventPacket receiveSingleEvent(byte expectedEventKind, int expectedRequestID) {
+ try {
+ EventPacket eventPacket = debuggee.getEventPacket();
+
+ eventPacket.checkHeader();
+ eventPacket.resetPosition();
+
+ eventPacket.getByte();
+
+ int eventCount = eventPacket.getInt();
+
+ if (eventCount != 1) {
+ setSuccess(false);
+ log.complain("Unexpected event count: " + eventCount + ", expected is " + 1);
+ }
+
+ byte eventKind = eventPacket.getByte();
+
+ if (eventKind != expectedEventKind) {
+ setSuccess(false);
+ log.complain("Unexpected event kind: " + eventKind + ", expected is " + expectedEventKind);
+ }
+
+ int requestID = eventPacket.getInt();
+
+ if (requestID != expectedRequestID) {
+ setSuccess(false);
+ log.complain("Unexpected request id: " + requestID + ", expected is " + expectedRequestID);
+ }
+
+ return eventPacket;
+ } catch (Exception e) {
+ setSuccess(false);
+ log.complain("Caught exception while testing JDWP command: " + e);
+ e.printStackTrace(log.getOutStream());
+
+ return null;
+ }
+ }
+
+
+ private boolean currentSuccess = false;
+ protected void forceGC() {
+ pipe.println(AbstractDebuggeeTest.COMMAND_FORCE_GC);
+ if (!isDebuggeeReady())
+ return;
+ currentSuccess = getSuccess();
+ }
+
+ // Get GC statistics
+ protected void resetStatusIfGC() {
+ pipe.println(AbstractDebuggeeTest.COMMAND_GC_COUNT);
+ String command = pipe.readln();
+ if (command.startsWith(AbstractDebuggeeTest.COMMAND_GC_COUNT)) {
+ if (!isDebuggeeReady()) {
+ return;
+ }
+ if (Integer.valueOf(command.substring(AbstractDebuggeeTest.COMMAND_GC_COUNT.length() + 1)) > 0) {
+ log.display("WARNING: The GC worked during tests. Results are skipped.");
+ setSuccess(currentSuccess);
+ }
+ return;
+ }
+ setSuccess(false);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/Transport.java Wed May 30 20:54:45 2018 -0700
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2001, 2018, 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.
+ */
+
+package nsk.share.jdwp;
+
+import nsk.share.*;
+
+import java.io.IOException;
+//import java.util.Vector;
+
+/**
+ * This class represents an abstract transport for JDWP.
+ */
+public abstract class Transport extends Log.Logger {
+
+ public static final String LOG_PREFIX = "transport> ";
+
+ /**
+ * Make base <code>Transport</code> object providing with specified Log.
+ */
+ public Transport(Log log) {
+ super(log, LOG_PREFIX);
+ }
+
+ /**
+ * Return number of bytes that can be received.
+ */
+ public abstract int available() throws IOException;
+
+ /**
+ * Flushe bytes being buffered for writing if any.
+ */
+ public abstract void flush() throws IOException;
+
+ /**
+ * Receive the next byte of data.
+ *
+ * The value byte is returned as an int in the range 0 to 255.
+ * If no byte is available, the value -1 is returned.
+ */
+ public abstract byte read() throws IOException;
+
+ /**
+ * Send the specified byte.
+ */
+ public abstract void write(int b) throws IOException;
+
+ /**
+ * Send the specified bytes.
+ */
+ public void write(byte[] b, int off, int len) throws IOException {
+ for (int i = 0; i < len; i++)
+ write(b[off + i]);
+ }
+
+ /**
+ * Receive bytes of JDWP packet for default timeout.
+ */
+ public void read(Packet packet) throws IOException {
+ packet.readFrom(this);
+ }
+
+ /**
+ * Send and flushe bytes of JDWP packet.
+ */
+ public void write(Packet packet) throws IOException {
+ packet.writeTo(this);
+ flush();
+ }
+
+ /**
+ * Perform JDWP "handshake" procedure.
+ */
+ public void handshake() throws IOException {
+
+ String hs = "JDWP-Handshake";
+ byte[] hsb = hs.getBytes();
+
+ write(hsb, 0, hsb.length);
+ flush();
+
+ try {
+ Thread.currentThread().sleep(500);
+ } catch (InterruptedException e) {
+ throw new Failure(e);
+ }
+
+ int received = 0;
+ for (int i = 0; i < Binder.CONNECT_TRIES; i++) {
+ received = available();
+ if (received < hsb.length) {
+// System.err.println("Failed to hadshake try #" + i + ", bytes: " + received);
+ try {
+ Thread.currentThread().sleep(Binder.CONNECT_TRY_DELAY);
+ } catch (InterruptedException e) {
+ throw new Failure("Thread interrupted while sleeping between connection attempts:\n\t"
+ + e);
+ }
+ } else {
+// System.err.println("Successed to hadshake try #" + i + ", bytes: " + received);
+ for (int j = 0; j < hsb.length; j++) {
+ byte b = (byte) (read() & 0xFF);
+ if (b != hsb[j])
+ throw new IOException("Target VM failed to handshake: unexpected byte #" + j
+ + ": " + b + " (expected:" + hsb[j] + ")");
+ }
+ return;
+ }
+ }
+
+ throw new IOException("Target VM failed to handshake: too few bytes in reply: "
+ + received + "(expected: " + hsb.length + ")");
+ }
+
+ /**
+ * Set timeout for reading data in milliseconds.
+ * Timeout of 0 means wait infinitly.
+ */
+ public abstract void setReadTimeout(long millisecs) throws IOException;
+
+ /**
+ * Close JDWP connection.
+ */
+ public abstract void close() throws IOException;
+
+ /**
+ * Perform finalization of object by closing JDWP connection.
+ */
+ protected void finalize() throws Throwable {
+ close();
+ }
+
+}