Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/jdi/BScenarios/hotswap/tc04x002.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:39* Suite 3 - Hot Swap40* Test case: TC441* Description: Before point of execution, different method42* Steps: 1.Set breakpoint at line 30 (call to c()43* from b())44* 2.Debug Main45* 3.Insert as first line in a():46* System.err.println("foo");47* 4.Smart Swap48* 5.Set Smart PopFrame to beginging of49* method a()50* 6.Resume51* X. Prints out "foo" and hits breakpoint52* at line 3053* 7.Resume54* X. Print numbers55* 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 at60* the 43th line (method <code>method_B</code>).61* After the breakpoint is reached, debugger:62* - redefines debugee adding a new line into <code>method_A</code>,63* - pops frames at beginning of <code>method_A</code>64* - sets breakpoint at the 43th line again65* and resumes debugee.66* It is expected the new code will be actual after the redefining and67* it hits breakpoint.68*/6970public class tc04x002 {7172public final static String UNEXPECTED_STRING = "***Unexpected exception ";7374private final static String prefix = "nsk.jdi.BScenarios.hotswap.";75private final static String debuggerName = prefix + "tc04x002";76private final static String debugeeName = debuggerName + "a";7778private final static String newClassFile = "newclass" + File.separator79+ debugeeName.replace('.',File.separatorChar)80+ ".class";8182private static int exitStatus;83private static Log log;84private static Debugee debugee;85private static long waitTime;86private static String classDir;8788private int expectedEventCount = 6;89private int eventCount = 0;9091private ReferenceType debugeeClass;9293private static void display(String msg) {94log.display(msg);95}9697private static void complain(String msg) {98log.complain("debugger FAILURE> " + msg + "\n");99}100101public static void main(String argv[]) {102System.exit(Consts.JCK_STATUS_BASE + run(argv, System.out));103}104105public static int run(String argv[], PrintStream out) {106107exitStatus = Consts.TEST_PASSED;108109tc04x002 thisTest = new tc04x002();110111ArgumentHandler argHandler = new ArgumentHandler(argv);112log = new Log(out, argHandler);113114classDir = argv[0];115waitTime = argHandler.getWaitTime() * 60000;116117Binder binder = new Binder(argHandler, log);118debugee = binder.bindToDebugee(debugeeName);119120try {121thisTest.execTest();122} catch (Throwable e) {123exitStatus = Consts.TEST_FAILED;124e.printStackTrace();125} finally {126debugee.endDebugee();127}128display("Test finished. exitStatus = " + exitStatus);129130return exitStatus;131}132133private void execTest() throws Failure {134135if (!debugee.VM().canRedefineClasses()) {136display("\n>>>canRedefineClasses() is false<<< test canceled.\n");137return;138}139140display("\nTEST BEGINS");141display("===========");142143EventSet eventSet = null;144EventIterator eventIterator = null;145Event event;146long totalTime = waitTime;147long tmp, begin = System.currentTimeMillis(),148delta = 0;149boolean exit = false;150151EventRequestManager evm = debugee.getEventRequestManager();152ClassPrepareRequest req = evm.createClassPrepareRequest();153req.addClassFilter(debugeeName);154req.enable();155debugee.resume();156157while (totalTime > 0 && !exit) {158if (eventIterator == null || !eventIterator.hasNext()) {159try {160eventSet = debugee.VM().eventQueue().remove(totalTime);161} catch (InterruptedException e) {162new Failure(e);163}164if (eventSet != null) {165eventIterator = eventSet.eventIterator();166} else {167eventIterator = null;168}169}170if (eventIterator != null) {171while (eventIterator.hasNext()) {172event = eventIterator.nextEvent();173// display("\n event ===>>> " + event);174175if (event instanceof ClassPrepareEvent) {176display("\n event ===>>> " + event);177debugeeClass = ((ClassPrepareEvent )event).referenceType();178display("Tested class\t:" + debugeeClass.name());179debugee.setBreakpoint(debugeeClass,180tc04x002a.brkpMethodName,181tc04x002a.brkpLineNumber);182183debugee.resume();184eventCount++;185186} else if (event instanceof BreakpointEvent) {187display("\n event ===>>> " + event);188switch (eventCount) {189case 1:190display("redefining...");191redefineDebugee();192popFrames(((BreakpointEvent )event).thread());193194debugee.setBreakpoint(debugeeClass,195tc04x002a.brkpMethodName,196tc04x002a.brkpLineNumber);197break;198199case 2:200display("!!!Expected second breakpoint event!!!");201createMethodExitRequest(debugeeClass);202break;203204default:205complain("Unexpected breakpoint event");206exitStatus = Consts.TEST_FAILED;207}208eventCount++;209hitBreakpoint((BreakpointEvent )event);210debugee.resume();211212} else if (event instanceof MethodExitEvent) {213display("\n event ===>>> " + event);214hitMethodExit((MethodExitEvent)event);215eventCount++;216debugee.resume();217218} else if (event instanceof VMDeathEvent) {219exit = true;220break;221} else if (event instanceof VMDisconnectEvent) {222exit = true;223break;224} // if225} // while226} // if227tmp = System.currentTimeMillis();228delta = tmp - begin;229totalTime -= delta;230begin = tmp;231}232233if (eventCount != expectedEventCount) {234if (totalTime <= 0) {235complain("out of wait time...");236}237complain("expecting " + expectedEventCount238+ " events, but "239+ eventCount + " events arrived.");240exitStatus = Consts.TEST_FAILED;241}242243display("=============");244display("TEST FINISHES\n");245}246247private void redefineDebugee() {248Map<com.sun.jdi.ReferenceType,byte[]> mapBytes;249boolean alreadyComplained = false;250mapBytes = mapClassToBytes(newClassFile);251try {252debugee.VM().redefineClasses(mapBytes);253} catch (Exception e) {254throw new Failure(UNEXPECTED_STRING + e);255}256}257258private void popFrames(ThreadReference thread) {259display("\npop frames...");260try {261StackFrame frame = thread.frame(0);262Method mthd = frame.location().method();263do {264thread.popFrames(frame);265display(mthd.name() + " is resetted");266frame = thread.frame(0);267mthd = frame.location().method();268} while (mthd.isObsolete());269} catch (IncompatibleThreadStateException e) {270throw new Failure(UNEXPECTED_STRING + e);271}272display("");273}274275private Map<com.sun.jdi.ReferenceType,byte[]> mapClassToBytes(String fileName) {276display("class-file\t:" + fileName);277File fileToBeRedefined = new File(classDir + File.separator + fileName);278int fileToRedefineLength = (int )fileToBeRedefined.length();279byte[] arrayToRedefine = new byte[fileToRedefineLength];280281FileInputStream inputFile;282try {283inputFile = new FileInputStream(fileToBeRedefined);284} catch (FileNotFoundException e) {285throw new Failure(UNEXPECTED_STRING + e);286}287288try {289inputFile.read(arrayToRedefine);290inputFile.close();291} catch (IOException e) {292throw new Failure(UNEXPECTED_STRING + e);293}294HashMap<com.sun.jdi.ReferenceType,byte[]> mapForClass = new HashMap<com.sun.jdi.ReferenceType,byte[]>();295mapForClass.put(debugeeClass, arrayToRedefine);296return mapForClass;297}298299private MethodExitRequest createMethodExitRequest(ReferenceType refType) {300EventRequestManager evm = debugee.getEventRequestManager();301MethodExitRequest request = evm.createMethodExitRequest();302request.addClassFilter(refType);303request.enable();304return request;305}306307private void hitBreakpoint(BreakpointEvent event) {308locationInfo(event);309if (event.location().lineNumber() != tc04x002a.checkLastLine) {310complain("BreakpointEvent steps to line " + event.location().lineNumber()311+ ", expected line number is "312+ tc04x002a.checkLastLine);313exitStatus = Consts.TEST_FAILED;314} else {315display("!!!BreakpointEvent steps to the expected line "316+ event.location().lineNumber() + "!!!");317}318display("");319}320321private void hitMethodExit(MethodExitEvent event) {322323locationInfo(event);324325Method mthd = ((MethodExitEvent )event).method();326if (mthd.name().compareTo(tc04x002a.brkpMethodName) == 0) {327Field fld = debugeeClass.fieldByName(tc04x002a.fieldToCheckName);328Value val = debugeeClass.getValue(fld);329if (((IntegerValue )val).value() != tc04x002a.CHANGED_VALUE) {330complain("Unexpected: new code is not actual "331+ "after resetting frames");332complain("Unexpected value of checked field: "333+ val);334exitStatus = Consts.TEST_FAILED;335} else {336display("!!!Expected: new code is actual "337+ "after resetting frames!!!");338}339}340display("");341}342343private void locationInfo(LocatableEvent event) {344display("event info:");345display("\tthread\t- " + event.thread().name());346try {347display("\tsource\t- " + event.location().sourceName());348} catch (AbsentInformationException e) {349}350display("\tmethod\t- " + event.location().method().name());351display("\tline\t- " + event.location().lineNumber());352}353}354355356