Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/jdi/BScenarios/hotswap/tc07x001.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: TC7 <br>41* Description: After point of execution, different method - stepping <br>42* Steps: 1.Set breakpoint at line 24 (call from a() <br>43* to b()) <br>44* 2.Debug Main <br>45* 3.Insert as first line in b(): <br>46* System.err.println("foo"); <br>47* 4.Smart Swap <br>48* 5.F7 to step into <br>49* X. Steps into b() <br>50* 6.F7 to step into <br>51* X. Prints "foo" <br>52* 7.F7 to step into <br>53* X. Steps on to line that prints "1" <br>54* <br>55* The description was drown up according to steps under JBuilder.56*57* Of course, the test has own line numbers and method/class names and58* works as follow:59* When the test is starting debugee, debugger sets breakpoint at the 38th60* line (<code>method method_A</code>). After the breakpoint is reached,61* debugger redefines debugee inserting first line into method_B, creates62* <code>StepRequest</code> and resumes debugee. When the location of the63* current <code>StepEvent</code> is in <code>method_C</code>, created64* <code>StepRequest</code> is disabled.65* The test checks up location of every step event and that new code66* becomes actual.67*/6869public class tc07x001 {7071public final static String UNEXPECTED_STRING = "***Unexpected exception ";7273private final static String prefix = "nsk.jdi.BScenarios.hotswap.";74private final static String debuggerName = prefix + "tc07x001";75private final static String debugeeName = debuggerName + "a";7677private final static String newClassFile = "newclass" + File.separator78+ debugeeName.replace('.',File.separatorChar)79+ ".class";8081private static int exitStatus;82private static Log log;83private static Debugee debugee;84private static long waitTime;85private static String classDir;8687private static final String firstMethodName = "method_B";88private static final String lastMethodName = "method_C";8990private int eventCount;91private int expectedEventCount = 4;92private ReferenceType debugeeClass;9394private static void display(String msg) {95log.display(msg);96}9798private static void complain(String msg) {99log.complain("debugger FAILURE> " + msg + "\n");100}101102public static void main(String argv[]) {103System.exit(Consts.JCK_STATUS_BASE + run(argv, System.out));104}105106public static int run(String argv[], PrintStream out) {107108exitStatus = Consts.TEST_PASSED;109110tc07x001 thisTest = new tc07x001();111112ArgumentHandler argHandler = new ArgumentHandler(argv);113log = new Log(out, argHandler);114115classDir = argv[0];116waitTime = argHandler.getWaitTime() * 60000;117118Binder binder = new Binder(argHandler, log);119debugee = binder.bindToDebugee(debugeeName);120121try {122thisTest.execTest();123} catch (Throwable e) {124exitStatus = Consts.TEST_FAILED;125e.printStackTrace();126} finally {127debugee.endDebugee();128}129display("Test finished. exitStatus = " + exitStatus);130131return exitStatus;132}133134private void execTest() throws Failure {135136if (!debugee.VM().canRedefineClasses()) {137display("\n>>>canRedefineClasses() is false<<< test canceled.\n");138return;139}140141display("\nTEST BEGINS");142display("===========");143144EventSet eventSet = null;145EventIterator eventIterator = null;146Event event;147long totalTime = waitTime;148long tmp, begin = System.currentTimeMillis(),149delta = 0;150boolean exit = false;151152eventCount = 0;153EventRequestManager evm = debugee.getEventRequestManager();154ClassPrepareRequest req = evm.createClassPrepareRequest();155req.addClassFilter(debugeeName);156req.enable();157debugee.resume();158159while (totalTime > 0 && !exit) {160if (eventIterator == null || !eventIterator.hasNext()) {161try {162eventSet = debugee.VM().eventQueue().remove(totalTime);163} catch (InterruptedException e) {164new Failure(e);165}166if (eventSet != null) {167eventIterator = eventSet.eventIterator();168} else {169eventIterator = null;170}171}172if (eventIterator != null) {173while (eventIterator.hasNext()) {174event = eventIterator.nextEvent();175// display("\n event ===>>> " + event);176177if (event instanceof ClassPrepareEvent) {178display("\n event ===>>> " + event);179debugeeClass = ((ClassPrepareEvent )event).referenceType();180display("Tested class\t:" + debugeeClass.name());181debugee.setBreakpoint(debugeeClass,182tc07x001a.brkpMethodName,183tc07x001a.brkpLineNumber);184185debugee.resume();186187} else if (event instanceof BreakpointEvent) {188display("\n event ===>>> " + event);189hitBreakpoint((BreakpointEvent )event);190display("redefining...");191redefineDebugee();192createStepRequest(((LocatableEvent )event).thread());193debugee.resume();194195} else if (event instanceof StepEvent) {196display("\n event ===>>> " + event);197hitStep((StepEvent )event);198debugee.resume();199200} else if (event instanceof VMDeathEvent) {201exit = true;202break;203} else if (event instanceof VMDisconnectEvent) {204exit = true;205break;206} // if207} // while208} // if209tmp = System.currentTimeMillis();210delta = tmp - begin;211totalTime -= delta;212begin = tmp;213}214215if (eventCount != expectedEventCount) {216if (totalTime <= 0) {217complain("out of wait time...");218}219complain("expecting " + expectedEventCount220+ " events, but "221+ eventCount + " events arrived.");222exitStatus = Consts.TEST_FAILED;223}224225display("=============");226display("TEST FINISHES\n");227}228229private void redefineDebugee() {230Map<? extends com.sun.jdi.ReferenceType,byte[]> mapBytes;231boolean alreadyComplained = false;232mapBytes = mapClassToBytes(newClassFile);233try {234debugee.VM().redefineClasses(mapBytes);235} catch (Exception e) {236throw new Failure(UNEXPECTED_STRING + e);237}238}239240private Map<? extends com.sun.jdi.ReferenceType,byte[]> mapClassToBytes(String fileName) {241display("class-file\t:" + fileName);242File fileToBeRedefined = new File(classDir + File.separator + fileName);243int fileToRedefineLength = (int )fileToBeRedefined.length();244byte[] arrayToRedefine = new byte[fileToRedefineLength];245246FileInputStream inputFile;247try {248inputFile = new FileInputStream(fileToBeRedefined);249} catch (FileNotFoundException e) {250throw new Failure(UNEXPECTED_STRING + e);251}252253try {254inputFile.read(arrayToRedefine);255inputFile.close();256} catch (IOException e) {257throw new Failure(UNEXPECTED_STRING + e);258}259HashMap<com.sun.jdi.ReferenceType,byte[]> mapForClass = new HashMap<com.sun.jdi.ReferenceType,byte[]>();260mapForClass.put(debugeeClass, arrayToRedefine);261return mapForClass;262}263264private StepRequest createStepRequest(ThreadReference thread) {265EventRequestManager evm = debugee.getEventRequestManager();266StepRequest request = evm.createStepRequest(thread,267StepRequest.STEP_LINE,268StepRequest.STEP_INTO);269request.enable();270return request;271}272273private void hitBreakpoint(BreakpointEvent event) {274locationInfo(event);275if (event.location().lineNumber() != tc07x001a.checkLastLine) {276complain("BreakpointEvent steps to line " + event.location().lineNumber()277+ ", expected line number is "278+ tc07x001a.checkLastLine);279exitStatus = Consts.TEST_FAILED;280} else {281display("!!!BreakpointEvent steps to the expected line "282+ event.location().lineNumber() + "!!!");283}284display("");285}286287private void hitStep(StepEvent event) {288locationInfo(event);289String methodName = event.location().method().name();290StepRequest request = (StepRequest )event.request();291if (methodName.compareTo(lastMethodName) == 0) {292request.disable();293}294switch (eventCount) {295case 2:296checkLocMethod(methodName, firstMethodName);297break;298case 3:299checkLocMethod(methodName, firstMethodName);300Field fld = debugeeClass.fieldByName(tc07x001a.fieldToCheckName);301Value val = debugeeClass.getValue(fld);302if (((IntegerValue )val).value() != tc07x001a.CHANGED_VALUE) {303complain("Unexpected: new code is not actual");304complain("Unexpected value of checked field: "305+ val);306exitStatus = Consts.TEST_FAILED;307} else {308display("!!!Expected: Inserted line has worked");309}310break;311case 4:312checkLocMethod(methodName, lastMethodName);313break;314default:315complain("Unexpected event" + event);316exitStatus = Consts.TEST_FAILED;317}318display("");319}320321private void checkLocMethod(String currentMethodName, String expectedMethodName) {322if (currentMethodName.compareTo(expectedMethodName) != 0) {323complain("Unexpected event location at \"" + currentMethodName + "\"");324exitStatus = Consts.TEST_FAILED;325} else {326display("!!!Expected event location at \"" + currentMethodName + "\"");327}328}329330private void locationInfo(LocatableEvent event) {331eventCount++;332display("event info: #" + eventCount);333display("\tthread\t- " + event.thread().name());334try {335display("\tsource\t- " + event.location().sourceName());336display("\tmethod\t- " + event.location().method().name());337display("\tline\t- " + event.location().lineNumber());338} catch (AbsentInformationException e) {339}340}341}342343344