Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ThreadReference/Frames/frames001.java
41161 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.ThreadReference.Frames;2425import java.io.*;2627import nsk.share.*;28import nsk.share.jpda.*;29import nsk.share.jdwp.*;3031/**32* Test for JDWP command: ThreadReference.Frames.33*34* See frames001.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 frames001 {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.ThreadReference.Frames";57static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "frames001";58static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";5960// tested JDWP command constants61static final String JDWP_COMMAND_NAME = "ThreadReference.Frames";62static final int JDWP_COMMAND_ID = JDWP.Command.ThreadReference.Frames;6364// tested class name and signature constants65static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedClass";66static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";6768// name of the tested thread and statioc field with thread value69static final String TESTED_CLASS_FIELD_NAME = frames001a.FIELD_NAME;70static final String TESTED_THREAD_NAME = frames001a.THREAD_NAME;7172// names of the methods with frames73static final String TESTED_METHOD_NAME = frames001a.METHOD_NAME;74static final String RUN_METHOD_NAME = "run";7576// expected number of frames count77static final int START_FRAME_INDEX = 2;78static final int FRAMES_COUNT = frames001a.FRAMES_COUNT - START_FRAME_INDEX;7980// usual scaffold objects81ArgumentHandler argumentHandler = null;82Log log = null;83Binder binder = null;84Debugee debugee = null;85Transport transport = null;86IOPipe pipe = null;8788// test passed or not89boolean success = true;9091// -------------------------------------------------------------------9293/**94* Start test from command line.95*/96public static void main (String argv[]) {97System.exit(run(argv,System.out) + JCK_STATUS_BASE);98}99100/**101* Start JCK-compilant test.102*/103public static int run(String argv[], PrintStream out) {104return new frames001().runIt(argv, out);105}106107// -------------------------------------------------------------------108109/**110* Perform test execution.111*/112public int runIt(String argv[], PrintStream out) {113114// make log for debugger messages115argumentHandler = new ArgumentHandler(argv);116log = new Log(out, argumentHandler);117118// execute test and display results119try {120log.display("\n>>> Preparing debugee for testing \n");121122// launch debuggee123binder = new Binder(argumentHandler, log);124log.display("Launching debugee");125debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);126transport = debugee.getTransport();127pipe = debugee.createIOPipe();128129// make debuggee ready for testing130prepareDebugee();131132// work with prepared debuggee133long threadID = 0;134try {135log.display("\n>>> Obtaining requred data from debugee \n");136137// query debuggee for classID of tested class138log.display("Getting classID by signature:\n"139+ " " + TESTED_CLASS_SIGNATURE);140long classID = debugee.getReferenceTypeID(TESTED_CLASS_SIGNATURE);141log.display(" got classID: " + classID);142143// query debuggee for methodID of the recursive method144log.display("Getting methodID by name: " + TESTED_METHOD_NAME);145long methodID = debugee.getMethodID(classID, TESTED_METHOD_NAME, true);146log.display(" got methodID: " + methodID);147148// query debuggee for methodID of the run() method149log.display("Getting methodID by name: " + RUN_METHOD_NAME);150long runMethodID = debugee.getMethodID(classID, RUN_METHOD_NAME, true);151log.display(" got methodID: " + runMethodID);152153// query debuggee for threadID value from a static field154log.display("Getting threadID value from static field: "155+ TESTED_CLASS_FIELD_NAME);156threadID = queryThreadID(classID, TESTED_CLASS_FIELD_NAME);157log.display(" got threadID: " + threadID);158159// suspend tested thread into debyggee160log.display("Suspending thread into debuggee for threadID: " + threadID);161debugee.suspendThread(threadID);162log.display(" thread suspended");163164// perform testing JDWP command165log.display("\n>>> Testing JDWP command \n");166testCommand(threadID, methodID, runMethodID, classID);167168} finally {169log.display("\n>>> Finishing test \n");170171// resume suspended thread172if (threadID != 0) {173log.display("Resuming suspended thread");174debugee.resumeThread(threadID);175}176177// quit debugee178quitDebugee();179}180181} catch (Failure e) {182log.complain("TEST FAILED: " + e.getMessage());183success = false;184} catch (Exception e) {185e.printStackTrace(out);186log.complain("Caught unexpected exception while running the test:\n\t" + e);187success = false;188}189190if (!success) {191log.complain("TEST FAILED");192return FAILED;193}194195out.println("TEST PASSED");196return PASSED;197198}199200/**201* Prepare debugee for testing and waiting for ready signal.202*/203void prepareDebugee() {204// wait for VM_INIT event from debugee205log.display("Waiting for VM_INIT event");206debugee.waitForVMInit();207208// query debugee for VM-dependent ID sizes209log.display("Querying for IDSizes");210debugee.queryForIDSizes();211212// resume initially suspended debugee213log.display("Resuming debugee VM");214debugee.resume();215216// wait for READY signal from debugee217log.display("Waiting for signal from debugee: " + READY);218String signal = pipe.readln();219log.display("Received signal from debugee: " + signal);220if (signal == null) {221throw new TestBug("Null signal received from debugee: " + signal222+ " (expected: " + READY + ")");223} else if (signal.equals(ERROR)) {224throw new TestBug("Debugee was not able to start tested thread"225+ " (received signal: " + signal + ")");226} else if (!signal.equals(READY)) {227throw new TestBug("Unexpected signal received from debugee: " + signal228+ " (expected: " + READY + ")");229}230}231232/**233* Sending debugee signal to quit and waiting for it exits.234*/235void quitDebugee() {236// send debugee signal to quit237log.display("Sending signal to debugee: " + QUIT);238pipe.println(QUIT);239240// wait for debugee exits241log.display("Waiting for debugee exits");242int code = debugee.waitFor();243244// analize debugee exit status code245if (code == JCK_STATUS_BASE + PASSED) {246log.display("Debugee PASSED with exit code: " + code);247} else {248log.complain("Debugee FAILED with exit code: " + code);249success = false;250}251}252253/**254* Query debuggee for threadID value of statuic field of the class.255*/256long queryThreadID(long classID, String fieldName) {257// get fieledID for static field (declared in the class)258long fieldID = debugee.getClassFieldID(classID, fieldName, true);259// get value of the field260JDWP.Value value = debugee.getStaticFieldValue(classID, fieldID);261262// check that value has THREAD tag263if (value.getTag() != JDWP.Tag.THREAD) {264throw new Failure("Not threadID value returned from debuggee: " + value);265}266267// extract threadID from the value268long threadID = ((Long)value.getValue()).longValue();269return threadID;270}271272/**273* Perform testing JDWP command for specified threadID.274*/275void testCommand(long threadID, long methodID, long runMethodID, long classID) {276// create command packet and fill requred out data277log.display("Create command packet:");278log.display("Command: " + JDWP_COMMAND_NAME);279CommandPacket command = new CommandPacket(JDWP_COMMAND_ID);280log.display(" threadID: " + threadID);281command.addObjectID(threadID);282log.display(" startFrame: " + START_FRAME_INDEX);283command.addInt(START_FRAME_INDEX);284log.display(" length: " + FRAMES_COUNT);285command.addInt(FRAMES_COUNT);286command.setLength();287288// send command packet to debugee289try {290log.display("Sending command packet:\n" + command);291transport.write(command);292} catch (IOException e) {293log.complain("Unable to send command packet:\n\t" + e);294success = false;295return;296}297298ReplyPacket reply = new ReplyPacket();299300// receive reply packet from debugee301try {302log.display("Waiting for reply packet");303transport.read(reply);304log.display("Reply packet received:\n" + reply);305} catch (IOException e) {306log.complain("Unable to read reply packet:\n\t" + e);307success = false;308return;309}310311// check reply packet header312try{313log.display("Checking reply packet header");314reply.checkHeader(command.getPacketID());315} catch (BoundException e) {316log.complain("Bad header of reply packet:\n\t" + e.getMessage());317success = false;318return;319}320321// start parsing reply packet data322log.display("Parsing reply packet:");323reply.resetPosition();324325// extract number of frames326int frames = 0;327try {328frames = reply.getInt();329log.display(" frames: " + frames);330} catch (BoundException e) {331log.complain("Unable to extract number of frames from reply packet:\n\t"332+ e.getMessage());333success = false;334return;335}336337// check that frames count is not negative338if (frames < 0) {339log.complain("Negative value of frames count in reply packet: "340+ frames);341success = false;342}343344// check that thread has an expected state345if (frames != FRAMES_COUNT) {346log.complain("Unexpected number of frames returned: "347+ frames + " (expected: " + FRAMES_COUNT + ")");348success = false;349}350351// use methodID of the recursive method to check all frames except the last one352long checkedMethodID = methodID;353354// extarct frame IDs and locations355for (int i = 0; i < frames; i++) {356357log.display(" frame #" + i + ":");358359// extract frame ID360long frameID = 0;361try {362frameID = reply.getFrameID();363log.display(" frameID: " + frameID);364} catch (BoundException e) {365log.complain("Unable to extract " + i + " frameID from reply packet:\n\t"366+ e.getMessage());367success = false;368return;369}370371// extract frame location372JDWP.Location location = null;373try {374location = reply.getLocation();375log.display(" location: " + location);376} catch (BoundException e) {377e.printStackTrace(log.getOutStream());378log.complain("Unable to extract " + i + " frame location from reply packet:\n\t"379+ e.getMessage());380success = false;381return;382}383384// check that frameID is not negative integer385if (frameID < 0) {386log.complain("Negative value of " + i + " frameID: "387+ frameID);388success = false;389}390391// check that type tag of location is CLASS tag392if (location.getTag() != JDWP.TypeTag.CLASS) {393log.complain("Unexpected type tag of " + i + " frame location: "394+ location.getTag() + "(expected: " + JDWP.TypeTag.CLASS + ")");395success = false;396}397398// check that classID of location is equal to original classID399if (location.getClassID() != classID) {400log.complain("Unexpected classID of " + i + " frame location: "401+ location.getClassID() + "(expected: " + classID + ")");402success = false;403}404405// use methodID of run() method for checking last frame406if (i == frames - 1) {407checkedMethodID = runMethodID;408}409410// check that methodID of location is equal to one of original methodIDs411if (location.getMethodID() != checkedMethodID) {412log.complain("Unexpected methodID of " + i + " frame location: "413+ location.getMethodID() + "(expected: " + checkedMethodID + ")");414success = false;415}416417// check that code index of location is not negative integer418if (location.getIndex() < 0) {419log.complain("Negative value of index of " + i + " frame location: "420+ location.getIndex());421success = false;422}423424}425426// check for extra data in reply packet427if (!reply.isParsed()) {428log.complain("Extra trailing bytes found in reply packet at: "429+ reply.offsetString());430success = false;431}432433}434435}436437438