1 /* 2 * Copyright (c) 2001, 2019, 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.ClassType.newInstance; 25 26 import nsk.share.*; 27 import nsk.share.jpda.*; 28 import nsk.share.jdi.*; 29 30 import com.sun.jdi.*; 31 import java.util.*; 32 import java.io.*; 33 34 import com.sun.jdi.event.*; 35 import com.sun.jdi.request.*; 36 37 /** 38 * The test for the implementation of an object of the type <BR> 39 * ClassType. <BR> 40 * <BR> 41 * The test checks up that results of the method <BR> 42 * <code>com.sun.jdi.ClassType.newInstance()</code> <BR> 43 * complies with its specification. <BR> 44 * The case for testing includes invoking the method to create <BR> 45 * new instance of the class TestClass <BR> 46 * which is global to a class implementing debuggee's thread <BR> 47 * in which instance creation is performed. <BR> 48 * No exception is expected to be thrown in response to call <BR> 49 * to the method. <BR> 50 * <BR> 51 * The test works as follows. <BR> 52 * A debugger launchs a debuggee which creates new thread, thread2. <BR> 53 * The tested class TestClass is specified outside of the class <BR> 54 * Threadnewinstance002a extends Thread <BR> 55 * After getting thread2 running but locked at a monitor <BR> 56 * the debugger informs the debugger of the thread2 creation <BR> 57 * and waits for an instruction from it. <BR> 58 * Upon receiving the message from the debuggee, the debugger <BR> 59 * sets up a breakpoint for the thread2 and instructs the <BR> 60 * debuggee to unlock the thread2 and after getting it suspended<BR> 61 * at the breakpoint, prepares arguments and invokes the method.<BR> 62 * After the method completes, the debugger checks up on <BR> 63 * a returned ObjectReference value; <BR> 64 * the following is expected to be true: <BR> 65 * objRef.referenceType().equals(classType) <BR> 66 * where <BR> 67 * ObjectReference objRef - is returned value <BR> 68 * ClassType classType - is a mirror of the tested class.<BR> 69 */ 70 71 public class newinstance001 { 72 73 //----------------------------------------------------- templete section 74 static final int PASSED = 0; 75 static final int FAILED = 2; 76 static final int PASS_BASE = 95; 77 78 //----------------------------------------------------- templete parameters 79 static final String 80 sHeader1 = "\n==> nsk/jdi/ClassType/newInstance/newinstance001 ", 81 sHeader2 = "--> debugger: ", 82 sHeader3 = "##> debugger: "; 83 84 //----------------------------------------------------- main method 85 main(String argv[])86 public static void main (String argv[]) { 87 int result = run(argv, System.out); 88 System.exit(result + PASS_BASE); 89 } 90 run(String argv[], PrintStream out)91 public static int run (String argv[], PrintStream out) { 92 return new newinstance001().runThis(argv, out); 93 } 94 95 //-------------------------------------------------- log procedures 96 97 private static Log logHandler; 98 log1(String message)99 private static void log1(String message) { 100 logHandler.display(sHeader1 + message); 101 } log2(String message)102 private static void log2(String message) { 103 logHandler.display(sHeader2 + message); 104 } log3(String message)105 private static void log3(String message) { 106 logHandler.complain(sHeader3 + message); 107 } 108 109 // ************************************************ test parameters 110 111 private String debuggeeName = 112 "nsk.jdi.ClassType.newInstance.newinstance001a"; 113 114 private String testedClassName = 115 "nsk.jdi.ClassType.newInstance.TestClass"; 116 117 private String threadName = "testedThread"; 118 119 private String threadClassName = 120 "nsk.jdi.ClassType.newInstance.Threadnewinstance001a"; 121 122 //String mName = "nsk.jdi.ClassType.newInstance"; 123 124 //====================================================== test program 125 //------------------------------------------------------ common section 126 127 static ArgumentHandler argsHandler; 128 129 static int waitTime; 130 131 static VirtualMachine vm = null; 132 static EventRequestManager eventRManager = null; 133 static EventQueue eventQueue = null; 134 static EventSet eventSet = null; 135 136 ReferenceType testedClass = null; 137 138 ReferenceType threadClass = null; 139 140 ThreadReference thread2 = null; 141 ThreadReference mainThread = null; 142 143 static int testExitCode = PASSED; 144 145 static final int returnCode0 = 0; 146 static final int returnCode1 = 1; 147 static final int returnCode2 = 2; 148 static final int returnCode3 = 3; 149 static final int returnCode4 = 4; 150 151 //------------------------------------------------------ methods 152 runThis(String argv[], PrintStream out)153 private int runThis (String argv[], PrintStream out) { 154 155 Debugee debuggee; 156 157 argsHandler = new ArgumentHandler(argv); 158 logHandler = new Log(out, argsHandler); 159 Binder binder = new Binder(argsHandler, logHandler); 160 161 if (argsHandler.verbose()) { 162 debuggee = binder.bindToDebugee(debuggeeName + " -vbs"); 163 } else { 164 debuggee = binder.bindToDebugee(debuggeeName); 165 } 166 167 waitTime = argsHandler.getWaitTime(); 168 169 170 IOPipe pipe = new IOPipe(debuggee); 171 172 debuggee.redirectStderr(out); 173 log2(debuggeeName + " debuggee launched"); 174 debuggee.resume(); 175 176 String line = pipe.readln(); 177 if ((line == null) || !line.equals("ready")) { 178 log3("signal received is not 'ready' but: " + line); 179 return FAILED; 180 } else { 181 log2("'ready' recieved"); 182 } 183 184 vm = debuggee.VM(); 185 186 //------------------------------------------------------ testing section 187 log1(" TESTING BEGINS"); 188 189 for (int i = 0; ; i++) { 190 191 pipe.println("newcheck"); 192 line = pipe.readln(); 193 194 if (line.equals("checkend")) { 195 log2(" : returned string is 'checkend'"); 196 break ; 197 } else if (!line.equals("checkready")) { 198 log3("ERROR: returned string is not 'checkready'"); 199 testExitCode = FAILED; 200 break ; 201 } 202 203 log1("new checkready: #" + i); 204 205 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ variable part 206 207 int expresult = returnCode0; 208 209 210 eventRManager = vm.eventRequestManager(); 211 eventQueue = vm.eventQueue(); 212 213 String breakpointMethod1 = "runt1"; 214 215 String bpLine1 = "breakpointLineNumber1"; 216 217 List allThreads = null; 218 ListIterator listIterator = null; 219 List classes = null; 220 221 BreakpointRequest breakpRequest1 = null; 222 223 ClassType classType = null; 224 225 label0: { 226 227 log2("getting ThreadReference object"); 228 try { 229 allThreads = vm.allThreads(); 230 classes = vm.classesByName(threadClassName); 231 threadClass = (ReferenceType) classes.get(0); 232 } catch ( Exception e) { 233 log3("ERROR: Exception at very beginning !? : " + e); 234 expresult = returnCode1; 235 break label0; 236 } 237 238 239 log2("......getting Thread thread2 - 1-st argument"); 240 listIterator = allThreads.listIterator(); 241 for (;;) { 242 try { 243 thread2 = (ThreadReference) listIterator.next(); 244 if (thread2.name().equals(threadName)) 245 break ; 246 } catch ( NoSuchElementException e ) { 247 log3("ERROR: NoSuchElementException for listIterator.next()"); 248 log3("ERROR: NO THREAD2 ?????????!!!!!!!"); 249 expresult = returnCode1; 250 break label0; 251 } 252 } 253 254 log2("setting up a breakpoint"); 255 256 breakpRequest1 = settingBreakpoint(breakpointMethod1, bpLine1, "one"); 257 if (breakpRequest1 == null) { 258 expresult = returnCode1; 259 break label0; 260 } 261 } 262 263 label1: { 264 265 if (expresult != returnCode0) 266 break label1; 267 268 log2(" enabling breakpRequest1"); 269 breakpRequest1.enable(); 270 271 log2(" forcing the main thread to leave synchronized block"); 272 pipe.println("continue"); 273 line = pipe.readln(); 274 if (!line.equals("docontinue")) { 275 log3("ERROR: returned string is not 'docontinue'"); 276 expresult = returnCode4; 277 break label1; 278 } 279 280 log2(" getting BreakpointEvent"); 281 expresult = breakpoint(); 282 if (expresult != returnCode0) 283 break label1; 284 log2(" thread2 is at breakpoint"); 285 286 287 log2("......getting ClassType classType - an object to apply newInstance()"); 288 classes = vm.classesByName(testedClassName); 289 testedClass = (ReferenceType) classes.get(0); 290 classType = (ClassType) testedClass; 291 292 List invokeMethods = testedClass.methods(); 293 ListIterator li = invokeMethods.listIterator(); 294 295 Method invokeMethod = null; 296 297 log2("......getting Method invokeMethod - a constructor to invoke; 2-nd argument"); 298 try { 299 for (;;) { 300 invokeMethod = (Method) li.next(); 301 if (!invokeMethod.isConstructor()) 302 continue; 303 if (invokeMethod.arguments().size() == 0) 304 break; 305 } 306 } catch ( AbsentInformationException e1 ) { 307 log2(" AbsentInformationException "); 308 break label1; 309 } catch ( NoSuchElementException e2 ) { 310 log3("ERROR: NoSuchElementException "); 311 expresult = returnCode2; 312 break label1; 313 } 314 315 316 // this is only to get an empty List with JDI methods but not with API List methods 317 log2("......forming an empty List argumentList for 3-d argument"); 318 log2(" List argumentList = testedClass.methodsByName('m');"); 319 List<Method> argumentListm = testedClass.methodsByName("m"); 320 log2(" argumentList.clear();"); 321 argumentListm.clear(); 322 List<? extends Value> argumentList = Collections.emptyList(); 323 324 ObjectReference objRef = null; 325 326 log2("......ObjectReference objRef = classType.newInstance(thread2, invokeMethod, argumentList, 0);"); 327 log2(" No Exception is expected"); 328 try { 329 objRef = classType.newInstance(thread2, 330 invokeMethod, argumentList, 0); 331 if (objRef == null) 332 log2(" objRe == null"); 333 334 335 log2(" ReferenceType refType = objRef.referenceType();"); 336 ReferenceType refType = objRef.referenceType(); 337 338 log2(" ClassType cType = (ClassType) refType;"); 339 ClassType cType = (ClassType) refType; 340 341 log2("......checking up on: cType.equals(classType); "); 342 if (!cType.equals(classType)) { 343 log3("ERROR: !cType.equals(classType)"); 344 expresult = returnCode1; 345 } 346 347 } catch ( Exception e ) { 348 log3("ERROR: Exception for classType.newInstance() :" + e); 349 expresult = returnCode1; 350 } 351 } 352 vm.resume(); 353 354 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 355 log2(" the end of testing"); 356 if (expresult != returnCode0) 357 testExitCode = FAILED; 358 } 359 log1(" TESTING ENDS"); 360 361 //-------------------------------------------------- test summary section 362 //------------------------------------------------- standard end section 363 364 pipe.println("quit"); 365 log2("waiting for the debuggee to finish ..."); 366 debuggee.waitFor(); 367 368 int status = debuggee.getStatus(); 369 if (status != PASSED + PASS_BASE) { 370 log3("debuggee returned UNEXPECTED exit status: " + 371 status + " != PASS_BASE"); 372 testExitCode = FAILED; 373 } else { 374 log2("debuggee returned expected exit status: " + 375 status + " == PASS_BASE"); 376 } 377 378 if (testExitCode != PASSED) { 379 System.out.println("TEST FAILED"); 380 } 381 return testExitCode; 382 } 383 384 385 /* 386 * private BreakpointRequest settingBreakpoint(String, String, String) 387 * 388 * It sets up a breakpoint within a given method at given line number 389 * for the thread2 only. 390 * Third parameter is required for any case in future debugging, as if. 391 * 392 * Return codes: 393 * = BreakpointRequest object in case of success 394 * = null in case of an Exception thrown within the method 395 */ 396 settingBreakpoint( String methodName, String bpLine, String property)397 private BreakpointRequest settingBreakpoint ( String methodName, 398 String bpLine, 399 String property) { 400 401 log2("setting up a breakpoint: method: '" + methodName + "' line: " + bpLine ); 402 403 List alllineLocations = null; 404 Location lineLocation = null; 405 BreakpointRequest breakpRequest = null; 406 407 try { 408 // Method method = (Method) testedclass.methodsByName(methodName).get(0); 409 Method method = (Method) threadClass.methodsByName(methodName).get(0); 410 411 alllineLocations = method.allLineLocations(); 412 413 int n = 414 // ( (IntegerValue) testedclass.getValue(testedclass.fieldByName(bpLine) ) ).value(); 415 ( (IntegerValue) threadClass.getValue(threadClass.fieldByName(bpLine) ) ).value(); 416 if (n > alllineLocations.size()) { 417 log3("ERROR: TEST_ERROR_IN_settingBreakpoint(): number is out of bound of method's lines"); 418 } else { 419 lineLocation = (Location) alllineLocations.get(n); 420 try { 421 breakpRequest = eventRManager.createBreakpointRequest(lineLocation); 422 breakpRequest.putProperty("number", property); 423 breakpRequest.addThreadFilter(thread2); 424 breakpRequest.setSuspendPolicy( EventRequest.SUSPEND_EVENT_THREAD); 425 } catch ( Exception e1 ) { 426 log3("ERROR: inner Exception within settingBreakpoint() : " + e1); 427 breakpRequest = null; 428 } 429 } 430 } catch ( Exception e2 ) { 431 log3("ERROR: ATTENTION: outer Exception within settingBreakpoint() : " + e2); 432 breakpRequest = null; 433 } 434 435 if (breakpRequest == null) 436 log2(" A BREAKPOINT HAS NOT BEEN SET UP"); 437 else 438 log2(" a breakpoint has been set up"); 439 440 return breakpRequest; 441 } 442 443 444 /* 445 * private int breakpoint () 446 * 447 * It removes events from EventQueue until gets first BreakpointEvent. 448 * To get next EventSet value, it uses the method 449 * EventQueue.remove(int timeout) 450 * The timeout argument passed to the method, is "waitTime*60000". 451 * Note: the value of waitTime is set up with 452 * the method ArgumentHandler.getWaitTime() at the beginning of the test. 453 * 454 * Return codes: 455 * = returnCode0 - success; 456 * = returnCode2 - Exception when "eventSet = eventQueue.remove()" is executed 457 * = returnCode3 - default case when loop of processing an event, that is, 458 * an unspecified event was taken from the EventQueue 459 */ 460 breakpoint()461 private int breakpoint () { 462 463 int returnCode = returnCode0; 464 465 log2(" waiting for BreakpointEvent"); 466 467 labelBP: 468 for (;;) { 469 470 log2(" new: eventSet = eventQueue.remove();"); 471 try { 472 eventSet = eventQueue.remove(waitTime*60000); 473 if (eventSet == null) { 474 log3("ERROR: timeout for waiting for a BreakpintEvent"); 475 returnCode = returnCode3; 476 break labelBP; 477 } 478 } catch ( Exception e ) { 479 log3("ERROR: Exception for eventSet = eventQueue.remove(); : " + e); 480 returnCode = 1; 481 break labelBP; 482 } 483 484 if (eventSet != null) { 485 486 log2(" : eventSet != null; size == " + eventSet.size()); 487 488 EventIterator eIter = eventSet.eventIterator(); 489 Event ev = null; 490 491 for (; eIter.hasNext(); ) { 492 493 if (returnCode != returnCode0) 494 break; 495 496 ev = eIter.nextEvent(); 497 498 ll: for (int ifor =0; ; ifor++) { 499 500 try { 501 switch (ifor) { 502 503 case 0: AccessWatchpointEvent awe = (AccessWatchpointEvent) ev; 504 log2(" AccessWatchpointEvent removed"); 505 break ll; 506 case 1: BreakpointEvent be = (BreakpointEvent) ev; 507 log2(" BreakpointEvent removed"); 508 break labelBP; 509 case 2: ClassPrepareEvent cpe = (ClassPrepareEvent) ev; 510 log2(" ClassPreparEvent removed"); 511 break ll; 512 case 3: ClassUnloadEvent cue = (ClassUnloadEvent) ev; 513 log2(" ClassUnloadEvent removed"); 514 break ll; 515 case 4: ExceptionEvent ee = (ExceptionEvent) ev; 516 log2(" ExceptionEvent removed"); 517 break ll; 518 case 5: MethodEntryEvent mene = (MethodEntryEvent) ev; 519 log2(" MethodEntryEvent removed"); 520 break ll; 521 case 6: MethodExitEvent mexe = (MethodExitEvent) ev; 522 log2(" MethodExiEvent removed"); 523 break ll; 524 case 7: ModificationWatchpointEvent mwe = (ModificationWatchpointEvent) ev; 525 log2(" ModificationWatchpointEvent removed"); 526 break ll; 527 case 8: StepEvent se = (StepEvent) ev; 528 log2(" StepEvent removed"); 529 break ll; 530 case 9: ThreadDeathEvent tde = (ThreadDeathEvent) ev; 531 log2(" ThreadDeathEvent removed"); 532 break ll; 533 case 10: ThreadStartEvent tse = (ThreadStartEvent) ev; 534 log2(" ThreadStartEvent removed"); 535 break ll; 536 case 11: VMDeathEvent vmde = (VMDeathEvent) ev; 537 log2(" VMDeathEvent removed"); 538 break ll; 539 case 12: VMStartEvent vmse = (VMStartEvent) ev; 540 log2(" VMStartEvent removed"); 541 break ll; 542 case 13: WatchpointEvent we = (WatchpointEvent) ev; 543 log2(" WatchpointEvent removed"); 544 break ll; 545 546 default: log3("ERROR: default case for casting event"); 547 returnCode = returnCode3; 548 break ll; 549 } // switch 550 } catch ( ClassCastException e ) { 551 } // try 552 } // ll: for (int ifor =0; ; ifor++) 553 } // for (; ev.hasNext(); ) 554 } 555 } 556 if (returnCode == returnCode0) 557 log2(" : eventSet == null: EventQueue is empty"); 558 559 return returnCode; 560 } 561 } 562