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