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.owningThread; 25 26 import nsk.share.*; 27 import nsk.share.jpda.*; 28 import nsk.share.jdi.*; 29 30 import com.sun.jdi.*; 31 import com.sun.jdi.connect.*; 32 import com.sun.jdi.request.*; 33 import com.sun.jdi.event.*; 34 import java.io.*; 35 import java.util.*; 36 37 /** 38 */ 39 public class owningthread002 { 40 41 //----------------------------------------------------- immutable common fields 42 43 static final int PASSED = 0; 44 static final int FAILED = 2; 45 static final int PASS_BASE = 95; 46 static final int quit = -1; 47 48 private int instruction = 1; 49 private int waitTime; 50 private static int exitCode = PASSED; 51 52 private ArgumentHandler argHandler; 53 private Log log; 54 private Debugee debuggee; 55 private VirtualMachine vm; 56 private ReferenceType debuggeeClass; 57 58 private EventRequestManager eventRManager; 59 private EventSet eventSet; 60 private EventIterator eventIterator; 61 62 //------------------------------------------------------ mutable common fields 63 64 private final static String prefix = "nsk.jdi.ObjectReference.owningThread."; 65 private final static String className = "owningthread002"; 66 private final static String debuggerName = prefix + className; 67 private final static String debuggeeName = debuggerName + "a"; 68 static final int lineForBreak = 62; 69 70 //------------------------------------------------------ immutable common methods 71 main(String argv[])72 public static void main (String argv[]) { 73 System.exit(run(argv, System.out) + PASS_BASE); 74 } 75 76 //------------------------------------------------------ test specific fields 77 78 //------------------------------------------------------ mutable common methods 79 run(String argv[], PrintStream out)80 public static int run (String argv[], PrintStream out) { 81 82 int exitStatus = new owningthread002().runThis(argv, out); 83 System.out.println (exitStatus == PASSED ? "TEST PASSED" : "TEST FAILED"); 84 return exitCode; 85 } 86 runThis(String argv[], PrintStream out)87 private int runThis(String argv[], PrintStream out) { 88 89 argHandler = new ArgumentHandler(argv); 90 log = new Log(out, argHandler); 91 waitTime = argHandler.getWaitTime() * 60000; 92 93 try { 94 95 Binder binder = new Binder(argHandler, log); 96 debuggee = binder.bindToDebugee(debuggeeName); 97 debuggee.redirectStderr(log, ""); 98 eventRManager = debuggee.getEventRequestManager(); 99 100 vm = debuggee.VM(); 101 eventRManager = vm.eventRequestManager(); 102 103 debuggeeClass = waitForDebuggeeClassPrepared(); 104 105 execTest(); 106 107 debuggee.resume(); 108 getEventSet(); 109 if (eventIterator.nextEvent() instanceof VMDeathEvent) { 110 display("Waiting for the debuggee's finish..."); 111 debuggee.waitFor(); 112 113 display("Getting the debuggee's exit status."); 114 int status = debuggee.getStatus(); 115 if (status != (PASSED + PASS_BASE)) { 116 complain("Debuggee returned UNEXPECTED exit status: " + status); 117 exitCode = Consts.TEST_FAILED; 118 } 119 } else { 120 throw new TestBug("Last event is not the VMDeathEvent"); 121 } 122 123 } catch (VMDisconnectedException e) { 124 exitCode = Consts.TEST_FAILED; 125 complain("The test cancelled due to VMDisconnectedException."); 126 e.printStackTrace(out); 127 display("Trying: vm.process().destroy();"); 128 if (vm != null) { 129 Process vmProcess = vm.process(); 130 if (vmProcess != null) { 131 vmProcess.destroy(); 132 } 133 } 134 135 } catch (Exception e) { 136 exitCode = Consts.TEST_FAILED; 137 complain("Unexpected Exception: " + e.getMessage()); 138 e.printStackTrace(out); 139 complain("The test has not finished normally. Forcing: vm.exit()."); 140 if (vm != null) { 141 vm.exit(PASSED + PASS_BASE); 142 } 143 debuggee.resume(); 144 getEventSet(); 145 } 146 147 return exitCode; 148 } 149 150 //--------------------------------------------------------- mutable common methods 151 execTest()152 private void execTest() { 153 ThreadReference mainThread = debuggee.threadByName("main"); 154 155 BreakpointRequest bpRequest = debuggee.makeBreakpoint(debuggeeClass, 156 "methodForCommunication", 157 lineForBreak); 158 bpRequest.addThreadFilter(mainThread); 159 bpRequest.putProperty("number", "breakpointForCommunication"); 160 bpRequest.enable(); 161 162 display("TESTING BEGINS"); 163 164 label0: 165 for (int testCase = 0; instruction != quit; testCase++) { 166 167 waitForEvent(bpRequest); 168 instruction = getInstruction(); 169 if (instruction == quit) { 170 vm.resume(); 171 break; 172 } 173 174 display(":: case: # " + testCase); 175 176 switch (testCase) { 177 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test case section 178 case 0: 179 180 if (vm.canGetMonitorInfo()) { 181 // create method entry request to track the moments of locking of owningthread002.lockObj 182 MethodEntryRequest meRequest = eventRManager.createMethodEntryRequest(); 183 meRequest.addClassFilter(debuggeeName + "Lock"); 184 meRequest.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD ); 185 meRequest.enable(); 186 display("methodEntryRequest is enabled "); 187 188 String fieldName = "lockObj"; 189 ObjectReference lockRef = (ObjectReference) debuggeeClass.getValue(debuggeeClass.fieldByName(fieldName)); 190 191 for (int i = 1; i <= owningthread002a.threadCount; i++) { 192 193 Event meEvent = waitForEvent(meRequest); 194 ThreadReference eventThread = ((LocatableEvent)meEvent).thread(); 195 display("Checking owningThread method after MethodEntryEvent in thread : " + eventThread ); 196 197 try { 198 ThreadReference thread = lockRef.owningThread(); 199 200 if (thread.name().indexOf(owningthread002a.threadNamePrefix) < 0) { 201 exitCode = Consts.TEST_FAILED; 202 complain("owningThread returned ThreadReference with unexpected name: " + thread.name()); 203 } 204 if (!eventThread.equals(thread)) { 205 exitCode = Consts.TEST_FAILED; 206 complain("owningThread returned unexpected ThreadReference : " + thread + 207 "\n\t expected ThreadReference returned by MethodEntryEvent.thread() : " + eventThread ); 208 } else { 209 display("Expected ThreadReference is returned by owningThread method: " + thread.name()); 210 } 211 212 } catch (Exception e) { 213 throw new Failure("Unexpected exception while invoking owningThread method: " + e); 214 } 215 } 216 meRequest.disable(); 217 } 218 break; 219 220 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ end of section 221 default: 222 instruction = quit; 223 setInstruction("quit"); 224 } 225 } 226 display("TESTING ENDS"); 227 } 228 229 //--------------------------------------------------------- test specific methodss 230 231 //--------------------------------------------------------- immutable common methods 232 display(String msg)233 void display(String msg) { 234 log.display("debugger > " + msg); 235 } 236 complain(String msg)237 void complain(String msg) { 238 log.complain("debugger FAILURE > " + msg); 239 } 240 waitForEvent(EventRequest eventRequest)241 private Event waitForEvent (EventRequest eventRequest) { 242 243 vm.resume(); 244 Event resultEvent = null; 245 try { 246 eventSet = null; 247 eventIterator = null; 248 eventSet = vm.eventQueue().remove(waitTime); 249 if (eventSet == null) { 250 throw new Failure("TIMEOUT while waiting for an event"); 251 } 252 eventIterator = eventSet.eventIterator(); 253 while (eventIterator.hasNext()) { 254 Event curEvent = eventIterator.nextEvent(); 255 if (curEvent instanceof VMDisconnectEvent) { 256 throw new Failure("Unexpected VMDisconnectEvent received."); 257 } else { 258 EventRequest evRequest = curEvent.request(); 259 if (evRequest != null && evRequest.equals(eventRequest)) { 260 display("Requested event received: " + curEvent.toString() + 261 "; request property: " + (String) curEvent.request().getProperty("number")); 262 resultEvent = curEvent; 263 break; 264 } else { 265 throw new Failure("Unexpected event received: " + curEvent.toString()); 266 } 267 } 268 } 269 } catch (Exception e) { 270 throw new Failure("Unexpected exception while waiting for an event: " + e); 271 } 272 return resultEvent; 273 } 274 275 getEventSet()276 private void getEventSet() { 277 try { 278 eventSet = vm.eventQueue().remove(waitTime); 279 if (eventSet == null) { 280 throw new Failure("TIMEOUT while waiting for an event"); 281 } 282 eventIterator = eventSet.eventIterator(); 283 } catch (Exception e) { 284 throw new Failure("getEventSet(): Unexpected exception while waiting for an event: " + e); 285 } 286 } 287 waitForDebuggeeClassPrepared()288 private ReferenceType waitForDebuggeeClassPrepared () { 289 display("Creating request for ClassPrepareEvent for debuggee."); 290 ClassPrepareRequest cpRequest = eventRManager.createClassPrepareRequest(); 291 cpRequest.addClassFilter(debuggeeName); 292 cpRequest.addCountFilter(1); 293 cpRequest.enable(); 294 295 ClassPrepareEvent event = (ClassPrepareEvent) waitForEvent(cpRequest); 296 cpRequest.disable(); 297 298 if (!event.referenceType().name().equals(debuggeeName)) { 299 throw new Failure("Unexpected class name for ClassPrepareEvent : " + debuggeeClass.name()); 300 } 301 return event.referenceType(); 302 } 303 getInstruction()304 private int getInstruction () { 305 if (debuggeeClass == null) { 306 throw new Failure("getInstruction() :: debuggeeClass reference is null"); 307 } 308 return ((IntegerValue) (debuggeeClass.getValue(debuggeeClass.fieldByName("instruction")))).value(); 309 } 310 setInstruction(String instructionField)311 private void setInstruction (String instructionField) { 312 if (debuggeeClass == null) { 313 throw new Failure("getInstruction() :: debuggeeClass reference is null"); 314 } 315 Field instrField = debuggeeClass.fieldByName("instruction"); 316 IntegerValue instrValue = (IntegerValue) (debuggeeClass.getValue(debuggeeClass.fieldByName(instructionField))); 317 try { 318 ((ClassType)debuggeeClass).setValue(instrField, instrValue ); 319 } catch (InvalidTypeException e1) { 320 throw new Failure("Caught unexpected InvalidTypeException while setting value '" + instructionField + "' for instruction field"); 321 } catch (ClassNotLoadedException e2) { 322 throw new Failure("Caught unexpected ClassNotLoadedException while setting value '" + instructionField + "' for instruction field"); 323 } 324 } 325 } 326