0N/A/*
2362N/A * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/A/**
0N/A * @test
0N/A * @bug 4628726
0N/A * @summary Test class redefinition - method data line numbers and local vars,
0N/A *
0N/A * @author Robert Field
0N/A *
0N/A * @library ..
0N/A * @run build TestScaffold VMConnection TargetListener TargetAdapter
0N/A * @run compile -g RedefineTest.java
0N/A * @run shell RedefineSetUp.sh
0N/A * @run main RedefineTest -repeat 3
0N/A * @run main RedefineTest
0N/A */
0N/Aimport com.sun.jdi.*;
0N/Aimport com.sun.jdi.event.*;
0N/Aimport com.sun.jdi.request.*;
0N/Aimport java.util.*;
0N/Aimport java.io.*;
0N/A
0N/A /********** target program **********/
0N/A
0N/Aclass RedefineTarg {
0N/A public static void main(String[] args){
0N/A RedefineSubTarg.stemcp();
0N/A RedefineSubTarg sub = new RedefineSubTarg();
0N/A sub.bottom();
0N/A RedefineSubTarg.stnemcp();
0N/A RedefineSubTarg.stemcp();
0N/A }
0N/A}
0N/A
0N/A /********** test program **********/
0N/A
0N/Apublic class RedefineTest extends TestScaffold {
0N/A static int redefineRepeat = 1;
0N/A int bpCnt = 0;
0N/A
0N/A // isObsolete, linenumber, lv name, lv value, lv isArg
0N/A String[] before = {
0N/A "+ 3",
0N/A "+ 6 eights 888 T",
0N/A "+ 11 rot 4 F",
0N/A "+ 15",
0N/A "+ 20 myArg 56 T paramy 12 F",
0N/A "+ 24",
0N/A "+ 28",
0N/A "+ 33" };
0N/A String[] after = {
0N/A "+ 5",
0N/A "O",
0N/A "O",
0N/A "+ 16",
0N/A "+ 21 whoseArg 56 T parawham 12 F",
0N/A "+ 25",
0N/A "O",
0N/A "+ 34" };
0N/A String[] shorter = {
0N/A "+ 5",
0N/A "+ 9 eights 88 T",
0N/A "+ 13",
0N/A "+ 16",
0N/A "+ 21 whoseArg 56 T parawham 12 F",
0N/A "+ 25" };
0N/A String[] refresh = {
0N/A "+ 5",
0N/A "+ 9 eights 88 T",
0N/A "+ 13",
0N/A "+ 16",
0N/A "+ 21 whoseArg 56 T parawham 12 F",
0N/A "+ 25",
0N/A "+ 29",
0N/A "+ 34" };
0N/A int[] bps = {7, 12, 16, 21, 25, 30, 34};
0N/A String[][] bpPlaces = {
0N/A {"+ 16"},
0N/A {"+ 21 myArg 56 T paramy 12 F"},
0N/A {"+ 25"},
0N/A {"+ 34"} };
0N/A
0N/A static String[] processArgs(String args[]) {
0N/A if (args.length > 0 && args[0].equals("-repeat")) {
0N/A redefineRepeat = Integer.decode(args[1]).intValue();
0N/A String[] args2 = new String[args.length - 2];
0N/A System.arraycopy(args, 2, args2, 0, args.length - 2);
0N/A return args2;
0N/A } else {
0N/A return args;
0N/A }
0N/A }
0N/A
0N/A RedefineTest (String args[]) {
0N/A super(args);
0N/A }
0N/A
0N/A public static void main(String[] args) throws Exception {
0N/A new RedefineTest(processArgs(args)).startTests();
0N/A }
0N/A
0N/A
0N/A /********** event handlers **********/
0N/A
0N/A public void breakpointReached(BreakpointEvent event) {
0N/A println("Got BreakpointEvent - " + event);
0N/A try {
0N/A checkFrames(event.thread(), bpPlaces[bpCnt++]);
0N/A if (bpCnt >= bpPlaces.length) {
0N/A eventRequestManager().deleteAllBreakpoints();
0N/A }
0N/A } catch (Exception exc) {
0N/A failure("FAIL: breakpoint checking threw " + exc);
0N/A }
0N/A }
0N/A
0N/A /********** test assists **********/
0N/A
0N/A // isObsolete, linenumber, lv name, lv value, lv isArg
0N/A // equals: ref type (always), method (not obsolete)
0N/A void checkFrames(ThreadReference thread, String[] matchList) throws Exception {
0N/A for (int i = 0; i < matchList.length; ++i) {
0N/A String match = matchList[i];
0N/A StackFrame frame = thread.frame(i);
0N/A Location loc = frame.location();
0N/A ReferenceType refType = loc.declaringType();
0N/A Method meth = loc.method();
0N/A String errInfo = "\nframe " + i + ": " + loc + "\n match: " + match;
0N/A if (!findReferenceType("RedefineSubTarg").equals(refType)) {
0N/A failure("FAIL: Bad reference type - " + errInfo);
0N/A return; // might be bad class, but might have run past bottom
0N/A }
0N/A StringTokenizer st = new StringTokenizer(match);
0N/A boolean expectObs = st.nextToken().equals("O");
0N/A println("Frame " + i + ": " + meth);
0N/A if (meth.isObsolete()) {
0N/A if (!expectObs) {
0N/A failure("FAIL: Method should NOT be obsolete - " + errInfo);
0N/A }
0N/A } else {
0N/A if (expectObs) {
0N/A failure("FAIL: Method should be obsolete - " + errInfo);
0N/A break; // no more data to read
0N/A }
0N/A if (!findMethod(refType, meth.name(), meth.signature()).equals(meth)) {
0N/A failure("FAIL: Non matching method - " + errInfo);
0N/A }
0N/A int line = loc.lineNumber();
0N/A if (line != Integer.parseInt(st.nextToken())) {
0N/A failure("FAIL: Unexpected line number: " + errInfo);
0N/A }
0N/A // local var matching
0N/A int lvCnt = 0;
0N/A while (st.hasMoreTokens()) {
0N/A ++lvCnt;
0N/A String lvName = st.nextToken();
0N/A int lvValue = Integer.parseInt(st.nextToken());
0N/A boolean isArg = st.nextToken().equals("T");
0N/A LocalVariable lv = frame.visibleVariableByName(lvName);
0N/A if (lv == null) {
0N/A failure("FAIL: local var not found: '" + lvName +
0N/A "' -- " + errInfo);
0N/A } else {
0N/A Value val = frame.getValue(lv);
0N/A int ival = ((IntegerValue)val).value();
0N/A if (ival != lvValue) {
0N/A failure("FAIL: expected value: '" + lvValue +
0N/A "' got: '" + ival + "' -- " + errInfo);
0N/A }
0N/A if (lv.isArgument() != isArg) {
0N/A failure("FAIL: expected argument: '" + isArg +
0N/A "' got: '" + lv.isArgument() + "' -- " + errInfo);
0N/A }
0N/A }
0N/A }
0N/A List locals = frame.visibleVariables();
0N/A if (locals.size() != lvCnt) {
0N/A failure("FAIL: expected '" + lvCnt +
0N/A "' locals were '" + locals.size() +
0N/A "' -- " + errInfo + "' -- " + locals);
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A
0N/A void doRedefine(String fileName) throws Exception {
0N/A File phyl = new File(fileName);
0N/A byte[] bytes = new byte[(int)phyl.length()];
0N/A InputStream in = new FileInputStream(phyl);
0N/A in.read(bytes);
0N/A in.close();
0N/A
0N/A Map map = new HashMap();
0N/A map.put(findReferenceType("RedefineSubTarg"), bytes);
0N/A
0N/A try {
0N/A for (int i = 0; i < redefineRepeat; ++i) {
0N/A vm().redefineClasses(map);
0N/A }
0N/A } catch (Exception thr) {
0N/A failure("FAIL: unexpected exception: " + thr);
0N/A }
0N/A }
0N/A
0N/A ThreadReference toTop() {
0N/A BreakpointEvent bpe = resumeTo("RedefineSubTarg", "top", "()V");
0N/A return bpe.thread();
0N/A }
0N/A
0N/A void setBP(int line) {
0N/A try {
0N/A Location loc = findLocation(findReferenceType("RedefineSubTarg"), line);
0N/A final BreakpointRequest request =
0N/A eventRequestManager().createBreakpointRequest(loc);
0N/A request.enable();
0N/A } catch (Exception exc) {
0N/A failure("FAIL: Attempt to set BP at line " + line + " threw " + exc);
0N/A }
0N/A }
0N/A
0N/A /********** test core **********/
0N/A
0N/A protected void runTests() throws Exception {
0N/A
0N/A startToMain("RedefineTarg");
0N/A
0N/A ThreadReference thread = toTop();
0N/A
0N/A println("------ Before Redefine ------");
0N/A checkFrames(thread, before);
0N/A
0N/A println("------ After Redefine ------");
0N/A doRedefine("Different_RedefineSubTarg.class");
0N/A checkFrames(thread, after);
0N/A
0N/A println("------ Static 2 ------");
0N/A toTop();
0N/A checkFrames(thread, shorter);
0N/A
0N/A println("------ Instance ------");
0N/A toTop();
0N/A checkFrames(thread, shorter);
0N/A
0N/A println("------ Re-entered ------");
0N/A toTop();
0N/A checkFrames(thread, refresh);
0N/A
0N/A println("------ Breakpoints ------");
0N/A doRedefine("RedefineSubTarg.class");
0N/A for (int i = 0; i < bps.length; ++i) {
0N/A setBP(bps[i]);
0N/A }
0N/A
0N/A /*
0N/A * resume the target listening for events
0N/A */
0N/A listenUntilVMDisconnect();
0N/A
0N/A if (bpCnt != bpPlaces.length) {
0N/A failure("FAIL: Wrong number of breakpoints encountered: " + bpCnt);
0N/A }
0N/A
0N/A /*
0N/A * deal with results of test
0N/A * if anything has called failure("foo") testFailed will be true
0N/A */
0N/A if (!testFailed) {
0N/A println("RedefineTest(method): passed");
0N/A } else {
0N/A throw new Exception("RedefineTest(method): failed");
0N/A }
0N/A }
0N/A}