1 /* 2 * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /** 25 * @test 26 * @bug 4628726 27 * @summary Test class redefinition - method data line numbers and local vars, 28 * 29 * @author Robert Field 30 * 31 * @library .. 32 * @modules jdk.jdi 33 * @run build TestScaffold VMConnection TargetListener TargetAdapter 34 * @run compile -g RedefineTest.java 35 * @run shell RedefineSetUp.sh 36 * @run driver RedefineTest -repeat 3 37 * @run driver RedefineTest 38 */ 39 import com.sun.jdi.*; 40 import com.sun.jdi.event.*; 41 import com.sun.jdi.request.*; 42 import java.util.*; 43 import java.io.*; 44 45 /********** target program **********/ 46 47 class RedefineTarg { 48 public static void main(String[] args){ 49 RedefineSubTarg.stemcp(); 50 RedefineSubTarg sub = new RedefineSubTarg(); 51 sub.bottom(); 52 RedefineSubTarg.stnemcp(); 53 RedefineSubTarg.stemcp(); 54 } 55 } 56 57 /********** test program **********/ 58 59 public class RedefineTest extends TestScaffold { 60 static int redefineRepeat = 1; 61 int bpCnt = 0; 62 63 // isObsolete, linenumber, lv name, lv value, lv isArg 64 String[] before = { 65 "+ 3", 66 "+ 6 eights 888 T", 67 "+ 11 rot 4 F", 68 "+ 15", 69 "+ 20 myArg 56 T paramy 12 F", 70 "+ 24", 71 "+ 28", 72 "+ 33" }; 73 String[] after = { 74 "+ 5", 75 "O", 76 "O", 77 "+ 16", 78 "+ 21 whoseArg 56 T parawham 12 F", 79 "+ 25", 80 "O", 81 "+ 34" }; 82 String[] shorter = { 83 "+ 5", 84 "+ 9 eights 88 T", 85 "+ 13", 86 "+ 16", 87 "+ 21 whoseArg 56 T parawham 12 F", 88 "+ 25" }; 89 String[] refresh = { 90 "+ 5", 91 "+ 9 eights 88 T", 92 "+ 13", 93 "+ 16", 94 "+ 21 whoseArg 56 T parawham 12 F", 95 "+ 25", 96 "+ 29", 97 "+ 34" }; 98 int[] bps = {7, 12, 16, 21, 25, 30, 34}; 99 String[][] bpPlaces = { 100 {"+ 16"}, 101 {"+ 21 myArg 56 T paramy 12 F"}, 102 {"+ 25"}, 103 {"+ 34"} }; 104 105 static String[] processArgs(String args[]) { 106 if (args.length > 0 && args[0].equals("-repeat")) { 107 redefineRepeat = Integer.decode(args[1]).intValue(); 108 String[] args2 = new String[args.length - 2]; 109 System.arraycopy(args, 2, args2, 0, args.length - 2); 110 return args2; 111 } else { 112 return args; 113 } 114 } 115 116 RedefineTest (String args[]) { 117 super(args); 118 } 119 120 public static void main(String[] args) throws Exception { 121 new RedefineTest(processArgs(args)).startTests(); 122 } 123 124 125 /********** event handlers **********/ 126 127 public void breakpointReached(BreakpointEvent event) { 128 println("Got BreakpointEvent - " + event); 129 try { 130 checkFrames(event.thread(), bpPlaces[bpCnt++]); 131 if (bpCnt >= bpPlaces.length) { 132 eventRequestManager().deleteAllBreakpoints(); 133 } 134 } catch (Exception exc) { 135 failure("FAIL: breakpoint checking threw " + exc); 136 } 137 } 138 139 /********** test assists **********/ 140 141 // isObsolete, linenumber, lv name, lv value, lv isArg 142 // equals: ref type (always), method (not obsolete) 143 void checkFrames(ThreadReference thread, String[] matchList) throws Exception { 144 for (int i = 0; i < matchList.length; ++i) { 145 String match = matchList[i]; 146 StackFrame frame = thread.frame(i); 147 Location loc = frame.location(); 148 ReferenceType refType = loc.declaringType(); 149 Method meth = loc.method(); 150 String errInfo = "\nframe " + i + ": " + loc + "\n match: " + match; 151 if (!findReferenceType("RedefineSubTarg").equals(refType)) { 152 failure("FAIL: Bad reference type - " + errInfo); 153 return; // might be bad class, but might have run past bottom 154 } 155 StringTokenizer st = new StringTokenizer(match); 156 boolean expectObs = st.nextToken().equals("O"); 157 println("Frame " + i + ": " + meth); 158 if (meth.isObsolete()) { 159 if (!expectObs) { 160 failure("FAIL: Method should NOT be obsolete - " + errInfo); 161 } 162 } else { 163 if (expectObs) { 164 failure("FAIL: Method should be obsolete - " + errInfo); 165 break; // no more data to read 166 } 167 if (!findMethod(refType, meth.name(), meth.signature()).equals(meth)) { 168 failure("FAIL: Non matching method - " + errInfo); 169 } 170 int line = loc.lineNumber(); 171 if (line != Integer.parseInt(st.nextToken())) { 172 failure("FAIL: Unexpected line number: " + errInfo); 173 } 174 // local var matching 175 int lvCnt = 0; 176 while (st.hasMoreTokens()) { 177 ++lvCnt; 178 String lvName = st.nextToken(); 179 int lvValue = Integer.parseInt(st.nextToken()); 180 boolean isArg = st.nextToken().equals("T"); 181 LocalVariable lv = frame.visibleVariableByName(lvName); 182 if (lv == null) { 183 failure("FAIL: local var not found: '" + lvName + 184 "' -- " + errInfo); 185 } else { 186 Value val = frame.getValue(lv); 187 int ival = ((IntegerValue)val).value(); 188 if (ival != lvValue) { 189 failure("FAIL: expected value: '" + lvValue + 190 "' got: '" + ival + "' -- " + errInfo); 191 } 192 if (lv.isArgument() != isArg) { 193 failure("FAIL: expected argument: '" + isArg + 194 "' got: '" + lv.isArgument() + "' -- " + errInfo); 195 } 196 } 197 } 198 List locals = frame.visibleVariables(); 199 if (locals.size() != lvCnt) { 200 failure("FAIL: expected '" + lvCnt + 201 "' locals were '" + locals.size() + 202 "' -- " + errInfo + "' -- " + locals); 203 } 204 } 205 } 206 } 207 208 209 void doRedefine(String fileName) throws Exception { 210 File phyl = new File(fileName); 211 byte[] bytes = new byte[(int)phyl.length()]; 212 InputStream in = new FileInputStream(phyl); 213 in.read(bytes); 214 in.close(); 215 216 Map map = new HashMap(); 217 map.put(findReferenceType("RedefineSubTarg"), bytes); 218 219 try { 220 for (int i = 0; i < redefineRepeat; ++i) { 221 vm().redefineClasses(map); 222 } 223 } catch (Exception thr) { 224 failure("FAIL: unexpected exception: " + thr); 225 } 226 } 227 228 ThreadReference toTop() { 229 BreakpointEvent bpe = resumeTo("RedefineSubTarg", "top", "()V"); 230 return bpe.thread(); 231 } 232 233 void setBP(int line) { 234 try { 235 Location loc = findLocation(findReferenceType("RedefineSubTarg"), line); 236 final BreakpointRequest request = 237 eventRequestManager().createBreakpointRequest(loc); 238 request.enable(); 239 } catch (Exception exc) { 240 failure("FAIL: Attempt to set BP at line " + line + " threw " + exc); 241 } 242 } 243 244 /********** test core **********/ 245 246 protected void runTests() throws Exception { 247 248 startToMain("RedefineTarg"); 249 250 ThreadReference thread = toTop(); 251 252 println("------ Before Redefine ------"); 253 checkFrames(thread, before); 254 255 println("------ After Redefine ------"); 256 doRedefine("Different_RedefineSubTarg.class"); 257 checkFrames(thread, after); 258 259 println("------ Static 2 ------"); 260 toTop(); 261 checkFrames(thread, shorter); 262 263 println("------ Instance ------"); 264 toTop(); 265 checkFrames(thread, shorter); 266 267 println("------ Re-entered ------"); 268 toTop(); 269 checkFrames(thread, refresh); 270 271 println("------ Breakpoints ------"); 272 doRedefine("RedefineSubTarg.class"); 273 for (int i = 0; i < bps.length; ++i) { 274 setBP(bps[i]); 275 } 276 277 /* 278 * resume the target listening for events 279 */ 280 listenUntilVMDisconnect(); 281 282 if (bpCnt != bpPlaces.length) { 283 failure("FAIL: Wrong number of breakpoints encountered: " + bpCnt); 284 } 285 286 /* 287 * deal with results of test 288 * if anything has called failure("foo") testFailed will be true 289 */ 290 if (!testFailed) { 291 println("RedefineTest(method): passed"); 292 } else { 293 throw new Exception("RedefineTest(method): failed"); 294 } 295 } 296 }