1 /* 2 * Copyright (c) 2001, 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 4409582 27 * @summary Test all info returned by modification watchpoints 28 * 29 * @author Daniel Prusa (or someone in the FFJ group) 30 * @author Robert Field (modified to JDIScaffold) 31 * 32 * @modules jdk.jdi 33 * @run build JDIScaffold VMConnection 34 * @run compile -g ModificationWatchpoints.java 35 * @run driver ModificationWatchpoints 36 */ 37 import com.sun.jdi.*; 38 import com.sun.jdi.event.*; 39 import com.sun.jdi.request.*; 40 import java.util.*; 41 42 /********** target program **********/ 43 44 class ModificationWatchpointsTarg { 45 public static final int RepeatCount = 3; 46 47 public static final byte ByteVal = -17; 48 public static final char CharVal = 'Y'; 49 public static final short ShortVal = -412; 50 public static final int IntVal = -711618; 51 public static final long LongVal = 0x1234567890123456L; 52 public static final float FloatVal = 7.986f; 53 public static final double DoubleVal = 3.14159265358979d; 54 public static final String StringVal = "OnceMore"; 55 public static final Object ObjectVal = new Object(); 56 57 static byte sByte; 58 static char sChar; 59 static short sShort; 60 static int sInt; 61 static long sLong; 62 static float sFloat; 63 static double sDouble; 64 static String sString; 65 static Object sObject; 66 67 byte iByte; 68 char iChar; 69 short iShort; 70 int iInt; 71 long iLong; 72 float iFloat; 73 double iDouble; 74 String iString; 75 Object iObject; 76 77 void iByteSet() { 78 iByte = ByteVal; 79 } 80 81 void iCharSet() { 82 iChar = CharVal; 83 } 84 85 void iShortSet() { 86 iShort = ShortVal; 87 } 88 89 void iIntSet() { 90 iInt = IntVal; 91 } 92 93 void iLongSet() { 94 iLong = LongVal; 95 } 96 97 void iFloatSet() { 98 iFloat = FloatVal; 99 } 100 101 void iDoubleSet() { 102 iDouble = DoubleVal; 103 } 104 105 void iStringSet() { 106 iString = StringVal; 107 } 108 109 void iObjectSet() { 110 iObject = ObjectVal; 111 } 112 113 static void sByteSet() { 114 sByte = ByteVal; 115 } 116 117 static void sCharSet() { 118 sChar = CharVal; 119 } 120 121 static void sShortSet() { 122 sShort = ShortVal; 123 } 124 125 static void sIntSet() { 126 sInt = IntVal; 127 } 128 129 static void sLongSet() { 130 sLong = LongVal; 131 } 132 133 static void sFloatSet() { 134 sFloat = FloatVal; 135 } 136 137 static void sDoubleSet() { 138 sDouble = DoubleVal; 139 } 140 141 static void sStringSet() { 142 sString = StringVal; 143 } 144 145 static void sObjectSet() { 146 sObject = ObjectVal; 147 } 148 149 void iUpdate(){ 150 iByteSet(); 151 iCharSet(); 152 iShortSet(); 153 iIntSet(); 154 iLongSet(); 155 iFloatSet(); 156 iDoubleSet(); 157 iStringSet(); 158 iObjectSet(); 159 } 160 161 static void sUpdate(){ 162 sByteSet(); 163 sCharSet(); 164 sShortSet(); 165 sIntSet(); 166 sLongSet(); 167 sFloatSet(); 168 sDoubleSet(); 169 sStringSet(); 170 sObjectSet(); 171 } 172 173 public static void main(String[] args){ 174 ModificationWatchpointsTarg targ = new ModificationWatchpointsTarg(); 175 for (int i = RepeatCount; i > 0; i--) { 176 sUpdate(); 177 targ.iUpdate(); 178 } 179 } 180 } 181 182 public class ModificationWatchpoints extends TestScaffold { 183 ReferenceType targ; 184 List allMWP = new ArrayList(); 185 186 ModificationWatchpoints (String args[]) { 187 super(args); 188 } 189 190 public static void main(String[] args) throws Exception { 191 new ModificationWatchpoints(args).startTests(); 192 } 193 194 /********** event handlers **********/ 195 196 public void fieldModified(ModificationWatchpointEvent event) { 197 MWP mwp = (MWP)event.request().getProperty("executor"); 198 mwp.fieldModified(event); 199 } 200 201 202 /********** test core **********/ 203 204 void set(String fieldName, String valString) { 205 Value val = targ.getValue(targ.fieldByName(valString)); 206 MWP mwp = new MWP("ModificationWatchpointsTarg", fieldName, val); 207 allMWP.add(mwp); 208 mwp.set(); 209 } 210 211 protected void runTests() throws Exception { 212 /* 213 * Get to the top of main(): 214 */ 215 BreakpointEvent bpe = startToMain("ModificationWatchpointsTarg"); 216 targ = bpe.location().declaringType(); 217 218 /* 219 * Set watchpoints 220 */ 221 set("iByte", "ByteVal"); 222 set("iChar", "CharVal"); 223 set("iShort", "ShortVal"); 224 set("iInt", "IntVal"); 225 set("iLong", "LongVal"); 226 set("iFloat", "FloatVal"); 227 set("iDouble", "DoubleVal"); 228 set("iString", "StringVal"); 229 set("iObject", "ObjectVal"); 230 231 set("sByte", "ByteVal"); 232 set("sChar", "CharVal"); 233 set("sShort", "ShortVal"); 234 set("sInt", "IntVal"); 235 set("sLong", "LongVal"); 236 set("sFloat", "FloatVal"); 237 set("sDouble", "DoubleVal"); 238 set("sString", "StringVal"); 239 set("sObject", "ObjectVal"); 240 241 listenUntilVMDisconnect(); 242 243 if (!testFailed) { 244 for (Iterator it = allMWP.iterator(); it.hasNext();) { 245 MWP mwp = (MWP)it.next(); 246 mwp.checkEventCounts(ModificationWatchpointsTarg.RepeatCount); 247 } 248 } 249 250 if (!testFailed) { 251 println("ModificationWatchpoints: passed"); 252 } else { 253 throw new Exception("ModificationWatchpoints: failed"); 254 } 255 } 256 257 /********** request wrapper **********/ 258 259 class MWP { 260 private final String className; 261 private final String fieldName; 262 private final Value expectedValue; 263 public int eventCount = 0; 264 public boolean failed = false; 265 266 public MWP(String className, String fieldName, Value value) { 267 this.className = className; 268 this.fieldName = fieldName; 269 this.expectedValue = value; 270 } 271 272 /* 273 * Sets watchpoint with specified properties. 274 */ 275 public void set() { 276 List classes = vm().classesByName(className); 277 if (classes.size() != 1) { 278 failure("Expected one class named " + className + " got " + classes.size()); 279 } 280 281 set ((ReferenceType)classes.get(0)); 282 } 283 284 /** 285 * Sets watchpoint for given class. 286 */ 287 public void set(ReferenceType clazz) { 288 Field f = clazz.fieldByName(fieldName); 289 ModificationWatchpointRequest mwr = 290 eventRequestManager().createModificationWatchpointRequest(f); 291 mwr.putProperty("executor", this); 292 mwr.enable(); 293 println("set watchpoint: " + className +"." + f); 294 } 295 296 public void fieldModified(ModificationWatchpointEvent event) { 297 Value val = event.valueToBe(); 298 println("Watchpoint reached: " + className + "." + fieldName + 299 ", new value: " + val); 300 if (!val.equals(expectedValue)) { 301 failure("FAILURE: value should be: " + 302 expectedValue.getClass() + ":" + expectedValue + 303 " has - " + val.getClass() + ":" + val); 304 } 305 if (!event.location().method().name().equals(fieldName + "Set")) { 306 failure("FAILURE: occurred in wrong place: " + event.location()); 307 } 308 eventCount++; 309 } 310 311 public void checkEventCounts(int expectedCount) { 312 if (eventCount != expectedCount) { 313 failure(className + "." + fieldName + 314 " - only got " + eventCount + " events"); 315 } 316 } 317 318 } // MWP inner class ................. 319 }