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