Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/jdwp/StackFrame/GetValues/getvalues001.java
41162 views
/*1* Copyright (c) 2001, 2021, 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.GetValues;2425import java.io.*;2627import nsk.share.*;28import nsk.share.jpda.*;29import nsk.share.jdwp.*;3031/**32* Test for JDWP command: StackFrame.GetValues.33*34* See getvalues001.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 getvalues001 {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 ERROR = "error";53static final String QUIT = "quit";5455// package and classes names constants56static final String PACKAGE_NAME = "nsk.jdwp.StackFrame.GetValues";57static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "getvalues001";58static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";5960// tested JDWP command constants61static final String JDWP_COMMAND_NAME = "StackFrame.GetValues";62static final int JDWP_COMMAND_ID = JDWP.Command.StackFrame.GetValues;6364// tested class name and signature constants65static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + getvalues001a.OBJECT_CLASS_NAME;66static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";6768// names of the static fields with the tested thread and object values69static final String TESTED_THREAD_FIELD_NAME = getvalues001a.THREAD_FIELD_NAME;70static final String TESTED_OBJECT_FIELD_NAME = getvalues001a.OBJECT_FIELD_NAME;71static final String TESTED_OBJECT_METHOD_NAME = getvalues001a.OBJECT_METHOD_NAME;7273// list of tested variables names and values74static final Object variables[][] = {75{ "booleanValue", "boolean", Boolean.valueOf(true), Byte.valueOf(JDWP.Tag.BOOLEAN)},76{ "byteValue", "byte", Byte.valueOf((byte)0x0F), Byte.valueOf(JDWP.Tag.BYTE) },77{ "charValue", "char", Character.valueOf('Z'), Byte.valueOf(JDWP.Tag.CHAR) },78{ "intValue", "int", Integer.valueOf(100), Byte.valueOf(JDWP.Tag.INT) },79{ "shortValue", "short", Short.valueOf((short)10), Byte.valueOf(JDWP.Tag.SHORT) },80{ "longValue", "long", Long.valueOf((long)1000000), Byte.valueOf(JDWP.Tag.LONG) },81{ "floatValue", "float", Float.valueOf((float)3.14), Byte.valueOf(JDWP.Tag.FLOAT) },82{ "doubleValue", "double", Double.valueOf((double)2.8e-12), Byte.valueOf(JDWP.Tag.DOUBLE) },83{ "objectValue", "objectID", Long.valueOf((long)0), Byte.valueOf(JDWP.Tag.OBJECT) }84};85static final int VARIABLES_COUNT = variables.length;8687// usual scaffold objects88ArgumentHandler argumentHandler = null;89Log log = null;90Binder binder = null;91Debugee debugee = null;92Transport transport = null;93IOPipe pipe = null;9495// test passed or not96boolean success = true;9798// -------------------------------------------------------------------99100/**101* Start test from command line.102*/103public static void main (String argv[]) {104System.exit(run(argv,System.out) + JCK_STATUS_BASE);105}106107/**108* Start JCK-compilant test.109*/110public static int run(String argv[], PrintStream out) {111return new getvalues001().runIt(argv, out);112}113114// -------------------------------------------------------------------115116/**117* Perform test execution.118*/119public int runIt(String argv[], PrintStream out) {120121// make log for debugger messages122argumentHandler = new ArgumentHandler(argv);123log = new Log(out, argumentHandler);124125// execute test and display results126try {127log.display("\n>>> Preparing debugee for testing \n");128129// launch debuggee130binder = new Binder(argumentHandler, log);131log.display("Launching debugee");132debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);133transport = debugee.getTransport();134pipe = debugee.createIOPipe();135136// make debuggee ready for testing137prepareDebugee();138139// work with prepared debuggee140long threadID = 0;141try {142log.display("\n>>> Obtaining requred data from debugee \n");143144// query debuggee for classID of tested class145log.display("Getting tested classID by signature:\n"146+ " " + TESTED_CLASS_SIGNATURE);147long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);148log.display(" got classID: " + classID);149150// query debuggee for tested methodID151log.display("Getting tested methodID by name: " + TESTED_OBJECT_METHOD_NAME);152long methodID = debugee.getMethodID(classID, TESTED_OBJECT_METHOD_NAME, true);153log.display(" got methodID: " + methodID);154155// query debugee for indexes of the method local variables156log.display("Getting indexes of the tested local variables for methodID: " + methodID);157int indexes[] = queryVariableIndexes(classID, methodID);158log.display(" got indexes: " + indexes.length);159160// query debuggee for tested objectID value from static field161log.display("Getting tested objectID value from static field: "162+ TESTED_OBJECT_FIELD_NAME);163long objectID = queryObjectID(classID, TESTED_OBJECT_FIELD_NAME, JDWP.Tag.OBJECT);164log.display(" got objectID: " + objectID);165166// query debuggee for tested threadID value from static field167log.display("Getting tested threadID value from static field: "168+ TESTED_THREAD_FIELD_NAME);169threadID = queryObjectID(classID, TESTED_THREAD_FIELD_NAME, JDWP.Tag.THREAD);170log.display(" got threadID: " + threadID);171172// suspend tested thread into debuggee173log.display("Suspending thread into debuggee for threadID: " + threadID);174debugee.suspendThread(threadID);175log.display(" thread suspended");176177// query debuggee for current frameID of the tested thread178log.display("Getting current frameID for the threadID: "179+ threadID);180long frameID = debugee.getCurrentFrameID(threadID);181log.display(" got frameID: " + frameID);182183// perform testing JDWP command184log.display("\n>>> Testing JDWP command \n");185testCommand(frameID, threadID, indexes);186187} finally {188log.display("\n>>> Finishing test \n");189190// resume suspended thread191if (threadID != 0) {192log.display("Resuming suspended thread");193debugee.resumeThread(threadID);194}195196// quit debugee197quitDebugee();198}199200} catch (Failure e) {201log.complain("TEST FAILED: " + e.getMessage());202success = false;203} catch (Exception e) {204e.printStackTrace(out);205log.complain("Caught unexpected exception while running the test:\n\t" + e);206success = false;207}208209if (!success) {210log.complain("TEST FAILED");211return FAILED;212}213214out.println("TEST PASSED");215return PASSED;216217}218219/**220* Prepare debugee for testing and waiting for ready signal.221*/222void prepareDebugee() {223// wait for VM_INIT event from debugee224log.display("Waiting for VM_INIT event");225debugee.waitForVMInit();226227// query debugee for VM-dependent ID sizes228log.display("Querying for IDSizes");229debugee.queryForIDSizes();230231// resume initially suspended debugee232log.display("Resuming debugee VM");233debugee.resume();234235// wait for READY signal from debugee236log.display("Waiting for signal from debugee: " + READY);237String signal = pipe.readln();238log.display("Received signal from debugee: " + signal);239if (signal == null) {240throw new TestBug("Null signal received from debugee: " + signal241+ " (expected: " + READY + ")");242} else if (signal.equals(ERROR)) {243throw new TestBug("Debugee was not able to start tested thread"244+ " (received signal: " + signal + ")");245} else if (!signal.equals(READY)) {246throw new TestBug("Unexpected signal received from debugee: " + signal247+ " (expected: " + READY + ")");248}249}250251/**252* Sending debugee signal to quit and waiting for it exits.253*/254void quitDebugee() {255// send debugee signal to quit256log.display("Sending signal to debugee: " + QUIT);257pipe.println(QUIT);258259// wait for debugee exits260log.display("Waiting for debugee exits");261int code = debugee.waitFor();262263// analize debugee exit status code264if (code == JCK_STATUS_BASE + PASSED) {265log.display("Debugee PASSED with exit code: " + code);266} else {267log.complain("Debugee FAILED with exit code: " + code);268success = false;269}270}271272/**273* Query debuggee for objectID value of static field of the class.274*/275long queryObjectID(long classID, String fieldName, byte tag) {276// get fieledID for static field (declared in the class)277long fieldID = debugee.getClassFieldID(classID, fieldName, true);278// get value of the field279JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);280281// check that value has expected tag282if (value.getTag() != tag) {283throw new Failure("Unexpected tag for object value returned: "284+ value.getTag() + " (expected: " + tag + ")");285}286287// extract objectID from the value288long objectID = ((Long)value.getValue()).longValue();289return objectID;290}291292/**293* Query debugee for indexes of the local method variables.294*/295int[] queryVariableIndexes(long classID, long methodID) {296// create array for expected indexes297int indexes[] = new int[VARIABLES_COUNT];298for (int i = 0; i < VARIABLES_COUNT; i++) {299indexes[i] = 0;300}301302// obtain variable indexes from debuggee303int count = 0;304try {305CommandPacket command = new CommandPacket(JDWP.Command.Method.VariableTable);306command.addReferenceTypeID(classID);307command.addMethodID(methodID);308command.setLength();309310ReplyPacket reply = debugee.receiveReplyFor(command);311reply.resetPosition();312313int argCount = reply.getInt();314long slots = reply.getInt();315if (slots < VARIABLES_COUNT) {316throw new Failure("Too few method local variables returned: " + slots317+ " (expected: at least " + VARIABLES_COUNT + ")");318}319320for (int i = 0; i < slots; i++ ) {321long codeindex = reply.getLong();322String name = reply.getString();323String signature = reply.getString();324int length = reply.getInt();325int slot = reply.getInt();326327for (int j = 0; j < VARIABLES_COUNT; j++) {328if (variables[j][0].equals(name)) {329indexes[j] = slot;330break;331}332}333}334335} catch (BoundException e) {336log.complain("Unable to extract local variable indexes from the reply packet:\n\t"337+ e.getMessage());338throw new Failure("Error occured while getting local variable indexes for methodID:"339+ methodID);340}341342return indexes;343}344345/**346* Check i-th value from the reply packet.347*/348void checkValue(int i, JDWP.Value value) {349if (!variables[i][2].equals(value.getValue())) {350log.complain("Unexpected value for " + i + " variable ("351+ variables[i][0] + ") received: " + value352+ " (expected: " + variables[i][2] + ")");353success = false;354}355}356357/**358* Perform testing JDWP command for specified frameID.359*/360void testCommand(long frameID, long threadID, int indexes[]) {361int slots = indexes.length;362363// create command packet and fill requred out data364log.display("Create command packet:");365log.display("Command: " + JDWP_COMMAND_NAME);366CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);367log.display(" threadID: " + threadID);368command.addObjectID(threadID);369log.display(" frameID: " + frameID);370command.addFrameID(frameID);371log.display(" slots: " + slots);372command.addInt(slots);373374// add code indexes of the requested variables375for (int i = 0; i < slots; i++) {376log.display(" slot #" + i + ":");377log.display(" slot: " + indexes[i]);378command.addInt(indexes[i]);379byte tag = ((Byte)variables[i][3]).byteValue();380log.display(" sigbyte: " + tag);381command.addByte(tag);382}383command.setLength();384385// send command packet to debugee386try {387log.display("Sending command packet:\n" + command);388transport.write(command);389} catch (IOException e) {390log.complain("Unable to send command packet:\n\t" + e);391success = false;392return;393}394395ReplyPacket reply = new ReplyPacket();396397// receive reply packet from debugee398try {399log.display("Waiting for reply packet");400transport.read(reply);401log.display("Reply packet received:\n" + reply);402} catch (IOException e) {403log.complain("Unable to read reply packet:\n\t" + e);404success = false;405return;406}407408// check reply packet header409try{410log.display("Checking reply packet header");411reply.checkHeader(command.getPacketID());412} catch (BoundException e) {413log.complain("Bad header of reply packet:\n\t" + e.getMessage());414success = false;415return;416}417418// start parsing reply packet data419log.display("Parsing reply packet:");420reply.resetPosition();421422// extract and check number of values423int values = 0;424try {425values = reply.getInt();426log.display(" values: " + values);427428} catch (BoundException e) {429log.complain("Unable to extract number of values form reply packet:\n\t"430+ e.getMessage());431success = false;432return;433}434435// check if number of values are as expected436if (values < 0) {437log.complain("Negative number of values received:" + values438+ " (expected: " + slots + ")");439success = false;440} else if (values != slots) {441log.complain("Unexpected number of values received:" + values442+ " (expected: " + slots + ")");443success = false;444}445446// extract and check each value447for (int i = 0; i < values; i++ ) {448log.display(" value #" + i + " (variable: " + variables[i][0] + ")");449450// extract value451JDWP.Value value = null;452try {453value = reply.getValue();454log.display(" slotValue: " + value);455} catch (BoundException e) {456log.complain("Unable to extract " + i + " slot value:\n\t"457+ e.getMessage());458success = false;459break;460}461462// extract and check value by known type tag463checkValue(i, value);464}465466// check for extra data in reply packet467if (!reply.isParsed()) {468log.complain("Extra trailing bytes found in reply packet at: "469+ reply.offsetString());470success = false;471}472473}474475}476477478