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.ThreadReference.isSuspended; 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 * ThreadReference. <BR> 40 * <BR> 41 * The test checks up that results of the method <BR> 42 * <code>com.sun.jdi.ThreadReference.isSuspended()</code> <BR> 43 * complies with its spec. <BR> 44 * The test checks up the following case: <BR> 45 * - a debuggee with two threads is suspended with VirtualMachine.suspend(); <BR> 46 * - then one thread is resumed with ThreadReference.resume(). <BR> 47 * <BR> 48 * After being started up, the debuggee : <BR> 49 * - creates a 'lockingObject'for synchronizing threads; <BR> 50 * - enters into the synchronized block <BR> 51 * in which it creates new thread, thread2; <BR> 52 * - informs a debugger of the thread creation, and is waiting for reply.<BR> 53 * Since the thread2 uses the same lockingObject in its 'run' method <BR> 54 * it is locked up until the main thread leaves the synchronized block. <BR> 55 * Upon the receiption a message from the debuggee, the debugger <BR> 56 * - sets up a breakpoint for the thread2; <BR> 57 * - suspends the thread2 with ThreadReference.suspend(); <BR> 58 * - instructs the main thread to leave the synchronized block, <BR> 59 * after what the thread is waiting for <BR> 60 * new instruction from the debugger again; <BR> 61 * - totally suspends the debuggee with VirtualMahcine.suspend(); <BR> 62 * - resumes only the thread2 with double ThreadReference.resume() <BR> 63 * that results in thread2's suspendCount == 0; <BR> 64 * - checks up that the thread2 is suspended at the breakpoint; <BR> 65 * - resumes the debuggee with VirtualMachine.resume(). <BR> 66 * <BR> 67 */ 68 69 public class issuspended002 { 70 71 //----------------------------------------------------- templete section 72 static final int PASSED = 0; 73 static final int FAILED = 2; 74 static final int PASS_BASE = 95; 75 76 //----------------------------------------------------- templete parameters 77 static final String 78 sHeader1 = "\n==> nsk/jdi/ThreadReference/isSuspended/issuspended002 ", 79 sHeader2 = "--> debugger: ", 80 sHeader3 = "##> debugger: "; 81 82 //----------------------------------------------------- main method 83 main(String argv[])84 public static void main (String argv[]) { 85 int result = run(argv, System.out); 86 System.exit(result + PASS_BASE); 87 } 88 run(String argv[], PrintStream out)89 public static int run (String argv[], PrintStream out) { 90 return new issuspended002().runThis(argv, out); 91 } 92 93 //-------------------------------------------------- log procedures 94 95 private static Log logHandler; 96 log1(String message)97 private static void log1(String message) { 98 logHandler.display(sHeader1 + message); 99 } log2(String message)100 private static void log2(String message) { 101 logHandler.display(sHeader2 + message); 102 } log3(String message)103 private static void log3(String message) { 104 logHandler.complain(sHeader3 + message); 105 } 106 107 // ************************************************ test parameters 108 109 private String debuggeeName = 110 "nsk.jdi.ThreadReference.isSuspended.issuspended002a"; 111 112 private String testedClassName = 113 "nsk.jdi.ThreadReference.isSuspended.Threadissuspended002a"; 114 115 //String mName = "nsk.jdi.ThreadReference.isSuspended"; 116 117 //====================================================== test program 118 //------------------------------------------------------ common section 119 static ArgumentHandler argsHandler; 120 121 static int waitTime; 122 123 static VirtualMachine vm = null; 124 static EventRequestManager eventRManager = null; 125 static EventQueue eventQueue = null; 126 static EventSet eventSet = null; 127 128 ReferenceType testedclass = null; 129 ThreadReference thread2 = null; 130 ThreadReference mainThread = null; 131 132 static int testExitCode = PASSED; 133 134 static final int returnCode0 = 0; 135 static final int returnCode1 = 1; 136 static final int returnCode2 = 2; 137 static final int returnCode3 = 3; 138 static final int returnCode4 = 4; 139 140 //------------------------------------------------------ methods 141 runThis(String argv[], PrintStream out)142 private int runThis (String argv[], PrintStream out) { 143 144 Debugee debuggee; 145 146 argsHandler = new ArgumentHandler(argv); 147 logHandler = new Log(out, argsHandler); 148 Binder binder = new Binder(argsHandler, logHandler); 149 150 if (argsHandler.verbose()) { 151 debuggee = binder.bindToDebugee(debuggeeName + " -vbs"); 152 } else { 153 debuggee = binder.bindToDebugee(debuggeeName); 154 } 155 156 waitTime = argsHandler.getWaitTime(); 157 158 159 IOPipe pipe = new IOPipe(debuggee); 160 161 debuggee.redirectStderr(out); 162 log2(debuggeeName + " debuggee launched"); 163 debuggee.resume(); 164 165 String line = pipe.readln(); 166 if ((line == null) || !line.equals("ready")) { 167 log3("signal received is not 'ready' but: " + line); 168 return FAILED; 169 } else { 170 log2("'ready' recieved"); 171 } 172 173 vm = debuggee.VM(); 174 175 //------------------------------------------------------ testing section 176 log1(" TESTING BEGINS"); 177 178 for (int i = 0; ; i++) { 179 180 pipe.println("newcheck"); 181 line = pipe.readln(); 182 183 if (line.equals("checkend")) { 184 log2(" : returned string is 'checkend'"); 185 break ; 186 } else if (!line.equals("checkready")) { 187 log3("ERROR: returned string is not 'checkready'"); 188 testExitCode = FAILED; 189 break ; 190 } 191 192 log1("new checkready: #" + i); 193 194 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ variable part 195 196 int expresult = returnCode0; 197 198 199 eventRManager = vm.eventRequestManager(); 200 eventQueue = vm.eventQueue(); 201 202 String threadName = "testedThread"; 203 204 String breakpointMethod1 = "runt1"; 205 //String breakpointMethod2 = "runt2"; 206 207 String bpLine1 = "breakpointLineNumber1"; 208 //String bpLine2 = "breakpointLineNumber2"; 209 //String bpLine3 = "breakpointLineNumber3"; 210 211 212 List allThreads = null; 213 ListIterator listIterator = null; 214 List classes = null; 215 216 BreakpointRequest breakpRequest1 = null; 217 //BreakpointRequest breakpRequest2 = null; 218 //BreakpointRequest breakpRequest3 = null; 219 220 int suspCount = 0; 221 int frameCount; 222 223 224 label0: { 225 226 log2("getting ThreadReference objects and setting up breakponts"); 227 try { 228 allThreads = vm.allThreads(); 229 classes = vm.classesByName(testedClassName); 230 testedclass = (ReferenceType) classes.get(0); 231 } catch ( Exception e) { 232 log3("ERROR: Exception at very beginning !? : " + e); 233 expresult = returnCode1; 234 break label0; 235 } 236 237 listIterator = allThreads.listIterator(); 238 for (;;) { 239 try { 240 thread2 = (ThreadReference) listIterator.next(); 241 if (thread2.name().equals(threadName)) 242 break ; 243 } catch ( NoSuchElementException e ) { 244 log3("ERROR: NoSuchElementException for listIterator.next()"); 245 log3("ERROR: NO THREAD2 ?????????!!!!!!!"); 246 expresult = returnCode1; 247 break label0; 248 } 249 } 250 251 log2("getting ThreadReference objects for main thread"); 252 listIterator = allThreads.listIterator(); 253 for (;;) { 254 try { 255 mainThread = (ThreadReference) listIterator.next(); 256 if (mainThread.name().equals("main")) 257 break ; 258 } catch ( NoSuchElementException e ) { 259 log3("ERROR: NoSuchElementException for listIterator.next() for 'mainThread'"); 260 log3("ERROR: NO MAIN THREAD ?????????!!!!!!!"); 261 expresult = returnCode1; 262 break label0; 263 } 264 } 265 266 log2("setting up breakpoints"); 267 268 breakpRequest1 = settingBreakpoint(breakpointMethod1, bpLine1, "one"); 269 if (breakpRequest1 == null) { 270 expresult = returnCode1; 271 break label0; 272 } 273 } 274 275 label1: { 276 if (expresult != returnCode0) 277 break label1; 278 279 log2(" checking up before to begin testing the thread2"); 280 log2(" thread2.suspendCount() == " + thread2.suspendCount()); 281 if (!thread2.isSuspended()) { 282 log2(" : !thread2.isSuspended()"); 283 } else { 284 log3("ERROR: thread2.isSuspended()"); 285 expresult = returnCode1; 286 } 287 log2(" mainThread.suspendCount() == " + mainThread.suspendCount()); 288 if (!mainThread.isSuspended()) { 289 log2(" : !mainThread.isSuspended()"); 290 } else { 291 log3("ERROR: mainThread.isSuspended()"); 292 expresult = returnCode1; 293 } 294 295 296 log2(" suspending thread2 with thread2.suspend();"); 297 thread2.suspend(); 298 299 log2(" thread2.suspendCount() == " + thread2.suspendCount()); 300 if (thread2.isSuspended()) { 301 log2(" : thread2.isSuspended()"); 302 } else { 303 log3("ERROR: !thread2.isSuspended()"); 304 expresult = returnCode1; 305 } 306 log2(" mainThread.suspendCount() == " + mainThread.suspendCount()); 307 if (!mainThread.isSuspended()) { 308 log2(" : !mainThread.isSuspended()"); 309 } else { 310 log3("ERROR: mainThread.isSuspended() ????????!!!"); 311 expresult = returnCode1; 312 } 313 314 log2(" forcing the main thread to leave synchronized block"); 315 pipe.println("continue"); 316 line = pipe.readln(); 317 if (!line.equals("docontinue")) { 318 log3("ERROR: returned string is not 'docontinue'"); 319 expresult = returnCode4; 320 } 321 322 if (expresult != returnCode0) 323 break label1; 324 325 326 log2(" suspending VM with vm.suspend();"); 327 vm.suspend(); 328 329 suspCount = thread2.suspendCount(); 330 if (suspCount != 2) { 331 log3("ERROR: thread2.suspendCount() != 2 : " + suspCount); 332 expresult = returnCode1; 333 } else { 334 log2(" thread2.suspendCount() == 2"); 335 } 336 if (thread2.isSuspended()) { 337 log2(" : thread2.isSuspended()"); 338 } else { 339 log3("ERROR: !thread2.isSuspended()"); 340 expresult = returnCode1; 341 } 342 suspCount = mainThread.suspendCount(); 343 if (suspCount != 1) { 344 log3("ERROR: mainThread.suspendCount() != 1 : " + suspCount); 345 expresult = returnCode1; 346 } else { 347 log2(" mainThread.suspendCount() == 1"); 348 } 349 if (mainThread.isSuspended()) { 350 log2(" : mainThread.isSuspended()"); 351 } else { 352 log3("ERROR: !mainThread.isSuspended()"); 353 expresult = returnCode1; 354 } 355 356 357 log2(" double resuming thread2 with thread2.resume();"); 358 359 thread2.resume(); 360 361 suspCount = thread2.suspendCount(); 362 log2(" thread2.suspendCount() == " + suspCount); 363 if (thread2.isSuspended()) { 364 log2(" : thread2.isSuspended()"); 365 } else { 366 log3("ERROR: !thread2.isSuspended()"); 367 expresult = returnCode1; 368 } 369 370 if (expresult == returnCode0) { 371 log2(" enabling breakpRequest1"); 372 breakpRequest1.enable(); 373 } 374 375 thread2.resume(); 376 377 suspCount = thread2.suspendCount(); 378 log2(" thread2.suspendCount() == " + suspCount); 379 if ( thread2.isAtBreakpoint() ) { 380 log2(" : thread2.isAtBreakpoint() before call to breakpoint()"); 381 } else { 382 log2(" : !thread2.isAtBreakpoint() before call to breakpoint()"); 383 } 384 } 385 386 label2: { 387 388 if (expresult == returnCode0) 389 expresult = breakpoint(); 390 if (expresult != returnCode0) 391 break label2; 392 393 log2(" the thread2 is at the breakpoint"); 394 395 log2(" the check that the thread2 is suspended at the breakpoint"); 396 log2(" thread2.suspendCount() == " + thread2.suspendCount()); 397 if ( thread2.isAtBreakpoint() ) { 398 log2(" : thread2.isAtBreakpoint()"); 399 } else { 400 log3("ERROR: !thread2.isAtBreakpoint()"); 401 expresult = returnCode1; 402 } 403 if ( thread2.isSuspended() ) { 404 log2(" : thread2.isSuspended()"); 405 } else { 406 log3("ERROR: !thread2.isSuspended()"); 407 expresult = returnCode1; 408 } 409 if (mainThread.isSuspended()) { 410 log2(" : mainThread.isSuspended()"); 411 } else { 412 log3("ERROR: !mainThread.isSuspended()"); 413 expresult = returnCode1; 414 } 415 } 416 417 log2(" resuming both second and main thread"); 418 419 vm.resume(); 420 421 if (expresult == returnCode0) { 422 if ( !thread2.isSuspended() ) { 423 log2(" : !thread2.isSuspended()"); 424 } else { 425 log3("ERROR: thread2.isSuspended()"); 426 expresult = returnCode1; 427 } 428 if ( !mainThread.isSuspended() ) { 429 log2(" : !mainThread.isSuspended()"); 430 } else { 431 log3("ERROR: mainThread.isSuspended()"); 432 expresult = returnCode2; 433 } 434 } 435 436 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 437 log2(" the end of testing"); 438 if (expresult != returnCode0) 439 testExitCode = FAILED; 440 } 441 log1(" TESTING ENDS"); 442 443 //-------------------------------------------------- test summary section 444 //------------------------------------------------- standard end section 445 446 pipe.println("quit"); 447 log2("waiting for the debuggee to finish ..."); 448 debuggee.waitFor(); 449 450 int status = debuggee.getStatus(); 451 if (status != PASSED + PASS_BASE) { 452 log3("debuggee returned UNEXPECTED exit status: " + 453 status + " != PASS_BASE"); 454 testExitCode = FAILED; 455 } else { 456 log2("debuggee returned expected exit status: " + 457 status + " == PASS_BASE"); 458 } 459 460 if (testExitCode != PASSED) { 461 logHandler.complain("TEST FAILED"); 462 } 463 return testExitCode; 464 } 465 466 467 468 /* 469 * private BreakpointRequest settingBreakpoint(String, String, String) 470 * 471 * It sets up a breakpoint within a given method at given line number 472 * for the thread2 only. 473 * Third parameter is required for any case in future debugging, as if. 474 * 475 * Return codes: 476 * = BreakpointRequest object in case of success 477 * = null in case of an Exception thrown within the method 478 */ 479 settingBreakpoint( String methodName, String bpLine, String property)480 private BreakpointRequest settingBreakpoint ( String methodName, 481 String bpLine, 482 String property) { 483 484 log2("setting up a breakpoint: method: '" + methodName + "' line: " + bpLine ); 485 486 List alllineLocations = null; 487 Location lineLocation = null; 488 BreakpointRequest breakpRequest = null; 489 490 try { 491 Method method = (Method) testedclass.methodsByName(methodName).get(0); 492 493 alllineLocations = method.allLineLocations(); 494 495 int n = 496 ( (IntegerValue) testedclass.getValue(testedclass.fieldByName(bpLine) ) ).value(); 497 if (n > alllineLocations.size()) { 498 log3("ERROR: TEST_ERROR_IN_settingBreakpoint(): number is out of bound of method's lines"); 499 } else { 500 lineLocation = (Location) alllineLocations.get(n); 501 try { 502 breakpRequest = eventRManager.createBreakpointRequest(lineLocation); 503 breakpRequest.putProperty("number", property); 504 breakpRequest.addThreadFilter(thread2); 505 breakpRequest.setSuspendPolicy( EventRequest.SUSPEND_EVENT_THREAD); 506 } catch ( Exception e1 ) { 507 log3("ERROR: inner Exception within settingBreakpoint() : " + e1); 508 breakpRequest = null; 509 } 510 } 511 } catch ( Exception e2 ) { 512 log3("ERROR: ATTENTION: outer Exception within settingBreakpoint() : " + e2); 513 breakpRequest = null; 514 } 515 516 if (breakpRequest == null) 517 log2(" A BREAKPOINT HAS NOT BEEN SET UP"); 518 else 519 log2(" a breakpoint has been set up"); 520 521 return breakpRequest; 522 } 523 524 525 /* 526 * private int breakpoint () 527 * 528 * It removes events from EventQueue until gets first BreakpointEvent. 529 * To get next EventSet value, it uses the method 530 * EventQueue.remove(int timeout) 531 * The timeout argument passed to the method, is "waitTime*60000". 532 * Note: the value of waitTime is set up with 533 * the method ArgumentHandler.getWaitTime() at the beginning of the test. 534 * 535 * Return codes: 536 * = returnCode0 - success; 537 * = returnCode2 - Exception when "eventSet = eventQueue.remove()" is executed 538 * = returnCode3 - default case when loop of processing an event, that is, 539 * an unspecified event was taken from the EventQueue 540 */ 541 breakpoint()542 private int breakpoint () { 543 544 int returnCode = returnCode0; 545 546 log2(" waiting for BreakpointEvent"); 547 548 labelBP: 549 for (;;) { 550 551 log2(" new: eventSet = eventQueue.remove();"); 552 try { 553 eventSet = eventQueue.remove(waitTime*60000); 554 if (eventSet == null) { 555 log3("ERROR: timeout for waiting for a BreakpintEvent"); 556 returnCode = returnCode3; 557 break labelBP; 558 } 559 } catch ( Exception e ) { 560 log3("ERROR: Exception for eventSet = eventQueue.remove(); : " + e); 561 returnCode = 1; 562 break labelBP; 563 } 564 565 if (eventSet != null) { 566 567 log2(" : eventSet != null; size == " + eventSet.size()); 568 569 EventIterator eIter = eventSet.eventIterator(); 570 Event ev = null; 571 572 for (; eIter.hasNext(); ) { 573 574 if (returnCode != returnCode0) 575 break; 576 577 ev = eIter.nextEvent(); 578 579 ll: for (int ifor =0; ; ifor++) { 580 581 try { 582 switch (ifor) { 583 584 case 0: AccessWatchpointEvent awe = (AccessWatchpointEvent) ev; 585 log2(" AccessWatchpointEvent removed"); 586 break ll; 587 case 1: BreakpointEvent be = (BreakpointEvent) ev; 588 log2(" BreakpointEvent removed"); 589 break labelBP; 590 case 2: ClassPrepareEvent cpe = (ClassPrepareEvent) ev; 591 log2(" ClassPreparEvent removed"); 592 break ll; 593 case 3: ClassUnloadEvent cue = (ClassUnloadEvent) ev; 594 log2(" ClassUnloadEvent removed"); 595 break ll; 596 case 4: ExceptionEvent ee = (ExceptionEvent) ev; 597 log2(" ExceptionEvent removed"); 598 break ll; 599 case 5: MethodEntryEvent mene = (MethodEntryEvent) ev; 600 log2(" MethodEntryEvent removed"); 601 break ll; 602 case 6: MethodExitEvent mexe = (MethodExitEvent) ev; 603 log2(" MethodExiEvent removed"); 604 break ll; 605 case 7: ModificationWatchpointEvent mwe = (ModificationWatchpointEvent) ev; 606 log2(" ModificationWatchpointEvent removed"); 607 break ll; 608 case 8: StepEvent se = (StepEvent) ev; 609 log2(" StepEvent removed"); 610 break ll; 611 case 9: ThreadDeathEvent tde = (ThreadDeathEvent) ev; 612 log2(" ThreadDeathEvent removed"); 613 break ll; 614 case 10: ThreadStartEvent tse = (ThreadStartEvent) ev; 615 log2(" ThreadStartEvent removed"); 616 break ll; 617 case 11: VMDeathEvent vmde = (VMDeathEvent) ev; 618 log2(" VMDeathEvent removed"); 619 break ll; 620 case 12: VMStartEvent vmse = (VMStartEvent) ev; 621 log2(" VMStartEvent removed"); 622 break ll; 623 case 13: WatchpointEvent we = (WatchpointEvent) ev; 624 log2(" WatchpointEvent removed"); 625 break ll; 626 627 default: log3("ERROR: default case for casting event"); 628 returnCode = returnCode3; 629 break ll; 630 } // switch 631 } catch ( ClassCastException e ) { 632 } // try 633 } // ll: for (int ifor =0; ; ifor++) 634 } // for (; ev.hasNext(); ) 635 } 636 } 637 if (returnCode == returnCode0) 638 log2(" : eventSet == null: EventQueue is empty"); 639 640 return returnCode; 641 } 642 643 } 644