Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/jdi/BScenarios/hotswap/tc06x001.java
41171 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: TC6 <br>41* Description: Before point of execution, same method - stepping <br>42* Steps: 1.Set breakpoint at line 24 (call to b() <br>43* from a()) <br>44* 2.Debug Main <br>45* 3.Insert as line before point of <br>46* execution: System.err.println("foo"); <br>47* 4.Smart Swap <br>48* 5.Set Smart PopFrame to beginging of <br>49* method a() <br>50* 6.F7 to step into <br>51* X. Stops on println <br>52* 7.F7 <br>53* X. Prints "foo" and stops on call to b() <br>54* 8.F7 <br>55* X. Steps into b() <br>56* 9.Resume <br>57* X. Prints numbers <br>58* The description was drown up according to steps under JBuilder.59*60* Of course, the test has own line numbers and method/class names and61* works as follow:62* When the test is starting debugee, debugger sets breakpoint at63* the 39th line (method <code>method_A</code>).64* After the breakpoint is reached, debugger redefines debugee adding65* a new line into <code>method_A</code>, pops frames,creates <code>StepRequest</code>66* and resumes debugee.67* When the location of the current <code>StepEvent</code> is in <code>method_B</code>,68* created <code>StepRequest</code> is disabled. The test checks up location of every69* step event and that new code becomes actual.70*/7172public class tc06x001 {7374public final static String UNEXPECTED_STRING = "***Unexpected exception ";7576private final static String prefix = "nsk.jdi.BScenarios.hotswap.";77private final static String debuggerName = prefix + "tc06x001";78private final static String debugeeName = debuggerName + "a";7980private final static String newClassFile = "newclass" + File.separator81+ debugeeName.replace('.',File.separatorChar)82+ ".class";8384private static int exitStatus;85private static Log log;86private static Debugee debugee;87private static long waitTime;88private static String classDir;8990private static final String firstMethodName = "method_A";91private static final String lastMethodName = "method_B";9293private int eventCount;94private int expectedEventCount = 4;95private ReferenceType debugeeClass;9697private static void display(String msg) {98log.display(msg);99}100101private static void complain(String msg) {102log.complain("debugger FAILURE> " + msg + "\n");103}104105public static void main(String argv[]) {106System.exit(Consts.JCK_STATUS_BASE + run(argv, System.out));107}108109public static int run(String argv[], PrintStream out) {110111exitStatus = Consts.TEST_PASSED;112113tc06x001 thisTest = new tc06x001();114115ArgumentHandler argHandler = new ArgumentHandler(argv);116log = new Log(out, argHandler);117118classDir = argv[0];119waitTime = argHandler.getWaitTime() * 60000;120121Binder binder = new Binder(argHandler, log);122debugee = binder.bindToDebugee(debugeeName);123124try {125thisTest.execTest();126} catch (Throwable e) {127exitStatus = Consts.TEST_FAILED;128e.printStackTrace();129} finally {130debugee.endDebugee();131}132display("Test finished. exitStatus = " + exitStatus);133134return exitStatus;135}136137private void execTest() throws Failure {138139if (!debugee.VM().canRedefineClasses()) {140display("\n>>>canRedefineClasses() is false<<< test canceled.\n");141return;142}143144display("\nTEST BEGINS");145display("===========");146147EventSet eventSet = null;148EventIterator eventIterator = null;149Event event;150long totalTime = waitTime;151long tmp, begin = System.currentTimeMillis(),152delta = 0;153boolean exit = false;154155eventCount = 0;156EventRequestManager evm = debugee.getEventRequestManager();157ClassPrepareRequest req = evm.createClassPrepareRequest();158req.addClassFilter(debugeeName);159req.enable();160debugee.resume();161162while (totalTime > 0 && !exit) {163if (eventIterator == null || !eventIterator.hasNext()) {164try {165eventSet = debugee.VM().eventQueue().remove(totalTime);166} catch (InterruptedException e) {167new Failure(e);168}169if (eventSet != null) {170eventIterator = eventSet.eventIterator();171} else {172eventIterator = null;173}174}175if (eventIterator != null) {176while (eventIterator.hasNext()) {177event = eventIterator.nextEvent();178// display("\n event ===>>> " + event);179180if (event instanceof ClassPrepareEvent) {181display("\n event ===>>> " + event);182debugeeClass = ((ClassPrepareEvent )event).referenceType();183display("Tested class\t:" + debugeeClass.name());184debugee.setBreakpoint(debugeeClass,185tc06x001a.brkpMethodName,186tc06x001a.brkpLineNumber);187188debugee.resume();189190} else if (event instanceof BreakpointEvent) {191display("\n event ===>>> " + event);192hitBreakpoint((BreakpointEvent )event);193display("redefining...");194redefineDebugee();195popFrames(((BreakpointEvent )event).thread());196createStepRequest(((LocatableEvent )event).thread());197debugee.resume();198199} else if (event instanceof StepEvent) {200display("\n event ===>>> " + event);201hitStep((StepEvent )event);202debugee.resume();203204} else if (event instanceof VMDeathEvent) {205exit = true;206break;207} else if (event instanceof VMDisconnectEvent) {208exit = true;209break;210} // if211} // while212} // if213tmp = System.currentTimeMillis();214delta = tmp - begin;215totalTime -= delta;216begin = tmp;217}218219if (eventCount != expectedEventCount) {220if (totalTime <= 0) {221complain("out of wait time...");222}223complain("expecting " + expectedEventCount224+ " events, but "225+ eventCount + " events arrived.");226exitStatus = Consts.TEST_FAILED;227}228229display("=============");230display("TEST FINISHES\n");231}232233private void redefineDebugee() {234Map<com.sun.jdi.ReferenceType,byte[]> mapBytes;235boolean alreadyComplained = false;236mapBytes = mapClassToBytes(newClassFile);237try {238debugee.VM().redefineClasses(mapBytes);239} catch (Exception e) {240throw new Failure(UNEXPECTED_STRING + e);241}242}243244private Map<com.sun.jdi.ReferenceType,byte[]> mapClassToBytes(String fileName) {245display("class-file\t:" + fileName);246File fileToBeRedefined = new File(classDir + File.separator + fileName);247int fileToRedefineLength = (int )fileToBeRedefined.length();248byte[] arrayToRedefine = new byte[fileToRedefineLength];249250FileInputStream inputFile;251try {252inputFile = new FileInputStream(fileToBeRedefined);253} catch (FileNotFoundException e) {254throw new Failure(UNEXPECTED_STRING + e);255}256257try {258inputFile.read(arrayToRedefine);259inputFile.close();260} catch (IOException e) {261throw new Failure(UNEXPECTED_STRING + e);262}263HashMap<com.sun.jdi.ReferenceType,byte[]> mapForClass = new HashMap<com.sun.jdi.ReferenceType,byte[]>();264mapForClass.put(debugeeClass, arrayToRedefine);265return mapForClass;266}267268private void popFrames(ThreadReference thread) {269display("\npop frames...");270try {271StackFrame frame = thread.frame(0);272Method mthd = frame.location().method();273do {274thread.popFrames(frame);275display(mthd.name() + " is resetted");276frame = thread.frame(0);277mthd = frame.location().method();278} while (mthd.isObsolete());279} catch (IncompatibleThreadStateException e) {280throw new Failure(UNEXPECTED_STRING + e);281}282display("");283}284285private StepRequest createStepRequest(ThreadReference thread) {286EventRequestManager evm = debugee.getEventRequestManager();287StepRequest request = evm.createStepRequest(thread,288StepRequest.STEP_LINE,289StepRequest.STEP_INTO);290request.enable();291return request;292}293294private void hitBreakpoint(BreakpointEvent event) {295locationInfo(event);296if (event.location().lineNumber() != tc06x001a.checkLastLine) {297complain("BreakpointEvent steps to line " + event.location().lineNumber()298+ ", expected line number is "299+ tc06x001a.checkLastLine);300exitStatus = Consts.TEST_FAILED;301} else {302display("!!!BreakpointEvent steps to the expected line "303+ event.location().lineNumber() + "!!!");304}305display("");306}307308private void hitStep(StepEvent event) {309locationInfo(event);310String methodName = event.location().method().name();311StepRequest request = (StepRequest )event.request();312313switch (eventCount) {314case 2:315checkLocMethod(methodName, firstMethodName);316break;317case 3:318Field fld = debugeeClass.fieldByName(tc06x001a.fieldToCheckName);319Value val = debugeeClass.getValue(fld);320if (((IntegerValue )val).value() != tc06x001a.CHANGED_VALUE) {321complain("Unexpected: new code is not actual");322complain("Unexpected value of checked field: "323+ val);324exitStatus = Consts.TEST_FAILED;325} else {326display("!!!Expected: Inserted line has worked");327}328break;329case 4:330checkLocMethod(methodName, lastMethodName);331request.disable();332break;333default:334complain("Unexpected event" + event);335exitStatus = Consts.TEST_FAILED;336}337display("");338}339340private void checkLocMethod(String currentMethodName, String expectedMethodName) {341if (currentMethodName.compareTo(expectedMethodName) != 0) {342complain("Unexpected event location at \"" + currentMethodName + "\"");343exitStatus = Consts.TEST_FAILED;344} else {345display("!!!Expected event location at \"" + currentMethodName + "\"");346}347}348349private void locationInfo(LocatableEvent event) {350eventCount++;351display("event info: #" + eventCount);352display("\tthread\t- " + event.thread().name());353try {354display("\tsource\t- " + event.location().sourceName());355display("\tmethod\t- " + event.location().method().name());356display("\tline\t- " + event.location().lineNumber());357} catch (AbsentInformationException e) {358}359}360}361362363