Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/jdi/BScenarios/hotswap/tc10x002.java
41161 views
/*1* Copyright (c) 2002, 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.jdi.BScenarios.hotswap;2425import nsk.share.*;26import nsk.share.jpda.*;27import nsk.share.jdi.*;2829import com.sun.jdi.*;30import com.sun.jdi.request.*;31import com.sun.jdi.event.*;3233import java.util.*;34import java.io.*;3536/**37* This test is from the group of so-called Borland's scenarios and38* implements the following test case: <br>39* Suite 3 - Hot Swap <br>40* Test case: TC10 <br>41* Description: Changing data type <br>42* Steps: 1.Set breakpoint on line 20 <br>43* 2.Debug Main <br>44* X. Stops on line 20 <br>45* 3.Change line 16 to boolean i = true; <br>46* 4.Smart Swap <br>47* 5.Resume <br>48* X. Prints "true" as last line of output <br>49* <br>50* The description was drown up according to steps under JBuilder.51*52* Of course, the test has own line numbers and method/class names and53* works as follow:54* When the test is starting debugee, debugger sets breakpoint at55* the 40th line (method <code>runIt</code>).56* Note: the <code>runIt</code> method was added into the test, to allow invoking57* <code>ThreadReference.popFrame()</code>. Current frame can not be reset because of58* there is no previous frame.59* After the breakpoint is reached, debugger redefines debugee changing type of60* local variable, pops current frame, sets a new breakpoint at 37th line and61* resumes debugee.62* When the second breakpoint hits, debugger requests value of the local63* variable <code>i</code> and compares got value with expected value.64* In this case expected value is the new value after redefinition.65*/6667public class tc10x002 {6869public final static String UNEXPECTED_STRING = "***Unexpected exception ";7071private final static String prefix = "nsk.jdi.BScenarios.hotswap.";72private final static String debuggerName = prefix + "tc10x002";73private final static String debugeeName = debuggerName + "a";7475private final static String newClassFile = "newclass" + File.separator76+ debugeeName.replace('.',File.separatorChar)77+ ".class";7879private static int exitStatus;80private static Log log;81private static Debugee debugee;82private static long waitTime;83private static String classDir;8485private int eventCount;86private int expectedEventCount = 2;87private ReferenceType debugeeClass;8889private static void display(String msg) {90log.display(msg);91}9293private static void complain(String msg) {94log.complain("debugger FAILURE> " + msg + "\n");95}9697public static void main(String argv[]) {98System.exit(Consts.JCK_STATUS_BASE + run(argv, System.out));99}100101public static int run(String argv[], PrintStream out) {102103exitStatus = Consts.TEST_PASSED;104105tc10x002 thisTest = new tc10x002();106107ArgumentHandler argHandler = new ArgumentHandler(argv);108log = new Log(out, argHandler);109110classDir = argv[0];111waitTime = argHandler.getWaitTime() * 60000;112113Binder binder = new Binder(argHandler, log);114debugee = binder.bindToDebugee(debugeeName);115debugee.createIOPipe();116117try {118thisTest.execTest();119} catch (Throwable e) {120exitStatus = Consts.TEST_FAILED;121e.printStackTrace();122} finally {123debugee.endDebugee();124}125display("Test finished. exitStatus = " + exitStatus);126127return exitStatus;128}129130private void execTest() throws Failure {131132if (!debugee.VM().canRedefineClasses()) {133display("\n>>>canRedefineClasses() is false<<< test canceled.\n");134return;135}136137display("\nTEST BEGINS");138display("===========");139140EventSet eventSet = null;141EventIterator eventIterator = null;142Event event;143BreakpointRequest brkpRequest;144long totalTime = waitTime;145long tmp, begin = System.currentTimeMillis(),146delta = 0;147boolean exit = false;148149eventCount = 0;150EventRequestManager evm = debugee.getEventRequestManager();151ClassPrepareRequest req = evm.createClassPrepareRequest();152req.addClassFilter(debugeeName);153req.enable();154debugee.resume();155156while (totalTime > 0 && !exit) {157if (eventIterator == null || !eventIterator.hasNext()) {158try {159eventSet = debugee.VM().eventQueue().remove(totalTime);160} catch (InterruptedException e) {161new Failure(e);162}163if (eventSet != null) {164eventIterator = eventSet.eventIterator();165} else {166eventIterator = null;167}168}169while (eventIterator.hasNext()) {170event = eventIterator.nextEvent();171// display("\n event ===>>> " + event);172173if (event instanceof ClassPrepareEvent) {174display("\n event ===>>> " + event);175debugeeClass = ((ClassPrepareEvent )event).referenceType();176display("Tested class\t:" + debugeeClass.name());177178brkpRequest = debugee.setBreakpoint(debugeeClass,179tc10x002a.brkpMethodName,180tc10x002a.brkpLineNumber1);181debugee.resume();182183} else if (event instanceof BreakpointEvent) {184display("\n event ===>>> " + event);185BreakpointEvent brkpEvent = (BreakpointEvent )event;186187switch (eventCount) {188case 0:189hitBreakpoint(brkpEvent, tc10x002a.checkLastLine1);190display("redefining...");191redefineDebugee();192193popFrames(brkpEvent.thread());194195brkpRequest = debugee.setBreakpoint(debugeeClass,196tc10x002a.brkpMethodName,197tc10x002a.brkpLineNumber2);198break;199case 1:200Value val = null;201hitBreakpoint(brkpEvent, tc10x002a.checkLastLine2);202try {203StackFrame frame = brkpEvent.thread().frame(0);204LocalVariable var = frame.visibleVariableByName("i");205display("local variable:\t" + var);206val = frame.getValue(var);207} catch (Exception e) {208throw new Failure(UNEXPECTED_STRING + e);209}210display("\nValue of local variable:\t" + val);211if (((PrimitiveValue)val).booleanValue() ==212tc10x002a.INITIAL_BOOL_VALUE) {213display("!!!Expected value of local variable!!!\n");214} else {215complain("Unexpected value of local variable.\n");216exitStatus = Consts.TEST_FAILED;217}218break;219}220debugee.resume();221222} else if (event instanceof VMDeathEvent) {223exit = true;224break;225} else if (event instanceof VMDisconnectEvent) {226exit = true;227break;228} // if229} // while230tmp = System.currentTimeMillis();231delta = tmp - begin;232totalTime -= delta;233begin = tmp;234}235236if (eventCount != expectedEventCount) {237if (totalTime <= 0) {238complain("out of wait time...");239}240complain("expecting " + expectedEventCount241+ " events, but "242+ eventCount + " events arrived.");243exitStatus = Consts.TEST_FAILED;244}245246display("=============");247display("TEST FINISHES\n");248}249250private void redefineDebugee() {251Map<? extends com.sun.jdi.ReferenceType,byte[]> mapBytes;252boolean alreadyComplained = false;253mapBytes = mapClassToBytes(newClassFile);254try {255debugee.VM().redefineClasses(mapBytes);256} catch (Exception e) {257throw new Failure(UNEXPECTED_STRING + e);258}259}260261private Map<? extends com.sun.jdi.ReferenceType,byte[]> mapClassToBytes(String fileName) {262display("class-file\t:" + fileName);263File fileToBeRedefined = new File(classDir + File.separator + fileName);264int fileToRedefineLength = (int )fileToBeRedefined.length();265byte[] arrayToRedefine = new byte[fileToRedefineLength];266267FileInputStream inputFile;268try {269inputFile = new FileInputStream(fileToBeRedefined);270} catch (FileNotFoundException e) {271throw new Failure(UNEXPECTED_STRING + e);272}273274try {275inputFile.read(arrayToRedefine);276inputFile.close();277} catch (IOException e) {278throw new Failure(UNEXPECTED_STRING + e);279}280HashMap<com.sun.jdi.ReferenceType,byte[]> mapForClass = new HashMap<com.sun.jdi.ReferenceType,byte[]>();281mapForClass.put(debugeeClass, arrayToRedefine);282return mapForClass;283}284285private void popFrames(ThreadReference thread) {286display("\npop frames...");287try {288StackFrame frame = thread.frame(0);289Method mthd = frame.location().method();290do {291thread.popFrames(frame);292display(mthd.name() + " is resetted");293frame = thread.frame(0);294mthd = frame.location().method();295} while (mthd.isObsolete());296} catch (IncompatibleThreadStateException e) {297throw new Failure(UNEXPECTED_STRING + e);298}299display("");300}301302private void hitBreakpoint(BreakpointEvent event, int expLine) {303eventInfo(event);304if (event.location().lineNumber() == expLine) {305display("!!!BreakpointEvent steps to the expected line "306+ event.location().lineNumber() + "!!!");307} else {308complain("BreakpointEvent steps to line " + event.location().lineNumber()309+ ", expected line number is "310+ expLine);311exitStatus = Consts.TEST_FAILED;312}313display("");314}315316private void eventInfo(LocatableEvent event) {317eventCount++;318display("event info: #" + eventCount);319display("\tthread\t- " + event.thread().name());320locationInfo(event);321}322323private void breakpointInfo(BreakpointRequest request) {324display("breakpoint info: ");325display("\tis enabled - " + request.isEnabled());326locationInfo(request);327}328329private void locationInfo(Locatable loc) {330try {331display("\tsource\t- " + loc.location().sourceName());332display("\tmethod\t- " + loc.location().method().name());333display("\tline\t- " + loc.location().lineNumber());334} catch (AbsentInformationException e) {335display("***information is not available***");336}337}338339private MethodExitRequest createMethodExitRequest(ReferenceType refType) {340EventRequestManager evm = debugee.getEventRequestManager();341MethodExitRequest request = evm.createMethodExitRequest();342request.addClassFilter(refType);343request.enable();344return request;345}346}347348349