Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/SetValues/setvalues001.java
41162 views
/*1* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223package nsk.jdwp.StackFrame.SetValues;2425import java.io.*;2627import nsk.share.*;28import nsk.share.jpda.*;29import nsk.share.jdwp.*;3031/**32* Test for JDWP command: StackFrame.SetValues.33*34* See setvalues001.README for description of test execution.35*36* This class represents debugger part of the test.37* Test is executed by invoking method runIt().38* JDWP command is tested in the method testCommand().39*40* @see #runIt()41* @see #testCommand()42*/43public class setvalues001 {4445// exit status constants46static final int JCK_STATUS_BASE = 95;47static final int PASSED = 0;48static final int FAILED = 2;4950// communication signals constants51static final String READY = "ready";52static final String RUN = "run";53static final String DONE = "done";54static final String ERROR = "error";55static final String QUIT = "quit";5657// package and classes names constants58static final String PACKAGE_NAME = "nsk.jdwp.StackFrame.SetValues";59static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "setvalues001";60static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";6162// tested JDWP command constants63static final String JDWP_COMMAND_NAME = "StackFrame.SetValues";64static final int JDWP_COMMAND_ID = JDWP.Command.StackFrame.SetValues;6566// tested class name and signature constants67static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + setvalues001a.OBJECT_CLASS_NAME;68static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";6970// target values class name and signature constants71static final String TARGET_VALUES_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TargetValuesClass";72static final String TARGET_VALUES_CLASS_SIGNATURE = "L" + TARGET_VALUES_CLASS_NAME.replace('.', '/') + ";";7374// names of the static fields with the tested thread and object values75static final String TESTED_THREAD_FIELD_NAME = setvalues001a.THREAD_FIELD_NAME;76static final String TESTED_OBJECT_FIELD_NAME = setvalues001a.OBJECT_FIELD_NAME;77static final String TESTED_OBJECT_METHOD_NAME = setvalues001a.OBJECT_METHOD_NAME;7879// list of tested variables names and values80static final Object variables[] = {81"booleanValue",82"byteValue",83"charValue",84"intValue",85"shortValue",86"longValue",87"floatValue",88"doubleValue",89"stringValue",90"objectValue"91};92static final int VARIABLES_COUNT = variables.length;9394// usual scaffold objects95ArgumentHandler argumentHandler = null;96Log log = null;97Binder binder = null;98Debugee debugee = null;99Transport transport = null;100IOPipe pipe = null;101102// test passed or not103boolean success = true;104105// -------------------------------------------------------------------106107/**108* Start test from command line.109*/110public static void main (String argv[]) {111System.exit(run(argv,System.out) + JCK_STATUS_BASE);112}113114/**115* Start JCK-compilant test.116*/117public static int run(String argv[], PrintStream out) {118return new setvalues001().runIt(argv, out);119}120121// -------------------------------------------------------------------122123/**124* Perform test execution.125*/126public int runIt(String argv[], PrintStream out) {127128// make log for debugger messages129argumentHandler = new ArgumentHandler(argv);130log = new Log(out, argumentHandler);131132// execute test and display results133try {134log.display("\n>>> Preparing debugee for testing \n");135136// launch debuggee137binder = new Binder(argumentHandler, log);138log.display("Launching debugee");139debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);140transport = debugee.getTransport();141pipe = debugee.createIOPipe();142143// make debuggee ready for testing144prepareDebugee();145146// work with prepared debuggee147long threadID = 0;148try {149log.display("\n>>> Obtaining requred data from debugee \n");150151// get target values from static fields152153// query debugee for classID for the class with target values154log.display("Getting classID for class with target values by signature:\n"155+ " " + TARGET_VALUES_CLASS_SIGNATURE);156long targetValuesClassID =157debugee.getReferenceTypeID(TARGET_VALUES_CLASS_SIGNATURE);158log.display(" got classID: " + targetValuesClassID);159160// query debugee for fieldIDs of the class static fields161log.display("Getting fieldIDs for static fields of the class");162long fieldIDs[] = queryClassFieldIDs(targetValuesClassID);163log.display(" got fields: " + fieldIDs.length);164165// query debugee for values of the fields166log.display("Getting values of the static fields");167JDWP.Value values[] =168queryClassFieldValues(targetValuesClassID, fieldIDs);169log.display(" got values: " + values.length);170171// get indexes of local variables172173// query debugee for classID of the tested class174log.display("Getting tested classID by signature:\n"175+ " " + TESTED_CLASS_SIGNATURE);176long testedClassID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);177log.display(" got classID: " + testedClassID);178179// query debuggee for tested methodID180log.display("Getting tested methodID by name: " + TESTED_OBJECT_METHOD_NAME);181long methodID = debugee.getMethodID(testedClassID, TESTED_OBJECT_METHOD_NAME, true);182log.display(" got methodID: " + methodID);183184// query debugee for indexes of the method local variables185log.display("Getting indexes of the tested local variables for methodID: " + methodID);186int indexes[] = queryVariableIndexes(testedClassID, methodID);187log.display(" got indexes: " + indexes.length);188189// get tested objectID and threadID from static fields190191// query debuggee for tested objectID value from static field192log.display("Getting tested objectID value from static field: "193+ TESTED_OBJECT_FIELD_NAME);194long objectID = queryObjectID(testedClassID, TESTED_OBJECT_FIELD_NAME, JDWP.Tag.OBJECT);195log.display(" got objectID: " + objectID);196197// query debuggee for tested threadID value from static field198log.display("Getting tested threadID value from static field: "199+ TESTED_THREAD_FIELD_NAME);200threadID = queryObjectID(testedClassID, TESTED_THREAD_FIELD_NAME, JDWP.Tag.THREAD);201log.display(" got threadID: " + threadID);202203// suspend tested thread into debuggee204log.display("Suspending thread into debuggee for threadID: " + threadID);205debugee.suspendThread(threadID);206log.display(" thread suspended");207208// get current frameID and test JDWP command209210// query debuggee for current frameID of the tested thread211log.display("Getting current frameID for the threadID: "212+ threadID);213long frameID = debugee.getCurrentFrameID(threadID);214log.display(" got frameID: " + frameID);215216// perform testing JDWP command217log.display("\n>>> Testing JDWP command \n");218testCommand(frameID, threadID, indexes, values);219220// check confirmation from debuggee that values have been set correctly221log.display("\n>>> Checking that the values have been set correctly \n");222223log.display("Resuming suspended thread");224debugee.resumeThread(threadID);225226checkValuesChanged();227228} finally {229log.display("\n>>> Finishing test \n");230231// resume suspended thread232if (threadID != 0) {233log.display("Finally resuming potentially suspended thread");234debugee.resumeThread(threadID);235}236237// quit debugee238quitDebugee();239}240241} catch (Failure e) {242log.complain("TEST FAILED: " + e.getMessage());243success = false;244} catch (Exception e) {245e.printStackTrace(out);246log.complain("Caught unexpected exception while running the test:\n\t" + e);247success = false;248}249250if (!success) {251log.complain("TEST FAILED");252return FAILED;253}254255out.println("TEST PASSED");256return PASSED;257258}259260/**261* Prepare debugee for testing and waiting for ready signal.262*/263void prepareDebugee() {264// wait for VM_INIT event from debugee265log.display("Waiting for VM_INIT event");266debugee.waitForVMInit();267268// query debugee for VM-dependent ID sizes269log.display("Querying for IDSizes");270debugee.queryForIDSizes();271272// resume initially suspended debugee273log.display("Resuming debugee VM");274debugee.resume();275276// wait for READY signal from debugee277log.display("Waiting for signal from debugee: " + READY);278String signal = pipe.readln();279log.display("Received signal from debugee: " + signal);280if (signal == null) {281throw new TestBug("Null signal received from debugee: " + signal282+ " (expected: " + READY + ")");283} else if (signal.equals(ERROR)) {284throw new TestBug("Debugee was not able to start tested thread"285+ " (received signal: " + signal + ")");286} else if (!signal.equals(READY)) {287throw new TestBug("Unexpected signal received from debugee: " + signal288+ " (expected: " + READY + ")");289}290}291292/**293* Sending debugee signal to quit and waiting for it exits.294*/295void quitDebugee() {296// send debugee signal to quit297log.display("Sending signal to debugee: " + QUIT);298pipe.println(QUIT);299300// wait for debugee exits301log.display("Waiting for debugee exits");302int code = debugee.waitFor();303304// analize debugee exit status code305if (code == JCK_STATUS_BASE + PASSED) {306log.display("Debugee PASSED with exit code: " + code);307} else {308log.complain("Debugee FAILED with exit code: " + code);309success = false;310}311}312313/**314* Query debuggee for objectID value of static field of the class.315*/316long queryObjectID(long classID, String fieldName, byte tag) {317// get fieledID for static field (declared in the class)318long fieldID = debugee.getClassFieldID(classID, fieldName, true);319// get value of the field320JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);321322// check that value has expected tag323if (value.getTag() != tag) {324throw new Failure("Unexpected tag for object value returned: "325+ value.getTag() + " (expected: " + tag + ")");326}327328// extract objectID from the value329long objectID = ((Long)value.getValue()).longValue();330return objectID;331}332333/**334* Query debugee for indexes of the local method variables.335*/336int[] queryVariableIndexes(long classID, long methodID) {337// create array for expected indexes338int indexes[] = new int[VARIABLES_COUNT];339for (int i = 0; i < VARIABLES_COUNT; i++) {340indexes[i] = 0;341}342343// obtain variable indexes from debuggee344int count = 0;345try {346CommandPacket command = new CommandPacket(JDWP.Command.Method.VariableTable);347command.addReferenceTypeID(classID);348command.addMethodID(methodID);349command.setLength();350351ReplyPacket reply = debugee.receiveReplyFor(command);352reply.resetPosition();353354int argCount = reply.getInt();355long slots = reply.getInt();356357for (int i = 0; i < slots; i++ ) {358long codeindex = reply.getLong();359String name = reply.getString();360String signature = reply.getString();361int length = reply.getInt();362int slot = reply.getInt();363364for (int j = 0; j < VARIABLES_COUNT; j++) {365if (variables[j].equals(name)) {366indexes[j] = slot;367break;368}369}370}371372} catch (BoundException e) {373log.complain("Unable to extract local variable indexes from the reply packet:\n\t"374+ e.getMessage());375throw new Failure("Error occured while getting local variable indexes for methodID:"376+ methodID);377}378379// check that all expected fieldIDs received380int notfound = 0;381for (int i = 0; i < VARIABLES_COUNT; i++) {382if(indexes[i] == 0) {383log.complain("Not found index for local variable: " + variables[i]);384notfound++;385}386}387if (notfound > 0) {388throw new Failure("Unable to get indexes for " + notfound +389" local variables for methodID: " + methodID);390}391return indexes;392}393394/**395* Query debugee for fieldID's of the class static fields.396*/397long[] queryClassFieldIDs(long classID) {398399// create array of fieldID's corresponding to tested variables400long[] fieldIDs = new long[VARIABLES_COUNT];401for (int i = 0; i < VARIABLES_COUNT; i++) {402fieldIDs[i] = 0;403}404405// compose ReferenceType.Fields command packet406CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.Fields);407command.addReferenceTypeID(classID);408command.setLength();409410// send the command and receive reply411ReplyPacket reply = debugee.receiveReplyFor(command);412413// extract fieldIDs from the reply packet414try {415reply.resetPosition();416417int declared = reply.getInt();418419for (int i = 0; i < declared; i++ ) {420long fieldID = reply.getFieldID();421String name = reply.getString();422String signature = reply.getString();423int modBits = reply.getInt();424425// find variable with the same name426for (int j = 0; j < VARIABLES_COUNT; j++) {427if (variables[j].equals(name)) {428fieldIDs[j] = fieldID;429}430}431}432} catch (BoundException e) {433log.complain("Unable to parse reply packet for ReferenceType.Fields command:\n\t"434+ e);435log.complain("Received reply packet:\n"436+ reply);437throw new Failure("Error occured while getting static fieldIDs for classID: " + classID);438}439440// check that all expected fieldIDs received441int notfound = 0;442for (int i = 0; i < VARIABLES_COUNT; i++) {443if(fieldIDs[i] == 0) {444log.complain("Not found fieldID for static field: " + variables[i]);445notfound++;446}447}448if (notfound > 0) {449throw new Failure("Unable to get fiedIDs for " + notfound +450" static fields for classID: " + classID);451}452return fieldIDs;453}454455/**456* Query debugee for values of the class fields.457*/458JDWP.Value[] queryClassFieldValues(long classID, long fieldIDs[]) {459// compose ReferenceType.Fields command packet460int count = fieldIDs.length;461CommandPacket command = new CommandPacket(JDWP.Command.ReferenceType.GetValues);462command.addReferenceTypeID(classID);463command.addInt(count);464for (int i = 0; i < count; i++) {465command.addFieldID(fieldIDs[i]);466}467command.setLength();468469// send the command and receive reply470ReplyPacket reply = debugee.receiveReplyFor(command);471472// extract values from the reply packet473try {474reply.resetPosition();475476int valuesCount = reply.getInt();477if (valuesCount != count) {478throw new Failure("Unexpected number of values of static fields returned: "479+ valuesCount + " (expected: " + count + ")");480}481482JDWP.Value values[] = new JDWP.Value[valuesCount];483for (int i = 0; i < valuesCount; i++ ) {484JDWP.Value value = reply.getValue();485values[i] = value;486}487return values;488} catch (BoundException e) {489log.complain("Unable to parse reply packet for ReferenceType.SetValues command:\n\t"490+ e);491log.complain("Received reply packet:\n"492+ reply);493throw new Failure("Error occured while getting static fields values for classID: " + classID);494}495}496497/**498* Perform testing JDWP command for specified frameID.499*/500void testCommand(long frameID, long threadID, int indexes[], JDWP.Value values[]) {501// create command packet and fill requred out data502log.display("Create command packet:");503log.display("Command: " + JDWP_COMMAND_NAME);504CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);505log.display(" threadID: " + threadID);506command.addObjectID(threadID);507log.display(" frameID: " + frameID);508command.addFrameID(frameID);509log.display(" slotValues: " + VARIABLES_COUNT);510command.addInt(VARIABLES_COUNT);511512// add indexes and new values of the tested variables513for (int i = 0; i < VARIABLES_COUNT; i++) {514log.display(" slot #" + i + ":");515log.display(" slot: " + indexes[i]);516command.addInt(indexes[i]);517log.display(" slotvalue: " + values[i]);518command.addValue(values[i]);519}520command.setLength();521522// send command packet to debugee523try {524log.display("Sending command packet:\n" + command);525transport.write(command);526} catch (IOException e) {527log.complain("Unable to send command packet:\n\t" + e);528success = false;529return;530}531532ReplyPacket reply = new ReplyPacket();533534// receive reply packet from debugee535try {536log.display("Waiting for reply packet");537transport.read(reply);538log.display("Reply packet received:\n" + reply);539} catch (IOException e) {540log.complain("Unable to read reply packet:\n\t" + e);541success = false;542return;543}544545// check reply packet header546try{547log.display("Checking reply packet header");548reply.checkHeader(command.getPacketID());549} catch (BoundException e) {550log.complain("Bad header of reply packet:\n\t" + e.getMessage());551success = false;552return;553}554555// start parsing reply packet data556log.display("Parsing reply packet:");557reply.resetPosition();558559// no data in the reply packet560561// check for extra data in reply packet562if (!reply.isParsed()) {563log.complain("Extra trailing bytes found in reply packet at: "564+ reply.offsetString());565success = false;566}567568}569570/**571* Check confiramtion from debuggee that values are changed.572*/573void checkValuesChanged() {574// send debugee signal RUN575log.display("Sending signal to debugee: " + RUN);576pipe.println(RUN);577578// wait for DONE signal from debugee579log.display("Waiting for signal from debugee: " + DONE);580String signal = pipe.readln();581log.display("Received signal from debugee: " + signal);582583// check received signal584if (signal == null) {585throw new TestBug("<null> signal received from debugee: " + signal586+ " (expected: " + DONE + ")");587} else if (signal.equals(DONE)) {588log.display("All varaible values have been correctly set into debuggee VM");589} else if (signal.equals(ERROR)) {590log.complain("Not all variables values have been correctly set into debuggee VM");591success = false;592} else {593throw new TestBug("Unexpected signal received from debugee: " + signal594+ " (expected: " + DONE + ")");595}596}597598}599600601