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