1 /* 2 * Copyright (c) 2002, 2018, 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 package nsk.jdi.ObjectReference.setValue; 25 26 import com.sun.jdi.ObjectReference; 27 import com.sun.jdi.ReferenceType; 28 import com.sun.jdi.ThreadReference; 29 import com.sun.jdi.LocalVariable; 30 import com.sun.jdi.StackFrame; 31 import com.sun.jdi.Field; 32 import com.sun.jdi.AbsentInformationException; 33 import com.sun.jdi.NativeMethodException; 34 35 import java.util.Iterator; 36 import java.util.List; 37 import java.io.*; 38 39 import nsk.share.*; 40 import nsk.share.jpda.*; 41 import nsk.share.jdi.*; 42 43 /** 44 * The test checks that the JDI method 45 * <code>com.sun.jdi.ObjectReference.setValue()</code> 46 * properly throws <i>IllegalArgumentException</i> - if the 47 * field is not valid for this object's class.<br> 48 * The debuggee part of the test contains two classes: the main one 49 * <i>setvalue002t</i> and the dummy one <i>DummyClass</i>. Each of 50 * them has the same set of static and instance fields.<br> 51 * The debugger part provokes the IllegalArgumentException trying to 52 * set value of: 53 * <li>an object reference to the debuggee's class <i>setvalue002t</i> 54 * and Field's value from an object reference to the debuggee's class 55 * <i>DummyClass</i> 56 * <li>an object reference to the debuggee's class <i>DummyClass</i> 57 * and Field's value from an object reference to the debuggee's class 58 * <i>setvalue002t</i>.<br> 59 */ 60 public class setvalue002 { 61 static final String DEBUGGEE_CLASS = 62 "nsk.jdi.ObjectReference.setValue.setvalue002t"; 63 64 // name of debuggee's main thread 65 static final String DEBUGGEE_THRNAME = "setvalue002tThr"; 66 67 // debuggee's local var used to find needed stack frame 68 static final String DEBUGGEE_LOCALVAR = "dummyCls"; 69 70 static final int ATTEMPTS = 5; 71 72 static final String COMMAND_READY = "ready"; 73 static final String COMMAND_QUIT = "quit"; 74 75 private Log log; 76 private IOPipe pipe; 77 private Debugee debuggee; 78 private ThreadReference thrRef = null; 79 private ObjectReference[] objRef = new ObjectReference[2]; 80 private int tot_res = Consts.TEST_PASSED; 81 main(String argv[])82 public static void main (String argv[]) { 83 System.exit(run(argv,System.out) + Consts.JCK_STATUS_BASE); 84 } 85 run(String argv[], PrintStream out)86 public static int run(String argv[], PrintStream out) { 87 return new setvalue002().runIt(argv, out); 88 } 89 runIt(String args[], PrintStream out)90 private int runIt(String args[], PrintStream out) { 91 ArgumentHandler argHandler = new ArgumentHandler(args); 92 log = new Log(out, argHandler); 93 Binder binder = new Binder(argHandler, log); 94 ReferenceType[] rType = new ReferenceType[2]; 95 String cmd; 96 int num = 0; 97 98 debuggee = binder.bindToDebugee(DEBUGGEE_CLASS); 99 pipe = debuggee.createIOPipe(); 100 debuggee.redirectStderr(log, "setvalue002t.err> "); 101 debuggee.resume(); 102 cmd = pipe.readln(); 103 if (!cmd.equals(COMMAND_READY)) { 104 log.complain("TEST BUG: unknown debuggee's command: " + cmd); 105 tot_res = Consts.TEST_FAILED; 106 return quitDebuggee(); 107 } 108 109 if ((thrRef = 110 debuggee.threadByName(DEBUGGEE_THRNAME)) == null) { 111 log.complain("TEST FAILURE: Method Debugee.threadByName() returned null for debuggee's thread " 112 + DEBUGGEE_THRNAME); 113 tot_res = Consts.TEST_FAILED; 114 return quitDebuggee(); 115 } 116 thrRef.suspend(); 117 while(!thrRef.isSuspended()) { 118 num++; 119 if (num > ATTEMPTS) { 120 log.complain("TEST FAILED: Unable to suspend debuggee's thread"); 121 tot_res = Consts.TEST_FAILED; 122 return quitDebuggee(); 123 } 124 log.display("Waiting for debuggee's thread suspension ..."); 125 try { 126 Thread.currentThread().sleep(1000); 127 } catch(InterruptedException ie) { 128 log.complain("TEST FAILED: caught: " + ie); 129 tot_res = Consts.TEST_FAILED; 130 return quitDebuggee(); 131 } 132 } 133 134 // Check the tested assersion 135 try { 136 findObjRefs(DEBUGGEE_LOCALVAR); 137 rType[0] = objRef[0].referenceType(); 138 rType[1] = objRef[1].referenceType(); 139 140 // provoke the IllegalArgumentException using an object reference 141 // to debuggee's main class "setvalue002t" and Field's value from 142 // an object reference to debuggee's dummy class "DummyClass" 143 provokeException(objRef[0], rType[0], objRef[1], rType[1]); 144 145 // provoke the IllegalArgumentException using an object reference 146 // to debuggee's dummy class "DummyClass" and Field's value from 147 // an object reference to debuggee's main class "setvalue002t" 148 provokeException(objRef[1], rType[1], objRef[0], rType[0]); 149 } catch (Exception e) { 150 e.printStackTrace(); 151 log.complain("TEST FAILURE: caught unexpected exception: " + e); 152 tot_res = Consts.TEST_FAILED; 153 return quitDebuggee(); 154 } 155 156 // Finish the test 157 thrRef.resume(); 158 return quitDebuggee(); 159 } 160 findObjRefs(String varName)161 private void findObjRefs(String varName) { 162 try { 163 List frames = thrRef.frames(); 164 Iterator iter = frames.iterator(); 165 while (iter.hasNext()) { 166 StackFrame stackFr = (StackFrame) iter.next(); 167 try { 168 LocalVariable locVar = stackFr.visibleVariableByName(varName); 169 if (locVar == null) 170 continue; 171 // main debuggee class 172 objRef[0] = stackFr.thisObject(); 173 // dummy debuggee class 174 objRef[1] = (ObjectReference)stackFr.getValue(locVar); 175 return; 176 } catch(AbsentInformationException e) { 177 // this is not needed stack frame, ignoring 178 } catch(NativeMethodException ne) { 179 // current method is native, also ignoring 180 } 181 } 182 } catch (Exception e) { 183 e.printStackTrace(); 184 tot_res = Consts.TEST_FAILED; 185 throw new Failure("findObjRef: caught unexpected exception: " + e); 186 } 187 throw new Failure("findObjRef: needed debuggee's stack frame not found"); 188 } 189 provokeException(ObjectReference objRef, ReferenceType refType, ObjectReference fldObjRef, ReferenceType fldRefType)190 private void provokeException(ObjectReference objRef, 191 ReferenceType refType, 192 ObjectReference fldObjRef, ReferenceType fldRefType) { 193 List fields; 194 195 try { 196 fields = fldRefType.allFields(); 197 } catch (Exception e) { 198 e.printStackTrace(); 199 log.complain("TEST FAILURE: allFields for " 200 + fldObjRef + ": caught: " + e); 201 tot_res = Consts.TEST_FAILED; 202 throw new Failure("provokeException: caught unexpected exception"); 203 } 204 205 Iterator iter = fields.iterator(); 206 while (iter.hasNext()) { 207 Field fld = (Field) iter.next(); 208 try { 209 log.display("\nTrying to set value for the field \"" 210 + fld.name() + "\"\n\tfrom the debuggee's object reference \"" 211 + objRef 212 + "\"\n\tusing not valid Field's value from the other object reference \"" 213 + fldObjRef + "\" ..."); 214 objRef.setValue(fld, objRef.getValue(refType.fieldByName(fld.name()))); 215 log.complain("TEST FAILED: expected IllegalArgumentException was not thrown" 216 + "\n\twhen attempted to set value for the field \"" 217 + fld.name() + "\"\n\tfrom the debuggee's object reference \"" 218 + objRef 219 + "\n\tusing not valid Field's value from the other object reference \"" 220 + fldObjRef + "\""); 221 tot_res = Consts.TEST_FAILED; 222 } catch (IllegalArgumentException ee) { 223 log.display("CHECK PASSED: caught expected " + ee); 224 } catch (Exception e) { 225 e.printStackTrace(); 226 log.complain("TEST FAILED: ObjectReference.setValue(): caught unexpected " 227 + e + "\n\tinstead of expected IllegalArgumentException" 228 + "\n\twhen attempted to set value for the field \"" 229 + fld.name() + "\"\n\tfrom the debuggee's object reference \"" 230 + objRef 231 + "\n\tusing not valid Field's value from the other object reference \"" 232 + fldObjRef + "\""); 233 tot_res = Consts.TEST_FAILED; 234 } 235 } 236 } 237 quitDebuggee()238 private int quitDebuggee() { 239 if (thrRef != null) { 240 if (thrRef.isSuspended()) 241 thrRef.resume(); 242 } 243 pipe.println(COMMAND_QUIT); 244 debuggee.waitFor(); 245 int debStat = debuggee.getStatus(); 246 if (debStat != (Consts.JCK_STATUS_BASE + Consts.TEST_PASSED)) { 247 log.complain("TEST FAILED: debuggee's process finished with status: " 248 + debStat); 249 tot_res = Consts.TEST_FAILED; 250 } else 251 log.display("Debuggee's process finished with the status: " 252 + debStat); 253 254 return tot_res; 255 } 256 257 } 258