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