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.jdwp.Event.VM_DEATH; 25 26 import java.io.*; 27 28 import nsk.share.*; 29 import nsk.share.jpda.*; 30 import nsk.share.jdwp.*; 31 32 /** 33 * Test for JDWP event: VM_DEATH. 34 * 35 * See vmdeath002.README for description of test execution. 36 * 37 * This class represents debugger part of the test. 38 * Test is executed by invoking method runIt(). 39 * JDWP event is tested in the method waitForTestedEvent(). 40 * 41 * @see #runIt() 42 * @see #waitForTestedEvent() 43 */ 44 public class vmdeath002 { 45 46 // exit status constants 47 static final int JCK_STATUS_BASE = 95; 48 static final int PASSED = 0; 49 static final int FAILED = 2; 50 51 // VM capability constants 52 static final int VM_CAPABILITY_NUMBER = JDWP.Capability.CAN_REQUEST_VMDEATH_EVENT; 53 static final String VM_CAPABILITY_NAME = "canRequestVMDeathEvent"; 54 55 // package and classes names constants 56 static final String PACKAGE_NAME = "nsk.jdwp.Event.VM_DEATH"; 57 static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "vmdeath002"; 58 static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a"; 59 60 // tested JDWP event constants 61 static final byte TESTED_EVENT_KIND = JDWP.EventKind.VM_DEATH; 62 static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL; 63 64 // usual scaffold objects 65 ArgumentHandler argumentHandler = null; 66 Log log = null; 67 Binder binder = null; 68 Debugee debugee = null; 69 Transport transport = null; 70 int waitTime = 0; // minutes 71 long timeout = 0; // milliseconds 72 boolean dead = false; 73 boolean resumed = false; 74 boolean success = true; 75 76 // obtained data 77 int eventRequestID = 0; 78 79 // ------------------------------------------------------------------- 80 81 /** 82 * Start test from command line. 83 */ main(String argv[])84 public static void main(String argv[]) { 85 System.exit(run(argv,System.out) + JCK_STATUS_BASE); 86 } 87 88 /** 89 * Start test from JCK-compilant environment. 90 */ run(String argv[], PrintStream out)91 public static int run(String argv[], PrintStream out) { 92 return new vmdeath002().runIt(argv, out); 93 } 94 95 // ------------------------------------------------------------------- 96 97 /** 98 * Perform test execution. 99 */ runIt(String argv[], PrintStream out)100 public int runIt(String argv[], PrintStream out) { 101 102 // make log for debugger messages 103 argumentHandler = new ArgumentHandler(argv); 104 log = new Log(out, argumentHandler); 105 waitTime = argumentHandler.getWaitTime(); 106 timeout = waitTime * 60 * 1000; 107 108 // execute test and display results 109 try { 110 log.display("\n>>> Starting debugee \n"); 111 112 // launch debuggee 113 binder = new Binder(argumentHandler, log); 114 log.display("Launching debugee"); 115 debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME); 116 transport = debugee.getTransport(); 117 log.display(" ... debugee launched"); 118 log.display(""); 119 120 // set timeout for debuggee responces 121 log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)"); 122 transport.setReadTimeout(timeout); 123 log.display(" ... timeout set"); 124 125 // wait for debuggee started 126 log.display("Waiting for VM_INIT event"); 127 debugee.waitForVMInit(); 128 log.display(" ... VM_INIT event received"); 129 130 // query debugee for VM-dependent ID sizes 131 log.display("Querying for IDSizes"); 132 debugee.queryForIDSizes(); 133 log.display(" ... size of VM-dependent types adjusted"); 134 135 // check for VM capability 136 log.display("\n>>> Checking VM capability \n"); 137 log.display("Getting VM capability: " + VM_CAPABILITY_NAME); 138 boolean capable = debugee.getNewCapability(VM_CAPABILITY_NUMBER, VM_CAPABILITY_NAME); 139 log.display(" ... got VM capability: " + capable); 140 141 // exit as PASSED if this capability is not supported 142 if (!capable) { 143 out.println("TEST PASSED: unsupported VM capability: " 144 + VM_CAPABILITY_NAME); 145 return PASSED; 146 } 147 148 // test JDWP event 149 log.display("\n>>> Testing JDWP event \n"); 150 log.display("Making request for METHOD_DEATH event"); 151 requestTestedEvent(); 152 log.display(" ... got requestID: " + eventRequestID); 153 log.display(""); 154 155 // resume debuggee 156 log.display("Resumindg debuggee"); 157 debugee.resume(); 158 log.display(" ... debuggee resumed"); 159 log.display(""); 160 161 // wait for tested VM_DEATH event 162 log.display("Waiting for VM_DEATH event received"); 163 waitForTestedEvent(); 164 log.display(" ... event received"); 165 log.display(""); 166 167 if (!dead) { 168 // clear tested request for VM_DEATH event 169 log.display("\n>>> Clearing request for tested event \n"); 170 clearTestedRequest(); 171 172 // finish debuggee after testing 173 log.display("\n>>> Finishing debuggee \n"); 174 175 // resume debuggee 176 log.display("Resuming debuggee"); 177 debugee.resume(); 178 log.display(" ... debuggee resumed"); 179 180 // wait for debuggee exited 181 log.display("Waiting for VM_DEATH event"); 182 debugee.waitForVMDeath(); 183 dead = true; 184 log.display(" ... VM_DEATH event received"); 185 } else if (!resumed) { 186 // resume debuggee 187 log.display("Resuming debuggee"); 188 debugee.resume(); 189 log.display(" ... debuggee resumed"); 190 } 191 192 } catch (Failure e) { 193 log.complain("TEST FAILED: " + e.getMessage()); 194 success = false; 195 } catch (Exception e) { 196 e.printStackTrace(out); 197 log.complain("Caught unexpected exception while running the test:\n\t" + e); 198 success = false; 199 } finally { 200 // quit debugee 201 log.display("\n>>> Finishing test \n"); 202 quitDebugee(); 203 } 204 205 // check test results 206 if (!success) { 207 log.complain("TEST FAILED"); 208 return FAILED; 209 } 210 211 out.println("TEST PASSED"); 212 return PASSED; 213 214 } 215 216 /** 217 * Make request for tested METHOD_ENTRY event. 218 */ requestTestedEvent()219 void requestTestedEvent() { 220 Failure failure = new Failure("Error occured while makind request for tested event"); 221 222 // create command packet and fill requred out data 223 log.display("Create command packet: " + "EventRequest.Set"); 224 CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set); 225 log.display(" eventKind: " + TESTED_EVENT_KIND); 226 command.addByte(TESTED_EVENT_KIND); 227 log.display(" eventPolicy: " + TESTED_EVENT_SUSPEND_POLICY); 228 command.addByte(TESTED_EVENT_SUSPEND_POLICY); 229 log.display(" modifiers: " + 0); 230 command.addInt(0); 231 command.setLength(); 232 log.display(" ... command packet composed"); 233 log.display(""); 234 235 // send command packet to debugee 236 try { 237 log.display("Sending command packet:\n" + command); 238 transport.write(command); 239 log.display(" ... command packet sent"); 240 } catch (IOException e) { 241 log.complain("Unable to send command packet:\n\t" + e); 242 success = false; 243 throw failure; 244 } 245 log.display(""); 246 247 ReplyPacket reply = new ReplyPacket(); 248 249 // receive reply packet from debugee 250 try { 251 log.display("Waiting for reply packet"); 252 transport.read(reply); 253 log.display(" ... packet received:\n" + reply); 254 } catch (IOException e) { 255 log.complain("Unable to read reply packet:\n\t" + e); 256 success = false; 257 throw failure; 258 } 259 log.display(""); 260 261 // check reply packet header 262 try{ 263 log.display("Checking header of reply packet"); 264 reply.checkHeader(command.getPacketID()); 265 log.display(" .. packet header is correct"); 266 } catch (BoundException e) { 267 log.complain("Bad header of reply packet:\n\t" + e.getMessage()); 268 success = false; 269 throw failure; 270 } 271 272 // start parsing reply packet data 273 log.display("Parsing reply packet:"); 274 reply.resetPosition(); 275 276 // extract requestID 277 int requestID = 0; 278 try { 279 requestID = reply.getInt(); 280 log.display(" requestID: " + requestID); 281 } catch (BoundException e) { 282 log.complain("Unable to extract requestID from request reply packet:\n\t" 283 + e.getMessage()); 284 success = false; 285 throw failure; 286 } 287 288 // check requestID 289 if (requestID == 0) { 290 log.complain("Unexpected null requestID returned: " + requestID); 291 success = false; 292 throw failure; 293 } 294 295 eventRequestID = requestID; 296 297 // check for extra data in reply packet 298 if (!reply.isParsed()) { 299 log.complain("Extra trailing bytes found in request reply packet at: " 300 + reply.offsetString()); 301 success = false; 302 } 303 304 log.display(" ... reply packet parsed"); 305 306 } 307 308 /** 309 * Clear request for tested METHOD_ENTRY event. 310 */ clearTestedRequest()311 void clearTestedRequest() { 312 Failure failure = new Failure("Error occured while clearing request for tested event"); 313 314 // create command packet and fill requred out data 315 log.display("Create command packet: " + "EventRequest.Clear"); 316 CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear); 317 log.display(" event: " + TESTED_EVENT_KIND); 318 command.addByte(TESTED_EVENT_KIND); 319 log.display(" requestID: " + eventRequestID); 320 command.addInt(eventRequestID); 321 log.display(" ... command packet composed"); 322 log.display(""); 323 324 // send command packet to debugee 325 try { 326 log.display("Sending command packet:\n" + command); 327 transport.write(command); 328 log.display(" ... command packet sent"); 329 } catch (IOException e) { 330 log.complain("Unable to send command packet:\n\t" + e); 331 success = false; 332 throw failure; 333 } 334 log.display(""); 335 336 ReplyPacket reply = new ReplyPacket(); 337 338 // receive reply packet from debugee 339 try { 340 log.display("Waiting for reply packet"); 341 transport.read(reply); 342 log.display(" ... packet received:\n" + reply); 343 } catch (IOException e) { 344 log.complain("Unable to read reply packet:\n\t" + e); 345 success = false; 346 throw failure; 347 } 348 349 // check reply packet header 350 try{ 351 log.display("Checking header of reply packet"); 352 reply.checkHeader(command.getPacketID()); 353 log.display(" .. packet header is correct"); 354 } catch (BoundException e) { 355 log.complain("Bad header of reply packet:\n\t" + e.getMessage()); 356 success = false; 357 throw failure; 358 } 359 360 // start parsing reply packet data 361 log.display("Parsing reply packet:"); 362 reply.resetPosition(); 363 364 log.display(" no data"); 365 366 // check for extra data in reply packet 367 if (!reply.isParsed()) { 368 log.complain("Extra trailing bytes found in request reply packet at: " 369 + reply.offsetString()); 370 success = false; 371 } 372 373 log.display(" ... reply packet parsed"); 374 } 375 376 /** 377 * Wait for tested VM_DEATH event. 378 */ waitForTestedEvent()379 void waitForTestedEvent() { 380 381 EventPacket eventPacket = null; 382 383 // receive reply packet from debugee 384 try { 385 log.display("Waiting for event packet"); 386 eventPacket = debugee.getEventPacket(timeout); 387 log.display(" ... event packet received:\n" + eventPacket); 388 } catch (IOException e) { 389 log.complain("Unable to read tested event packet:\n\t" + e); 390 success = false; 391 return; 392 } 393 394 // check reply packet header 395 try{ 396 log.display("Checking header of event packet"); 397 eventPacket.checkHeader(); 398 log.display(" ... packet header is OK"); 399 } catch (BoundException e) { 400 log.complain("Bad header of tested event packet:\n\t" 401 + e.getMessage()); 402 success = false; 403 return; 404 } 405 406 // start parsing reply packet data 407 log.display("Parsing event packet:"); 408 eventPacket.resetPosition(); 409 410 // get suspendPolicy value 411 byte suspendPolicy = 0; 412 try { 413 suspendPolicy = eventPacket.getByte(); 414 log.display(" suspendPolicy: " + suspendPolicy); 415 } catch (BoundException e) { 416 log.complain("Unable to get suspendPolicy value from tested event packet:\n\t" 417 + e.getMessage()); 418 success = false; 419 return; 420 } 421 422 // check suspendPolicy value 423 if (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY) { 424 log.complain("Unexpected SuspendPolicy in tested event packet: " + 425 suspendPolicy + " (expected: " + TESTED_EVENT_SUSPEND_POLICY + ")"); 426 success = false; 427 } 428 429 // get events count 430 int events = 0; 431 try { 432 events = eventPacket.getInt(); 433 log.display(" events: " + events); 434 } catch (BoundException e) { 435 log.complain("Unable to get events count from tested event packet:\n\t" 436 + e.getMessage()); 437 success = false; 438 return; 439 } 440 441 // check events count 442 if (events < 0) { 443 log.complain("Negative value of events number in tested event packet: " + 444 events + " (expected: " + 1 + ")"); 445 success = false; 446 } 447 448 // extract each event 449 int eventReceived = 0; 450 for (int i = 0; i < events; i++) { 451 log.display(" event #" + i + ":"); 452 453 // get eventKind 454 byte eventKind = 0; 455 try { 456 eventKind = eventPacket.getByte(); 457 log.display(" eventKind: " + eventKind); 458 } catch (BoundException e) { 459 log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t" 460 + e.getMessage()); 461 success = false; 462 return; 463 } 464 465 // check eventKind 466 if (eventKind != TESTED_EVENT_KIND) { 467 log.complain("Unexpected eventKind of event " + i + " in tested event packet: " + 468 eventKind + " (expected: " + TESTED_EVENT_KIND + ")"); 469 success = false; 470 continue; 471 } 472 473 // get requestID 474 int requestID = 0; 475 try { 476 requestID = eventPacket.getInt(); 477 log.display(" requestID: " + requestID); 478 } catch (BoundException e) { 479 log.complain("Unable to get requestID of event #" + i + " from tested event packet:\n\t" 480 + e.getMessage()); 481 success = false; 482 dead = true; 483 resumed = (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY); 484 return; 485 } 486 487 // check requestID 488 if (requestID == eventRequestID) { 489 eventReceived++; 490 } else if (requestID == 0) { 491 dead = true; 492 resumed = (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY); 493 } else { 494 log.complain("Unexpected requestID of event " + i + " in tested event packet: " + 495 requestID + " (expected: " + eventRequestID + " or 0)"); 496 success = false; 497 return; 498 } 499 500 } 501 502 // check for extra data in event packet 503 if (!eventPacket.isParsed()) { 504 int extra = eventPacket.length() - eventPacket.currentPosition(); 505 log.complain("Extra trailing bytes found in event packet at: " 506 + eventPacket.offsetString() + " (" + extra + " bytes)"); 507 success = false; 508 } 509 510 log.display(" ... event packet parsed"); 511 512 if (eventReceived <= 0) { 513 log.complain("No requested event received: " + eventReceived + " (expected: 1)"); 514 success = false; 515 } 516 517 } 518 519 /** 520 * Disconnect debuggee and wait for it exited. 521 */ quitDebugee()522 void quitDebugee() { 523 if (debugee == null) 524 return; 525 526 // disconnect debugee 527 if (!dead) { 528 try { 529 log.display("Disconnecting debuggee"); 530 debugee.dispose(); 531 log.display(" ... debuggee disconnected"); 532 } catch (Failure e) { 533 log.display("Failed to finally disconnect debuggee:\n\t" 534 + e.getMessage()); 535 } 536 } 537 538 // wait for debugee exited 539 log.display("Waiting for debuggee exit"); 540 int code = debugee.waitFor(); 541 log.display(" ... debuggee exited with exit code: " + code); 542 543 // analize debugee exit status code 544 if (code != JCK_STATUS_BASE + PASSED) { 545 log.complain("Debuggee FAILED with exit code: " + code); 546 success = false; 547 } 548 } 549 550 } 551