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.EXCEPTION;
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: EXCEPTION.
34  *
35  * See exception001.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 exception001 {
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     // package and classes names constants
52     static final String PACKAGE_NAME = "nsk.jdwp.Event.EXCEPTION";
53     static final String TEST_CLASS_NAME = PACKAGE_NAME + "." + "exception001";
54     static final String DEBUGEE_CLASS_NAME = TEST_CLASS_NAME + "a";
55 
56     // tested JDWP event constants
57     static final byte TESTED_EVENT_KIND = JDWP.EventKind.EXCEPTION;
58     static final byte TESTED_EVENT_SUSPEND_POLICY = JDWP.SuspendPolicy.ALL;
59 
60     // name and signature of the tested class
61     static final String TESTED_CLASS_NAME = DEBUGEE_CLASS_NAME + "$" + "TestedThreadClass";
62     static final String TESTED_CLASS_SIGNATURE = "L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
63     static final String TESTED_THREAD_NAME = "TestedThread";
64 
65     // name of field and method of tested class
66     static final String EXCEPTION_FIELD_NAME = "exception";
67     static final String BREAKPOINT_METHOD_NAME = "run";
68     static final String THROW_METHOD_NAME = "methodForThrow";
69     static final String CATCH_METHOD_NAME = "methodForCatch";
70     static final int BREAKPOINT_LINE = exception001a.BREAKPOINT_LINE;
71     static final int EXCEPTION_THROW_LINE = exception001a.EXCEPTION_THROW_LINE;
72     static final int EXCEPTION_CATCH_LINE = exception001a.EXCEPTION_CATCH_LINE;
73 
74     // usual scaffold objects
75     ArgumentHandler argumentHandler = null;
76     Log log = null;
77     Binder binder = null;
78     Debugee debugee = null;
79     Transport transport = null;
80     int waitTime = 0;  // minutes
81     long timeout = 0;  // milliseconds
82     boolean dead = false;
83     boolean success = true;
84 
85     // obtained data
86     long testedClassID = 0;
87     long testedThreadID = 0;
88     long catchMethodID = 0;
89     long throwMethodID = 0;
90     JDWP.Location throwLocation = null;
91     JDWP.Location catchLocation = null;
92     long exceptionObjectID = 0;
93     int eventRequestID = 0;
94 
95     // -------------------------------------------------------------------
96 
97     /**
98      * Start test from command line.
99      */
main(String argv[])100     public static void main(String argv[]) {
101         System.exit(run(argv,System.out) + JCK_STATUS_BASE);
102     }
103 
104     /**
105      * Start test from JCK-compilant environment.
106      */
run(String argv[], PrintStream out)107     public static int run(String argv[], PrintStream out) {
108         return new exception001().runIt(argv, out);
109     }
110 
111     // -------------------------------------------------------------------
112 
113     /**
114      * Perform test execution.
115      */
runIt(String argv[], PrintStream out)116     public int runIt(String argv[], PrintStream out) {
117 
118         // make log for debugger messages
119         argumentHandler = new ArgumentHandler(argv);
120         log = new Log(out, argumentHandler);
121         waitTime = argumentHandler.getWaitTime();
122         timeout = waitTime * 60 * 1000;
123 
124         // execute test and display results
125         try {
126             log.display("\n>>> Starting debugee \n");
127 
128             // launch debuggee
129             binder = new Binder(argumentHandler, log);
130             log.display("Launching debugee");
131             debugee = binder.bindToDebugee(DEBUGEE_CLASS_NAME);
132             transport = debugee.getTransport();
133             log.display("  ... debugee launched");
134             log.display("");
135 
136             // set timeout for debuggee responces
137             log.display("Setting timeout for debuggee responces: " + waitTime + " minute(s)");
138             transport.setReadTimeout(timeout);
139             log.display("  ... timeout set");
140 
141             // wait for debuggee started
142             log.display("Waiting for VM_INIT event");
143             debugee.waitForVMInit();
144             log.display("  ... VM_INIT event received");
145 
146             // query debugee for VM-dependent ID sizes
147             log.display("Querying for IDSizes");
148             debugee.queryForIDSizes();
149             log.display("  ... size of VM-dependent types adjusted");
150 
151             // prepare debuggee
152             log.display("\n>>> Getting prepared for testing \n");
153             prepareForTest();
154 
155             // test JDWP event
156             log.display("\n>>> Testing JDWP event \n");
157             log.display("Making request for EXCEPTION event for class:\n\t"
158                     + TESTED_CLASS_NAME);
159             requestTestedEvent();
160             log.display("  ... got requestID: " + eventRequestID);
161             log.display("");
162 
163             // resume debuggee
164             log.display("Resumindg debuggee");
165             debugee.resume();
166             log.display("  ... debuggee resumed");
167             log.display("");
168 
169             // wait for tested EXCEPTION event
170             log.display("Waiting for EXCEPTION event received");
171             waitForTestedEvent();
172             log.display("  ... event received");
173             log.display("");
174 
175             // clear tested request for EXCEPTION event
176             log.display("Clearing request for tested event");
177             clearTestedRequest();
178             log.display("  ... request removed");
179 
180             // finish debuggee after testing
181             log.display("\n>>> Finishing debuggee \n");
182 
183             // resume debuggee
184             log.display("Resuming debuggee");
185             debugee.resume();
186             log.display("  ... debuggee resumed");
187 
188             // wait for debuggee exited
189             log.display("Waiting for VM_DEATH event");
190             debugee.waitForVMDeath();
191             dead = true;
192             log.display("  ... VM_DEATH event received");
193 
194         } catch (Failure e) {
195             log.complain("TEST FAILED: " + e.getMessage());
196             success = false;
197         } catch (Exception e) {
198             e.printStackTrace(out);
199             log.complain("Caught unexpected exception while running the test:\n\t" + e);
200             success = false;
201         } finally {
202             // quit debugee
203             log.display("\n>>> Finishing test \n");
204             quitDebugee();
205         }
206 
207         // check test results
208         if (!success) {
209             log.complain("TEST FAILED");
210             return FAILED;
211         }
212 
213         out.println("TEST PASSED");
214         return PASSED;
215 
216     }
217 
218     /**
219      * Get debuggee prepared for testing and obtain required data.
220      */
prepareForTest()221     void prepareForTest() {
222         // wait for tested class loaded
223         log.display("Waiting for tested class loaded");
224         testedClassID = debugee.waitForClassLoaded(TESTED_CLASS_NAME, JDWP.SuspendPolicy.ALL);
225         log.display("  ... got classID: " + testedClassID);
226         log.display("");
227 
228         // get methodID for the exception throw method
229         log.display("Getting methodID for exception throw method: " + THROW_METHOD_NAME);
230         throwMethodID = debugee.getMethodID(testedClassID, THROW_METHOD_NAME, true);
231         log.display("  ... got methodID: " + throwMethodID);
232 
233         // get codeIndex for exception throw line
234         log.display("Getting codeIndex for exception throw line: " + EXCEPTION_THROW_LINE);
235         long codeIndex = debugee.getCodeIndex(testedClassID, throwMethodID, EXCEPTION_THROW_LINE);
236         log.display("  ... got index: " + codeIndex);
237 
238         // create location for exception throw line
239         log.display("Creating location for exception throw");
240         throwLocation = new JDWP.Location(JDWP.TypeTag.CLASS, testedClassID,
241                                                         throwMethodID, codeIndex);
242         log.display("  ... got location: " + throwLocation);
243 
244         // get methodID for the exception catch method
245         log.display("Getting methodID for exception catch method: " + CATCH_METHOD_NAME);
246         catchMethodID = debugee.getMethodID(testedClassID, CATCH_METHOD_NAME, true);
247         log.display("  ... got methodID: " + catchMethodID);
248 
249         // get codeIndex for exception catch line
250         log.display("Getting codeIndex for exception catch line: " + EXCEPTION_CATCH_LINE);
251         codeIndex = debugee.getCodeIndex(testedClassID, catchMethodID, EXCEPTION_CATCH_LINE);
252         log.display("  ... got index: " + codeIndex);
253 
254         // create location for exception catch line
255         log.display("Creating location for exception catch");
256         catchLocation = new JDWP.Location(JDWP.TypeTag.CLASS, testedClassID,
257                                                         catchMethodID, codeIndex);
258         log.display("  ... got location: " + catchLocation);
259         log.display("");
260 
261         // wait for breakpoint reached
262         log.display("Waiting for breakpoint reached at: "
263                         + BREAKPOINT_METHOD_NAME + ":" + BREAKPOINT_LINE);
264         testedThreadID = debugee.waitForBreakpointReached(testedClassID,
265                                                         BREAKPOINT_METHOD_NAME,
266                                                         BREAKPOINT_LINE,
267                                                         JDWP.SuspendPolicy.ALL);
268         log.display("  ... breakpoint reached with threadID: " + testedThreadID);
269 
270         // get excepion objectID value for static field
271         log.display("Getting exception objectID from static field: " + EXCEPTION_FIELD_NAME);
272         JDWP.Value value = debugee.getStaticFieldValue(testedClassID,  EXCEPTION_FIELD_NAME, JDWP.Tag.OBJECT);
273         exceptionObjectID = ((Long)value.getValue()).longValue();
274         log.display("  ... got exception objectID: " + exceptionObjectID);
275         log.display("");
276     }
277 
278     /**
279      * Make request for tested EXCEPTION event.
280      */
requestTestedEvent()281     void requestTestedEvent() {
282         Failure failure = new Failure("Error occured while makind request for tested event");
283 
284         // create command packet and fill requred out data
285         log.display("Create command packet: " + "EventRequest.Set");
286         CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Set);
287         log.display("    eventKind: " + TESTED_EVENT_KIND);
288         command.addByte(TESTED_EVENT_KIND);
289         log.display("    eventPolicy: " + TESTED_EVENT_SUSPEND_POLICY);
290         command.addByte(TESTED_EVENT_SUSPEND_POLICY);
291         log.display("    modifiers: " + 1);
292         command.addInt(1);
293         log.display("      modKind: " + JDWP.EventModifierKind.CLASS_ONLY + " (CLASS_ONLY)");
294         command.addByte(JDWP.EventModifierKind.CLASS_ONLY);
295         log.display("      classID: " + testedClassID);
296         command.addReferenceTypeID(testedClassID);
297         command.setLength();
298         log.display("  ... command packet composed");
299         log.display("");
300 
301         // send command packet to debugee
302         try {
303             log.display("Sending command packet:\n" + command);
304             transport.write(command);
305             log.display("  ... command packet sent");
306         } catch (IOException e) {
307             log.complain("Unable to send command packet:\n\t" + e);
308             success = false;
309             throw failure;
310         }
311         log.display("");
312 
313         // receive reply packet from debugee
314         ReplyPacket reply = new ReplyPacket();
315         try {
316             log.display("Waiting for reply packet");
317             transport.read(reply);
318             log.display("  ... packet received:\n" + reply);
319         } catch (IOException e) {
320             log.complain("Unable to read reply packet:\n\t" + e);
321             success = false;
322             throw failure;
323         }
324         log.display("");
325 
326         // check reply packet header
327         try{
328             log.display("Checking header of reply packet");
329             reply.checkHeader(command.getPacketID());
330             log.display("  .. packet header is correct");
331         } catch (BoundException e) {
332             log.complain("Bad header of reply packet:\n\t" + e.getMessage());
333             success = false;
334             throw failure;
335         }
336 
337         // start parsing reply packet data
338         log.display("Parsing reply packet:");
339         reply.resetPosition();
340 
341         // extract requestID
342         int requestID = 0;
343         try {
344             requestID = reply.getInt();
345             log.display("    requestID: " + requestID);
346         } catch (BoundException e) {
347             log.complain("Unable to extract requestID from request reply packet:\n\t"
348                         + e.getMessage());
349             success = false;
350             throw failure;
351         }
352 
353         // check requestID
354         if (requestID == 0) {
355             log.complain("Unexpected null requestID returned: " + requestID);
356             success = false;
357             throw failure;
358         }
359 
360         eventRequestID = requestID;
361 
362         // check for extra data in reply packet
363         if (!reply.isParsed()) {
364             log.complain("Extra trailing bytes found in request reply packet at: "
365                         + reply.offsetString());
366             success = false;
367         }
368 
369         log.display("  ... reply packet parsed");
370     }
371 
372     /**
373      * Clear request for tested EXCEPTION event.
374      */
clearTestedRequest()375     void clearTestedRequest() {
376         Failure failure = new Failure("Error occured while clearing request for tested event");
377 
378         // create command packet and fill requred out data
379         log.display("Create command packet: " + "EventRequest.Clear");
380         CommandPacket command = new CommandPacket(JDWP.Command.EventRequest.Clear);
381         log.display("    event: " + TESTED_EVENT_KIND);
382         command.addByte(TESTED_EVENT_KIND);
383         log.display("    requestID: " + eventRequestID);
384         command.addInt(eventRequestID);
385         log.display("  ... command packet composed");
386         log.display("");
387 
388         // send command packet to debugee
389         try {
390             log.display("Sending command packet:\n" + command);
391             transport.write(command);
392             log.display("  ... command packet sent");
393         } catch (IOException e) {
394             log.complain("Unable to send command packet:\n\t" + e);
395             success = false;
396             throw failure;
397         }
398         log.display("");
399 
400         ReplyPacket reply = new ReplyPacket();
401 
402         // receive reply packet from debugee
403         try {
404             log.display("Waiting for reply packet");
405             transport.read(reply);
406             log.display("  ... packet received:\n" + reply);
407         } catch (IOException e) {
408             log.complain("Unable to read reply packet:\n\t" + e);
409             success = false;
410             throw failure;
411         }
412 
413         // check reply packet header
414         try{
415             log.display("Checking header of reply packet");
416             reply.checkHeader(command.getPacketID());
417             log.display("  .. packet header is correct");
418         } catch (BoundException e) {
419             log.complain("Bad header of reply packet:\n\t" + e.getMessage());
420             success = false;
421             throw failure;
422         }
423 
424         // start parsing reply packet data
425         log.display("Parsing reply packet:");
426         reply.resetPosition();
427 
428         log.display("    no data");
429 
430         // check for extra data in reply packet
431         if (!reply.isParsed()) {
432             log.complain("Extra trailing bytes found in request reply packet at: "
433                         + reply.offsetString());
434             success = false;
435         }
436 
437         log.display("  ... reply packet parsed");
438     }
439 
440     /**
441      * Wait for tested EXCEPTION event.
442      */
waitForTestedEvent()443     void waitForTestedEvent() {
444 
445         // receive reply packet from debugee
446         EventPacket eventPacket = null;
447         try {
448             log.display("Waiting for event packet");
449             eventPacket = debugee.getEventPacket(timeout);
450             log.display("  ... event packet received:\n" + eventPacket);
451         } catch (IOException e) {
452             log.complain("Unable to read tested event packet:\n\t" + e);
453             success = false;
454             return;
455         }
456         log.display("");
457 
458         // check reply packet header
459         try{
460             log.display("Checking header of event packet");
461             eventPacket.checkHeader();
462             log.display("  ... packet header is correct");
463         } catch (BoundException e) {
464             log.complain("Bad header of tested event packet:\n\t"
465                         + e.getMessage());
466             success = false;
467             return;
468         }
469 
470         // start parsing reply packet data
471         log.display("Parsing event packet:");
472         eventPacket.resetPosition();
473 
474         // get suspendPolicy value
475         byte suspendPolicy = 0;
476         try {
477             suspendPolicy = eventPacket.getByte();
478             log.display("    suspendPolicy: " + suspendPolicy);
479         } catch (BoundException e) {
480             log.complain("Unable to get suspendPolicy value from tested event packet:\n\t"
481                         + e.getMessage());
482             success = false;
483             return;
484         }
485 
486         // check suspendPolicy value
487         if (suspendPolicy != TESTED_EVENT_SUSPEND_POLICY) {
488             log.complain("Unexpected SuspendPolicy in tested event packet: " +
489                         suspendPolicy + " (expected: " + TESTED_EVENT_SUSPEND_POLICY + ")");
490             success = false;
491         }
492 
493         // get events count
494         int events = 0;
495         try {
496             events = eventPacket.getInt();
497             log.display("    events: " + events);
498         } catch (BoundException e) {
499             log.complain("Unable to get events count from tested event packet:\n\t"
500                         + e.getMessage());
501             success = false;
502             return;
503         }
504 
505         // check events count
506         if (events < 0) {
507             log.complain("Negative value of events number in tested event packet: " +
508                         events + " (expected: " + 1 + ")");
509             success = false;
510         } else if (events != 1) {
511             log.complain("Invalid number of events in tested event packet: " +
512                         events + " (expected: " + 1 + ")");
513             success = false;
514         }
515 
516         // extract each event
517         long eventThreadID = 0;
518         for (int i = 0; i < events; i++) {
519             log.display("    event #" + i + ":");
520 
521             // get eventKind
522             byte eventKind = 0;
523             try {
524                 eventKind = eventPacket.getByte();
525                 log.display("      eventKind: " + eventKind);
526             } catch (BoundException e) {
527                 log.complain("Unable to get eventKind of event #" + i + " from tested event packet:\n\t"
528                             + e.getMessage());
529                 success = false;
530                 return;
531             }
532 
533             // check eventKind
534             if (eventKind == JDWP.EventKind.VM_DEATH) {
535                 log.complain("Unexpected VM_DEATH event received: " +
536                             eventKind + " (expected: " + JDWP.EventKind.EXCEPTION + ")");
537                 dead = true;
538                 success = false;
539                 return;
540             }  else if (eventKind != JDWP.EventKind.EXCEPTION) {
541                 log.complain("Unexpected eventKind of event " + i + " in tested event packet: " +
542                             eventKind + " (expected: " + JDWP.EventKind.EXCEPTION + ")");
543                 success = false;
544                 return;
545             }
546 
547             // get requestID
548             int requestID = 0;
549             try {
550                 requestID = eventPacket.getInt();
551                 log.display("      requestID: " + requestID);
552             } catch (BoundException e) {
553                 log.complain("Unable to get requestID of event #" + i + " from tested event packet:\n\t"
554                             + e.getMessage());
555                 success = false;
556                 return;
557             }
558 
559             // check requestID
560             if (requestID != eventRequestID) {
561                 log.complain("Unexpected requestID of event " + i + " in tested event packet: " +
562                             requestID + " (expected: " + eventRequestID + ")");
563                 success = false;
564             }
565 
566             // get threadID
567             long threadID = 0;
568             try {
569                 threadID = eventPacket.getObjectID();
570                 log.display("      threadID: " + threadID);
571             } catch (BoundException e) {
572                 log.complain("Unable to get threadID of event #" + i + " from tested event packet:\n\t"
573                             + e.getMessage());
574                 success = false;
575                 return;
576             }
577 
578             // check threadID
579             if (threadID != testedThreadID) {
580                 log.complain("Unexpected threadID of event " + i + " in tested event packet: " +
581                             threadID + " (expected: " + testedThreadID + ")");
582                 success = false;
583             }
584 
585             // get throw location
586             JDWP.Location location = null;
587             try {
588                 location = eventPacket.getLocation();
589                 log.display("      throw_location: " + location);
590             } catch (BoundException e) {
591                 log.complain("Unable to get throw location of event #" + i + " from tested event packet:\n\t"
592                             + e.getMessage());
593                 success = false;
594                 return;
595             }
596 
597             // check location
598             checkLocation(location, throwLocation, i, EXCEPTION_THROW_LINE, "throw");
599 
600             // get exception tag
601             byte tag = 0;
602             try {
603                 tag = eventPacket.getByte();
604                 log.display("      exception_tag: " + tag);
605             } catch (BoundException e) {
606                 log.complain("Unable to get exception tag of event #" + i + " from tested event packet:\n\t"
607                             + e.getMessage());
608                 success = false;
609                 return;
610             }
611 
612             // check tag
613             if (tag != JDWP.Tag.OBJECT) {
614                 log.complain("Unexpected exception tag of event " + i + " in tested event packet: " +
615                             tag + " (expected: " + JDWP.Tag.OBJECT + ")");
616                 success = false;
617             }
618 
619             // get exception objectID
620             long objectID = 0;
621             try {
622                 objectID = eventPacket.getObjectID();
623                 log.display("      exception_objectID: " + objectID);
624             } catch (BoundException e) {
625                 log.complain("Unable to get exception objectID of event #" + i + " from tested event packet:\n\t"
626                             + e.getMessage());
627                 success = false;
628                 return;
629             }
630 
631             // check threadID
632             if (objectID != exceptionObjectID) {
633                 log.complain("Unexpected exception objectID of event " + i + " in tested event packet: " +
634                             objectID + " (expected: " + exceptionObjectID + ")");
635                 success = false;
636             }
637 
638             // get catch location
639             location = null;
640             try {
641                 location = eventPacket.getLocation();
642                 log.display("      catch_location: " + location);
643             } catch (BoundException e) {
644                 log.complain("Unable to get catch location of event #" + i + " from tested event packet:\n\t"
645                             + e.getMessage());
646                 success = false;
647                 return;
648             }
649 
650             // check location
651             checkLocation(location, catchLocation, i, EXCEPTION_CATCH_LINE, "catch");
652         }
653 
654         // check for extra data in event packet
655         if (!eventPacket.isParsed()) {
656             log.complain("Extra trailing bytes found in event packet at: "
657                         + eventPacket.offsetString());
658             success = false;
659         }
660 
661         log.display("  ... event packet parsed");
662     }
663 
664     /**
665      * Check if given location is equal to the expected one.
666      */
checkLocation(JDWP.Location location, JDWP.Location expectedLocation, int eventNumber, int expectedLine, String kind)667     void checkLocation(JDWP.Location location, JDWP.Location expectedLocation,
668                                     int eventNumber, int expectedLine, String kind) {
669         if (location.getTag() != expectedLocation.getTag()) {
670             log.complain("Unexpected class tag of " + kind + " location of event "
671                         + eventNumber + " in tested event packet: " + location.getTag()
672                         + " (expected: " + expectedLocation.getTag() + ")");
673             success = false;
674         }
675         if (location.getClassID() != expectedLocation.getClassID()) {
676             log.complain("Unexpected classID of " + kind + " location of event "
677                         + eventNumber + " in tested event packet: " + location.getClassID()
678                         + " (expected: " + expectedLocation.getClassID() + ")");
679             success = false;
680         }
681         if (location.getMethodID() != expectedLocation.getMethodID()) {
682             log.complain("Unexpected methodID of " + kind + " location of event "
683                         + eventNumber + " in tested event packet: " + location.getMethodID()
684                         + " (expected: " + expectedLocation.getMethodID() + ")");
685             success = false;
686         }
687         if (location.getIndex() != expectedLocation.getIndex()) {
688 /*
689             log.complain("Unexpected codeIndex of " + kind + " location of event " + i
690                         + " in tested event packet: " + location.getIndex()
691                         + " (expected: " + expectedLocation.getIndex() + ")");
692             success = false;
693 */
694             try {
695                 // find approximate line number for location
696                 int lineNumber = debugee.getLineNumber(location, true);
697                 if (lineNumber != expectedLine) {
698                     log.complain("Unexpected line number of " + kind + " location of event "
699                                 + eventNumber + " in tested event packet: " + lineNumber
700                                 + " (expected: " + expectedLine + ")");
701                     success = false;
702                 } else {
703                     log.display("Unexpected codeIndex of " + kind + " location: " + location.getIndex()
704                                 + " (expected: " + expectedLocation.getIndex() + ")");
705                     log.display("Though line number of catch location is as expected: "
706                                 + expectedLine);
707                 }
708             } catch (Failure e) {
709                 log.complain("Unable to get line number for " + kind + " location of event "
710                             + eventNumber + " in tested event packet:\n\t" + e.getMessage());
711                 success = false;
712             }
713         }
714     }
715 
716     /**
717      * Disconnect debuggee and wait for it exited.
718      */
quitDebugee()719     void quitDebugee() {
720         if (debugee == null)
721             return;
722 
723         // disconnect debugee
724         if (!dead) {
725             try {
726                 log.display("Disconnecting debuggee");
727                 debugee.dispose();
728                 log.display("  ... debuggee disconnected");
729             } catch (Failure e) {
730                 log.display("Failed to finally disconnect debuggee:\n\t"
731                             + e.getMessage());
732             }
733         }
734 
735         // wait for debugee exited
736         log.display("Waiting for debuggee exit");
737         int code = debugee.waitFor();
738         log.display("  ... debuggee exited with exit code: " + code);
739 
740         // analize debugee exit status code
741         if (code != JCK_STATUS_BASE + PASSED) {
742             log.complain("Debuggee FAILED with exit code: " + code);
743             success = false;
744         }
745     }
746 
747 }
748