1 #!/bin/sh 2 3 # 4 # Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. 5 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6 # 7 # This code is free software; you can redistribute it and/or modify it 8 # under the terms of the GNU General Public License version 2 only, as 9 # published by the Free Software Foundation. 10 # 11 # This code is distributed in the hope that it will be useful, but WITHOUT 12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 # version 2 for more details (a copy is included in the LICENSE file that 15 # accompanied this code). 16 # 17 # You should have received a copy of the GNU General Public License version 18 # 2 along with this work; if not, write to the Free Software Foundation, 19 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 # 21 # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 # or visit www.oracle.com if you need additional information or have any 23 # questions. 24 # 25 26 # @test 27 # @bug 4724076 28 # @summary Redefine does not work in for/while loop. 29 # The failure occurs when a method is active and 30 # a method that it calls multiple times is redefined 31 # more than once. 32 # @author Jim Holmlund/Swamy Venkataramanappa 33 # 34 # @run shell/timeout=240 RedefineMulti.sh 35 36 compileOptions=-g 37 #java=java_g 38 39 createJavaFile() 40 { 41 cat <<EOF > $1.java.1 42 43 public class $1 { 44 45 String field1; 46 String field2; 47 48 // The first time thru the loop in start, 49 // "Before update..." should be printed. 50 // After the first redefine, "After update..." should be printed 51 // After the 2nd redefine, "abcde..." should be printed. 52 // The bug is that "After update..." is printed instead because 53 // stat() calls version 2 of doSomething() instead of 54 // version 3. 55 private void doSomething() { 56 System.out.println("Before update..."); // @1 commentout 57 // @1 uncomment System.out.println("After update..."); // @2 commentout 58 // @2 uncomment System.out.println("abcde..."); 59 } 60 61 public void start() { 62 for (int i=0; i < 3; i++) { 63 doSomething(); // @1 breakpoint here line 16 64 System.out.println("field1 = " + field1); 65 System.out.println("field2 = " + field2); 66 } 67 // Redefinex myx = new Redefinex(); 68 // for (int i = 0; i < 5; i++) { 69 // myx.methodx1(); // line 22 70 // System.out.println("fieldx1 = " + myx.fieldx1); 71 // System.out.println("fieldx2 = " + myx.fieldx2); 72 // } 73 } 74 75 public static void main(String[] args) { 76 $1 xxx = new $1(); 77 xxx.field1 = "field1"; 78 xxx.field2 = "field2"; 79 xxx.start(); 80 } 81 } 82 83 class Redefinex { 84 public String fieldx1; 85 public String fieldx2; 86 87 Redefinex() { 88 fieldx1 = "fieldx1"; 89 fieldx2 = "fieldx2"; 90 } 91 92 public void methodx1() { 93 System.out.println("redefinex 1"); 94 //System.out.println("redefinex 2"); 95 //System.out.println("redefinex 3"); 96 } 97 98 } 99 100 /********* 101 Steps to reproduce this problem: 102 a. add line breakpoint in start() 103 b. debug 104 c. when breakpoint is hit, type continue. You should see output 105 "Before update..." 106 d. change "Before update" to "After update" 107 e. redefine, and set line breakpoint (see step a) 108 f. type continue. You should see output "After update" 109 g. change "After update" to "abcde" 110 h. redefine, and set line breakpoint (see step a) 111 i. type continue. The output is shown as "After update" 112 113 j. to see "abcde" output, users will have to pop the stack, and 114 re-execute method start(). 115 ************/ 116 EOF 117 } 118 119 # This is called to feed cmds to jdb. 120 dojdbCmds() 121 { 122 setBkpts @1 123 runToBkpt @1 124 contToBkpt 125 redefineClass @1 126 setBkpts @1 127 contToBkpt 128 redefineClass @2 129 cmd allowExit cont 130 } 131 132 133 mysetup() 134 { 135 if [ -z "$TESTSRC" ] ; then 136 TESTSRC=. 137 fi 138 139 for ii in . $TESTSRC $TESTSRC/.. ; do 140 if [ -r "$ii/ShellScaffold.sh" ] ; then 141 . $ii/ShellScaffold.sh 142 break 143 fi 144 done 145 } 146 147 # You could replace this next line with the contents 148 # of ShellScaffold.sh and this script will run just the same. 149 mysetup 150 151 runit 152 debuggeeFailIfPresent "Internal exception:" 153 debuggeeFailIfNotPresent "abcde" 154 pass