Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/jdwp/Method/IsObsolete/isobsolete002.java
41161 views
/*1* Copyright (c) 2001, 2020, 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.Method.IsObsolete;2425import java.io.*;2627import nsk.share.*;28import nsk.share.jpda.*;29import nsk.share.jdwp.*;3031/**32* Test for JDWP command: Method.IsObsolete.33*34* See isobsolete002.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 isobsolete002 {4445// exit status constants46static final int JCK_STATUS_BASE = 95;47static final int PASSED = 0;48static final int FAILED = 2;4950// VM capability constatnts51static final int VM_CAPABILITY_NUMBER = JDWP.Capability.CAN_REDEFINE_CLASSES;52static final String VM_CAPABILITY_NAME = "canRedefineClasses";5354// package and classes names55static final String PACKAGE_NAME = "nsk.jdwp.Method.IsObsolete";56static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "isobsolete002";57static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";5859// tested JDWP command60static final String JDWP_COMMAND_NAME = "Method.IsObsolete";61static final int JDWP_COMMAND_ID = JDWP.Command.Method.IsObsolete;6263// tested class name and signature64static final String TESTED_CLASS_NAME = TEST_CLASS_NAME + "b";65static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";6667// tested method name68static final String TESTED_METHOD_NAME = "testedMethod";69static final int BREAKPOINT_LINE = isobsolete002a.BREAKPOINT_LINE;7071// filename for redefined class72static final String REDEFINED_CLASS_FILE_NAME = "bin" + File.separator + "newclass"73+ File.separator + PACKAGE_NAME.replace('.', File.separatorChar)74+ File.separator + "isobsolete002b.class";7576// usual scaffold objects77ArgumentHandler argumentHandler = null;78Log log = null;79Binder binder = null;80Debugee debugee = null;81Transport transport = null;82int waitTime = 0; // minutes83long timeout = 0; // milliseconds84String testDir = null;85boolean dead = false;86boolean success = true;8788// data obtained from debuggee89long testedClassID = 0;90long testedMethodID = 0;9192// -------------------------------------------------------------------9394/**95* Start test from command line.96*/97public static void main (String argv[]) {98System.exit(run(argv,System.out) + JCK_STATUS_BASE);99}100101/**102* Start JCK-compilant test.103*/104public static int run(String argv[], PrintStream out) {105return new isobsolete002().runIt(argv, out);106}107108// -------------------------------------------------------------------109110/**111* Perform test execution.112*/113public int runIt(String argv[], PrintStream out) {114115// make log for debugger messages116argumentHandler = new ArgumentHandler(argv);117log = new Log(out, argumentHandler);118waitTime = argumentHandler.getWaitTime(); // minutes119timeout = waitTime * 60 * 1000; // milliseconds120121// get testDir as first positional parameter122String args[] = argumentHandler.getArguments();123if (args.length < 1) {124log.complain("Test dir required as the first positional argument");125return FAILED;126}127testDir = args[0];128129// execute test and display results130try {131log.display("\n>>> Loading redefined class \n");132133// launch debuggee134binder = new Binder(argumentHandler, log);135log.display("Launching debugee VM");136debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);137transport = debugee.getTransport();138log.display(" ... debuggee launched");139140// set timeout for debuggee responces141log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");142transport.setReadTimeout(timeout);143log.display(" ... timeout set");144145// wait for VM_INIT event146log.display("Waiting for VM_INIT event");147debugee.waitForVMInit();148log.display(" ... VM_INIT event received");149150// query debugee for VM-dependent ID sizes151log.display("Querying for IDSizes");152debugee.queryForIDSizes();153log.display(" ... size of VM-dependent types adjusted");154155// check for VM capability156log.display("\n>>> Checking VM capability \n");157log.display("Getting new VM capability: " + VM_CAPABILITY_NAME);158boolean capable = debugee.getNewCapability(VM_CAPABILITY_NUMBER, VM_CAPABILITY_NAME);159log.display(" ... got VM capability: " + capable);160161// exit as PASSED if this capability is not supported162if (!capable) {163out.println("TEST PASSED: unsupported VM capability: "164+ VM_CAPABILITY_NAME);165return PASSED;166}167168// prepare debuggee for testing and obtain required data169log.display("\n>>> Getting prepared for testing \n");170prepareForTest();171172// test JDWP command173log.display("\n>>> Testing JDWP command \n");174testCommand(testedMethodID, TESTED_METHOD_NAME);175176// finish debuggee177log.display("\n>> Finishing debuggee \n");178179// resume debuggee after testing command180log.display("Resuming debuggee");181debugee.resume();182log.display(" ... debuggee resumed");183184// wait for VM_DEATH event185log.display("Waiting for VM_DEATH event");186debugee.waitForVMDeath();187log.display(" ... VM_DEATH event received");188dead = true;189190} catch (Failure e) {191log.complain("TEST FAILED: " + e.getMessage());192success = false;193} catch (Exception e) {194e.printStackTrace(out);195log.complain("Caught unexpected exception while running the test:\n\t" + e);196success = false;197} finally {198log.display("\n>>> Finishing test \n");199200// disconnect debugee and wait for its exit201if (debugee != null) {202quitDebugee();203}204}205206// check result207if (!success) {208log.complain("TEST FAILED");209return FAILED;210}211out.println("TEST PASSED");212return PASSED;213}214215/**216* Get debuggee prepared for testing and obtain required data.217*/218void prepareForTest() {219// wait for debuggee and tested classes loaded on debuggee startup220log.display("Waiting for classes loaded:"221+ "\n\t" + TESTED_CLASS_NAME);222testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME,223JDWP.SuspendPolicy.ALL);224log.display(" ... class loaded with classID: " + testedClassID);225log.display("");226227/*228// get tested methodID by names229log.display("Getting methodID for method name :" + TESTED_METHOD_NAME);230testedMethodID = debugee.getMethodID(testedClassID, TESTED_METHOD_NAME, true);231log.display(" ... got methodID: " + testedMethodID);232log.display("");233*/234235// wait for breakpoint reached236log.display("Waiting for breakpoint reached at: "237+ TESTED_METHOD_NAME + ":" + BREAKPOINT_LINE);238long threadID = debugee.waitForBreakpointReached(testedClassID,239TESTED_METHOD_NAME,240BREAKPOINT_LINE,241JDWP.SuspendPolicy.ALL);242log.display(" ... breakpoint reached with threadID: " + threadID);243log.display("");244245// load class file for redefined class246log.display("Loading bytecode of redefined class from file: " +247REDEFINED_CLASS_FILE_NAME);248byte[] classBytes = loadClassBytes(REDEFINED_CLASS_FILE_NAME, testDir);249log.display(" ... loaded bytes: " + classBytes.length);250251// redefine class252log.display("Redefine class by classID: " + testedClassID);253redefineClass(testedClassID, classBytes);254log.display(" ... class redefined");255log.display("");256257// get top frameID of the thread258log.display("Getting top frameID of the threadID: " + threadID);259JDWP.Location location = queryTopFrameLocation(threadID);260log.display(" ... got location: " + location);261262// get methodID of the top frameID263log.display("Getting methodID for the location :" + location);264testedMethodID = location.getMethodID();265log.display(" ... got methodID: " + testedMethodID);266log.display("");267268}269270/**271* Perform testing JDWP command for given methodID.272*/273void testCommand(long testedMethodID, String methodName) {274// create command packet and fill requred out data275log.display("Create command packet:");276log.display("Command: " + JDWP_COMMAND_NAME);277CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);278log.display(" refTypeID: " + testedClassID);279command.addReferenceTypeID(testedClassID);280log.display(" methodID: " + testedMethodID);281command.addMethodID(testedMethodID);282command.setLength();283284// send command packet to debugee285try {286log.display("Sending command packet:\n" + command);287transport.write(command);288} catch (IOException e) {289log.complain("Unable to send command packet for method " + methodName + ":\n\t" + e);290success = false;291return;292}293294// receive reply packet from debugee295ReplyPacket reply = new ReplyPacket();296try {297log.display("Waiting for reply packet");298transport.read(reply);299log.display(" ... reply packet received:\n" + reply);300} catch (IOException e) {301log.complain("Unable to read reply packet for method " + methodName + ":\n\t" + e);302success = false;303return;304}305306// check reply packet header307try{308log.display("Checking header of reply packet");309reply.checkHeader(command.getPacketID());310log.display(" ... packet header is correct");311} catch (BoundException e) {312log.complain("Wrong header of reply packet for method " + methodName + ":\n\t"313+ e.getMessage());314success = false;315return;316}317318// start parsing reply packet data319log.display("Parsing reply packet data:");320reply.resetPosition();321322// extract boolean isObsolete323byte isObsolete = 0;324try {325isObsolete = reply.getByte();326log.display(" isObsolete: " + isObsolete);327} catch (BoundException e) {328log.complain("Unable to extract isObsolete value from reply packet for method "329+ methodName + ":\n\t" + e.getMessage());330success = false;331}332333// check isObsolete334if (isObsolete == 0) {335log.complain("Unexpected isObsolete value for method "336+ methodName + ": " + isObsolete + " (expected: not " + 0 + ")");337success = false;338}339340// check for extra data in reply packet341if (!reply.isParsed()) {342log.complain("Extra trailing bytes in reply packet for "343+ methodName + " method at: " + reply.offsetString());344success = false;345}346347log.display(" ... packed data parsed");348}349350/**351* Redefine class bytes for given classID.352*/353void redefineClass(long classID, byte[] classBytes) {354int length = classBytes.length;355356CommandPacket command = new CommandPacket(JDWP.Command.VirtualMachine.RedefineClasses);357command.addInt(1);358command.addReferenceTypeID(classID);359command.addInt(length);360command.addBytes(classBytes, 0, length);361362// receive reply packet from debugee363ReplyPacket reply = debugee.receiveReplyFor(command, "VirtualMachine.RedefineClasses");364}365366/**367* Query debuggee VM for top frameID of the thread.368*/369JDWP.Location queryTopFrameLocation(long threadID) {370String error = "Error occured while getting top frameID for threadID: " + threadID;371372CommandPacket command = new CommandPacket(JDWP.Command.ThreadReference.Frames);373command.addObjectID(threadID);374command.addInt(0);375command.addInt(1);376command.setLength();377378ReplyPacket reply = debugee.receiveReplyFor(command, "ThreadReference.Frames");379reply.resetPosition();380381// extract number of frames382int frames = 0;383try {384frames = reply.getInt();385} catch (BoundException e) {386log.complain("Unable to extract number of frames from reply packet:\n\t"387+ e.getMessage());388throw new Failure(error);389}390391// check frames count392if (frames != 1) {393log.complain("Unexpected number of frames returned: "394+ frames + " (expected: " + 1 + ")");395throw new Failure(error);396}397398// extract frame ID399long frameID = 0;400try {401frameID = reply.getFrameID();402} catch (BoundException e) {403log.complain("Unable to extract top frameID from reply packet:\n\t"404+ e.getMessage());405throw new Failure(error);406}407408// extract frame location409JDWP.Location location = null;410try {411location = reply.getLocation();412} catch (BoundException e) {413log.complain("Unable to extract location for top frame from reply packet:\n\t"414+ e.getMessage());415throw new Failure(error);416}417418return location;419}420421422/**423* Load class bytes form the given file.424*/425byte[] loadClassBytes(String fileName, String dirName) {426String fileSep = System.getProperty("file.separator");427String filePath = dirName + fileSep + fileName;428429String error = "Unable to read bytes from class file:\n\t" + filePath;430431int length = 0;432byte bytes[] = null;433try {434File file = new File(filePath);435length = (int)file.length();436FileInputStream is = new FileInputStream(file);437bytes = new byte[length];438int number = is.read(bytes);439if (number < 0) {440log.complain("EOF reached while reading bytes from file");441throw new Failure(error);442} else if (number != length) {443log.complain("Unexpected number of bytes red from file: " + number444+ " (expected: " + length + ")");445throw new Failure(error);446}447is.close();448} catch ( IOException e ) {449log.complain("Caught IOException while reading bytes from file:\n\t" + e);450throw new Failure(error);451}452return bytes;453}454455/**456* Disconnect debuggee and wait for it exited.457*/458void quitDebugee() {459if (debugee == null)460return;461462// disconnect debugee463if (!dead) {464try {465log.display("Disconnecting debuggee");466debugee.dispose();467log.display(" ... debuggee disconnected");468} catch (Failure e) {469log.display("Failed to finally disconnect debuggee:\n\t"470+ e.getMessage());471}472}473474// wait for debugee exited475log.display("Waiting for debuggee exit");476int code = debugee.waitFor();477log.display(" ... debuggee exited with exit code: " + code);478479// analize debugee exit status code480if (code != JCK_STATUS_BASE + PASSED) {481log.complain("Debuggee FAILED with exit code: " + code);482success = false;483}484}485}486487488