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