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