1 /* 2 * Copyright (c) 2001, 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 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! templete parameters !!!! 24 25 // VMDeathEvent Interface Name VMDeathEvent 26 // _itself_ Method Name _itself_ 27 // vmdeath003 Test Name vmdeath003 28 // ------------------------------------------------------ 29 30 package nsk.jdi.VMDeathEvent._itself_; 31 32 import nsk.share.*; 33 import nsk.share.jpda.*; 34 import nsk.share.jdi.*; 35 36 import com.sun.jdi.*; 37 import com.sun.jdi.event.*; 38 import com.sun.jdi.request.*; 39 40 import java.util.*; 41 import java.io.*; 42 43 /** 44 * The test for the implementation of an object of the type <BR> 45 * VMDeathEvent. <BR> 46 * <BR> 47 * The test checks that the interface <BR> 48 * <code>com.sun.jdi.VMDeathEvent</code> <BR> 49 * complies with its spec. <BR> 50 * <BR> 51 * The case to test includes receiving no VMDeathEvent <BR> 52 * as a response to VirtualMachine.dispose(); <BR> 53 * <BR> 54 * The test works as follows. <BR> 55 * <BR> 56 * Upon launching debuggee's VM which will be suspended, <BR> 57 * a debugger waits for the VMStartEvent within a predefined <BR> 58 * time interval. If no the VMStartEvent received, the test is FAILED. <BR> 59 * Upon getting the VMStartEvent, it makes the request for debuggee's <BR> 60 * ClassPrepareEvent with SUSPEND_EVENT_THREAD, resumes the VM, <BR> 61 * and waits for the event within the predefined time interval. <BR> 62 * If no the ClassPrepareEvent received, the test is FAILED. <BR> 63 * Upon getting the ClassPrepareEvent, <BR> 64 * the debugger sets up the breakpoint with SUSPEND_EVENT_THREAD <BR> 65 * within debuggee's special methodForCommunication(). <BR> 66 * <BR> 67 * Then to test the interface, <BR> 68 * the debugger invokes the method VirtualMachine.dispose() and <BR> 69 * checks up on the event received in the response to. <BR> 70 * <BR> 71 */ 72 73 public class vmdeath003 { 74 75 //----------------------------------------------------- templete section 76 static final int PASSED = 0; 77 static final int FAILED = 2; 78 static final int PASS_BASE = 95; 79 80 //----------------------------------------------------- templete parameters 81 static final String 82 sHeader1 = "\n==> nsk/jdi/VMDeathEvent/_itself_/vmdeath003 ", 83 sHeader2 = "--> debugger: ", 84 sHeader3 = "##> debugger: "; 85 86 //----------------------------------------------------- main method 87 main(String argv[])88 public static void main (String argv[]) { 89 90 int result = run(argv, System.out); 91 92 System.exit(result + PASS_BASE); 93 } 94 run(String argv[], PrintStream out)95 public static int run (String argv[], PrintStream out) { 96 97 int exitCode = new vmdeath003().runThis(argv, out); 98 99 if (exitCode != PASSED) { 100 System.out.println("TEST FAILED"); 101 } 102 return testExitCode; 103 } 104 105 //-------------------------------------------------- log procedures 106 107 private static Log logHandler; 108 log1(String message)109 private static void log1(String message) { 110 logHandler.display(sHeader1 + message); 111 } log2(String message)112 private static void log2(String message) { 113 logHandler.display(sHeader2 + message); 114 } log3(String message)115 private static void log3(String message) { 116 logHandler.complain(sHeader3 + message); 117 } 118 119 // ************************************************ test parameters 120 121 private String debuggeeName = 122 "nsk.jdi.VMDeathEvent._itself_.vmdeath003a"; 123 124 //====================================================== test program 125 //------------------------------------------------------ common section 126 127 static Debugee debuggee; 128 static ArgumentHandler argsHandler; 129 130 static int waitTime; 131 132 static VirtualMachine vm = null; 133 static EventRequestManager eventRManager = null; 134 static EventQueue eventQueue = null; 135 static EventSet eventSet = null; 136 static EventIterator eventIterator = null; 137 138 static ReferenceType debuggeeClass = null; 139 140 static int testExitCode = PASSED; 141 142 143 class JDITestRuntimeException extends RuntimeException { JDITestRuntimeException(String str)144 JDITestRuntimeException(String str) { 145 super("JDITestRuntimeException : " + str); 146 } 147 } 148 149 //------------------------------------------------------ methods 150 runThis(String argv[], PrintStream out)151 private int runThis (String argv[], PrintStream out) { 152 153 argsHandler = new ArgumentHandler(argv); 154 logHandler = new Log(out, argsHandler); 155 Binder binder = new Binder(argsHandler, logHandler); 156 157 waitTime = argsHandler.getWaitTime() * 60000; 158 159 try { 160 log2("launching a debuggee :"); 161 log2(" " + debuggeeName); 162 if (argsHandler.verbose()) { 163 debuggee = binder.bindToDebugee(debuggeeName + " -vbs"); 164 } else { 165 debuggee = binder.bindToDebugee(debuggeeName); 166 } 167 if (debuggee == null) { 168 log3("ERROR: no debuggee launched"); 169 return FAILED; 170 } 171 log2("debuggee launched"); 172 } catch ( Exception e ) { 173 log3("ERROR: Exception : " + e); 174 log2(" test cancelled"); 175 return FAILED; 176 } 177 178 debuggee.redirectOutput(logHandler); 179 180 vm = debuggee.VM(); 181 182 eventQueue = vm.eventQueue(); 183 if (eventQueue == null) { 184 log3("ERROR: eventQueue == null : TEST ABORTED"); 185 vm.exit(PASS_BASE); 186 return FAILED; 187 } 188 189 log2("invocation of the method runTest()"); 190 switch (runTest()) { 191 192 case 0 : log2("test phase has finished normally"); 193 log2(" waiting for the debuggee to finish ..."); 194 debuggee.waitFor(); 195 196 log2("......getting the debuggee's exit status"); 197 int status = debuggee.getStatus(); 198 if (status != PASS_BASE) { 199 log3("ERROR: debuggee returned UNEXPECTED exit status: " + 200 status + " != PASS_BASE"); 201 testExitCode = FAILED; 202 } else { 203 log2("......debuggee returned expected exit status: " + 204 status + " == PASS_BASE"); 205 } 206 break; 207 208 default : log3("ERROR: runTest() returned unexpected value"); 209 210 case 1 : log3("test phase has not finished normally: debuggee is still alive"); 211 log2("......forcing: vm.exit();"); 212 testExitCode = FAILED; 213 try { 214 vm.exit(PASS_BASE); 215 } catch ( Exception e ) { 216 log3("ERROR: Exception : e"); 217 } 218 break; 219 220 case 2 : //log3("test cancelled due to VMDisconnectedException"); 221 log2("......trying: vm.process().destroy();"); 222 // testExitCode = FAILED; 223 try { 224 Process vmProcess = vm.process(); 225 if (vmProcess != null) { 226 vmProcess.destroy(); 227 } 228 } catch ( Exception e ) { 229 log3("ERROR: Exception : e"); 230 } 231 break; 232 } 233 234 return testExitCode; 235 } 236 237 238 /* 239 * Return value: 0 - normal end of the test 240 * 1 - ubnormal end of the test 241 * 2 - VMDisconnectedException while test phase 242 */ 243 runTest()244 private int runTest() { 245 246 try { 247 testRun(); 248 249 log2("waiting for VMDisconnectEvent"); 250 getEventSet(); 251 Event newEvent = eventIterator.nextEvent(); 252 if (newEvent instanceof VMDeathEvent) { 253 testExitCode = FAILED; 254 log3("ERROR: last event is the VMDeathEvent"); 255 return 0; 256 } 257 if (newEvent instanceof VMDisconnectEvent) { 258 log2("......received : VMDisconnectEvent"); 259 return 2; 260 } 261 262 throw new JDITestRuntimeException("** Unexpected event **"); 263 } catch ( VMDisconnectedException e ) { 264 log3("ERROR: VMDisconnectedException : " + e); 265 return 2; 266 } catch ( Exception e ) { 267 log3("ERROR: Exception : " + e); 268 return 1; 269 } 270 271 } 272 testRun()273 private void testRun() 274 throws JDITestRuntimeException, Exception { 275 276 eventRManager = vm.eventRequestManager(); 277 278 ClassPrepareRequest cpRequest = eventRManager.createClassPrepareRequest(); 279 cpRequest.setSuspendPolicy( EventRequest.SUSPEND_EVENT_THREAD); 280 cpRequest.addClassFilter(debuggeeName); 281 282 cpRequest.enable(); 283 vm.resume(); 284 getEventSet(); 285 cpRequest.disable(); 286 287 ClassPrepareEvent event = (ClassPrepareEvent) eventIterator.next(); 288 debuggeeClass = event.referenceType(); 289 290 if (!debuggeeClass.name().equals(debuggeeName)) 291 throw new JDITestRuntimeException("** Unexpected ClassName for ClassPrepareEvent **"); 292 293 log2(" received: ClassPrepareEvent for debuggeeClass"); 294 295 String bPointMethod = "methodForCommunication"; 296 String lineForComm = "lineForComm"; 297 BreakpointRequest bpRequest; 298 299 bpRequest = settingBreakpoint(threadByName("main"), 300 debuggeeClass, 301 bPointMethod, lineForComm, "zero"); 302 bpRequest.enable(); 303 304 //------------------------------------------------------ testing section 305 306 log1(" TESTING BEGINS"); 307 308 for (int i = 0; ; i++) { 309 310 vm.resume(); 311 breakpointForCommunication(); 312 313 int instruction = ((IntegerValue) 314 (debuggeeClass.getValue(debuggeeClass.fieldByName("instruction")))).value(); 315 316 if (instruction == 0) { 317 vm.resume(); 318 break; 319 } 320 321 log1(":::::: case: # " + i); 322 323 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ variable part 324 325 log2("......vm.dispose(); :: VMDeathEvent is NOT excpected"); 326 327 vm.dispose(); 328 break; 329 330 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 331 } 332 log1(" TESTING ENDS"); 333 return; 334 } 335 threadByName(String name)336 private ThreadReference threadByName(String name) 337 throws JDITestRuntimeException { 338 339 List all = vm.allThreads(); 340 ListIterator li = all.listIterator(); 341 342 for (; li.hasNext(); ) { 343 ThreadReference thread = (ThreadReference) li.next(); 344 if (thread.name().equals(name)) 345 return thread; 346 } 347 throw new JDITestRuntimeException("** Thread IS NOT found ** : " + name); 348 } 349 350 /* 351 * private BreakpointRequest settingBreakpoint(ThreadReference, ReferenceType, 352 * String, String, String) 353 * 354 * It sets up a breakpoint at given line number within a given method in a given class 355 * for a given thread. 356 * 357 * Return value: BreakpointRequest object in case of success 358 * 359 * JDITestRuntimeException in case of an Exception thrown within the method 360 */ 361 settingBreakpoint( ThreadReference thread, ReferenceType testedClass, String methodName, String bpLine, String property)362 private BreakpointRequest settingBreakpoint ( ThreadReference thread, 363 ReferenceType testedClass, 364 String methodName, 365 String bpLine, 366 String property) 367 throws JDITestRuntimeException { 368 369 log2("......setting up a breakpoint:"); 370 log2(" thread: " + thread + "; class: " + testedClass + 371 "; method: " + methodName + "; line: " + bpLine); 372 373 List alllineLocations = null; 374 Location lineLocation = null; 375 BreakpointRequest breakpRequest = null; 376 377 try { 378 Method method = (Method) testedClass.methodsByName(methodName).get(0); 379 380 alllineLocations = method.allLineLocations(); 381 382 int n = 383 ( (IntegerValue) testedClass.getValue(testedClass.fieldByName(bpLine) ) ).value(); 384 if (n > alllineLocations.size()) { 385 log3("ERROR: TEST_ERROR_IN_settingBreakpoint(): number is out of bound of method's lines"); 386 } else { 387 lineLocation = (Location) alllineLocations.get(n); 388 try { 389 breakpRequest = eventRManager.createBreakpointRequest(lineLocation); 390 breakpRequest.putProperty("number", property); 391 breakpRequest.addThreadFilter(thread); 392 breakpRequest.setSuspendPolicy( EventRequest.SUSPEND_EVENT_THREAD); 393 } catch ( Exception e1 ) { 394 log3("ERROR: inner Exception within settingBreakpoint() : " + e1); 395 breakpRequest = null; 396 } 397 } 398 } catch ( Exception e2 ) { 399 log3("ERROR: ATTENTION: outer Exception within settingBreakpoint() : " + e2); 400 breakpRequest = null; 401 } 402 403 if (breakpRequest == null) { 404 log2(" A BREAKPOINT HAS NOT BEEN SET UP"); 405 throw new JDITestRuntimeException("**FAILURE to set up a breakpoint**"); 406 } 407 408 log2(" a breakpoint has been set up"); 409 return breakpRequest; 410 } 411 412 getEventSet()413 private void getEventSet() 414 throws JDITestRuntimeException { 415 try { 416 // log2(" eventSet = eventQueue.remove(waitTime);"); 417 eventSet = eventQueue.remove(waitTime); 418 if (eventSet == null) { 419 throw new JDITestRuntimeException("** TIMEOUT while waiting for event **"); 420 } 421 // log2(" eventIterator = eventSet.eventIterator;"); 422 eventIterator = eventSet.eventIterator(); 423 } catch ( Exception e ) { 424 throw new JDITestRuntimeException("** EXCEPTION while waiting for event ** : " + e); 425 } 426 } 427 428 breakpointForCommunication()429 private void breakpointForCommunication() 430 throws JDITestRuntimeException { 431 432 log2("breakpointForCommunication"); 433 getEventSet(); 434 435 if (eventIterator.nextEvent() instanceof BreakpointEvent) 436 return; 437 438 throw new JDITestRuntimeException("** event IS NOT a breakpoint **"); 439 } 440 441 } 442