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