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