test/jdk/com/sun/jdi/MethodEntryExitEvents.java
changeset 47216 71c04702a3d5
parent 44423 306c020eb154
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 2001, 2015, 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 /**
       
    25  * @test
       
    26  * @bug 4409241 4432820
       
    27  * @summary Test the bug fix for: MethodExitEvents disappear when Object-Methods are called from main
       
    28  * @author Tim Bell
       
    29  *
       
    30  * @run build TestScaffold VMConnection TargetListener TargetAdapter
       
    31  * @run compile -g MethodEntryExitEvents.java
       
    32  * @run driver MethodEntryExitEvents SUSPEND_EVENT_THREAD MethodEntryExitEventsDebugee
       
    33  * @run driver MethodEntryExitEvents SUSPEND_NONE MethodEntryExitEventsDebugee
       
    34  * @run driver MethodEntryExitEvents SUSPEND_ALL MethodEntryExitEventsDebugee
       
    35  */
       
    36 import com.sun.jdi.*;
       
    37 import com.sun.jdi.event.*;
       
    38 import com.sun.jdi.request.*;
       
    39 import java.util.*;
       
    40 
       
    41 class t2 {
       
    42     public static void sayHello1(int i, int j) {
       
    43         sayHello2(i, j);
       
    44     }
       
    45     public static void sayHello2(int i, int j) {
       
    46         sayHello3(i, j);
       
    47     }
       
    48     public static void sayHello3(int i, int j) {
       
    49         sayHello4(i, j);
       
    50     }
       
    51     public static void sayHello4(int i, int j) {
       
    52         sayHello5(i, j);
       
    53     }
       
    54     public static void sayHello5(int i, int j) {
       
    55         if (i < 2) {
       
    56             sayHello1(++i, j);
       
    57         } else {
       
    58             System.out.print  ("MethodEntryExitEventsDebugee: ");
       
    59             System.out.print  ("    -->> Hello.  j is: ");
       
    60             System.out.print  (j);
       
    61             System.out.println(" <<--");
       
    62         }
       
    63     }
       
    64 }
       
    65 
       
    66 class MethodEntryExitEventsDebugee {
       
    67     public static void loopComplete () {
       
    68         /*
       
    69          * The implementation here is deliberately inefficient
       
    70          * because the debugger is still watching this method.
       
    71          */
       
    72         StringBuffer sb = new StringBuffer();
       
    73         sb.append ("MethodEntryExitEventsDebugee: ");
       
    74         sb.append ("Executing loopComplete method for a graceful shutdown...");
       
    75         String s = sb.toString();
       
    76         for (int i = 0; i < s.length(); i++) {
       
    77             char c = s.charAt(i);
       
    78             System.out.print(c);
       
    79         }
       
    80         System.out.println();
       
    81     }
       
    82     public static void main(String[] args) {
       
    83         t2 test = new t2();
       
    84         for (int j = 0; j < 3; j++) {
       
    85             test.sayHello1(0, j);
       
    86         }
       
    87         loopComplete();
       
    88     }
       
    89 }
       
    90 
       
    91 
       
    92 public class MethodEntryExitEvents extends TestScaffold {
       
    93     int sessionSuspendPolicy = EventRequest.SUSPEND_ALL;
       
    94     StepRequest stepReq = null; //Only one step request allowed per thread
       
    95     boolean finishedCounting = false;
       
    96 
       
    97     /*
       
    98      * Enter main() , then t2.<init>, then sayHello[1,2,3,4,5] 15 times 3 loops,
       
    99      * then loopComplete()
       
   100      */
       
   101     final int expectedEntryCount = 1 + 1 + (15 * 3) + 1;
       
   102     int methodEntryCount = 0;
       
   103 
       
   104     /*
       
   105      * Exit t2.<init>, then sayHello[1,2,3,4,5] 15 times 3 loopa
       
   106      * (event monitoring is cancelled before we exit loopComplete() or main())
       
   107      */
       
   108     final int expectedExitCount = 1 + (15 * 3);
       
   109     int methodExitCount = 0;
       
   110 
       
   111     // Classes which we are interested in
       
   112     private List includes = Arrays.asList(new String[] {
       
   113         "MethodEntryExitEventsDebugee",
       
   114         "t2"
       
   115     });
       
   116 
       
   117     MethodEntryExitEvents (String args[]) {
       
   118         super(args);
       
   119     }
       
   120 
       
   121     private void usage(String[] args) throws Exception {
       
   122         StringBuffer sb = new StringBuffer("Usage: ");
       
   123         sb.append(System.getProperty("line.separator"));
       
   124         sb.append("  java ");
       
   125         sb.append(getClass().getName());
       
   126         sb.append(" [SUSPEND_NONE | SUSPEND_EVENT_THREAD | SUSPEND_ALL]");
       
   127         sb.append(" [MethodEntryExitEventsDebugee | -connect <connector options...>] ");
       
   128         throw new Exception (sb.toString());
       
   129     }
       
   130 
       
   131     public static void main(String[] args)      throws Exception {
       
   132         MethodEntryExitEvents meee = new MethodEntryExitEvents (args);
       
   133         meee.startTests();
       
   134     }
       
   135 
       
   136     public void exceptionThrown(ExceptionEvent event) {
       
   137         System.out.println("Exception: " + event.exception());
       
   138         System.out.println(" at catch location: " + event.catchLocation());
       
   139 
       
   140         // Step to the catch
       
   141         if (stepReq == null) {
       
   142             stepReq =
       
   143                 eventRequestManager().createStepRequest(event.thread(),
       
   144                                                         StepRequest.STEP_MIN,
       
   145                                                         StepRequest.STEP_INTO);
       
   146             stepReq.addCountFilter(1);  // next step only
       
   147             stepReq.setSuspendPolicy(EventRequest.SUSPEND_ALL);
       
   148         }
       
   149         stepReq.enable();
       
   150     }
       
   151     public void stepCompleted(StepEvent event) {
       
   152         System.out.println("stepCompleted: line#=" +
       
   153                            event.location().lineNumber() +
       
   154                            " event=" + event);
       
   155         // disable the step and then run to completion
       
   156         //eventRequestManager().deleteEventRequest(event.request());
       
   157         StepRequest str= (StepRequest)event.request();
       
   158         str.disable();
       
   159     }
       
   160     public void methodEntered(MethodEntryEvent event) {
       
   161         if (!includes.contains(event.method().declaringType().name())) {
       
   162             return;
       
   163         }
       
   164 
       
   165         if (! finishedCounting) {
       
   166             // We have to count the entry to loopComplete, but
       
   167             // not the exit
       
   168             methodEntryCount++;
       
   169             System.out.print  (" Method entry number: ");
       
   170             System.out.print  (methodEntryCount);
       
   171             System.out.print  ("  :  ");
       
   172             System.out.println(event);
       
   173             if ("loopComplete".equals(event.method().name())) {
       
   174                 finishedCounting = true;
       
   175             }
       
   176         }
       
   177     }
       
   178 
       
   179     public void methodExited(MethodExitEvent event) {
       
   180         if (!includes.contains(event.method().declaringType().name())) {
       
   181             return;
       
   182         }
       
   183 
       
   184         if (! finishedCounting){
       
   185             methodExitCount++;
       
   186             System.out.print  (" Method exit  number: ");
       
   187             System.out.print  (methodExitCount);
       
   188             System.out.print  ("  :  ");
       
   189             System.out.println(event);
       
   190         }
       
   191     }
       
   192 
       
   193     protected void runTests() throws Exception {
       
   194         if (args.length < 1) {
       
   195             usage(args);
       
   196         }
       
   197         //Pick up the SUSPEND_xxx in first argument
       
   198         if ("SUSPEND_NONE".equals(args[0])) {
       
   199             sessionSuspendPolicy = EventRequest.SUSPEND_NONE;
       
   200         } else if ("SUSPEND_EVENT_THREAD".equals(args[0])) {
       
   201             sessionSuspendPolicy = EventRequest.SUSPEND_EVENT_THREAD;
       
   202         } else if ("SUSPEND_ALL".equals(args[0])) {
       
   203             sessionSuspendPolicy = EventRequest.SUSPEND_ALL;
       
   204         } else {
       
   205             usage(args);
       
   206         }
       
   207         System.out.print("Suspend policy is: ");
       
   208         System.out.println(args[0]);
       
   209 
       
   210         // Skip the test arg
       
   211         String[] args2 = new String[args.length - 1];
       
   212         System.arraycopy(args, 1, args2, 0, args.length - 1);
       
   213 
       
   214         if (args2.length < 1) {
       
   215             usage(args2);
       
   216         }
       
   217         List argList = new ArrayList(Arrays.asList(args2));
       
   218         System.out.println("run args: " + argList);
       
   219         connect((String[]) argList.toArray(args2));
       
   220         waitForVMStart();
       
   221 
       
   222         // Determine main thread
       
   223         ClassPrepareEvent e = resumeToPrepareOf("MethodEntryExitEventsDebugee");
       
   224         mainThread = e.thread();
       
   225 
       
   226         try {
       
   227 
       
   228             /*
       
   229              * Ask for Exception events
       
   230              */
       
   231             ExceptionRequest exceptionRequest =
       
   232                 eventRequestManager().createExceptionRequest(null, // refType (null == all instances)
       
   233                                                              true, // notifyCaught
       
   234                                                              true);// notifyUncaught
       
   235             exceptionRequest.addThreadFilter(mainThread);
       
   236             exceptionRequest.setSuspendPolicy(EventRequest.SUSPEND_ALL);
       
   237             exceptionRequest.enable();
       
   238 
       
   239             /*
       
   240              * Ask for method entry events
       
   241              */
       
   242             MethodEntryRequest entryRequest =
       
   243                eventRequestManager().createMethodEntryRequest();
       
   244             entryRequest.addThreadFilter(mainThread);
       
   245             entryRequest.setSuspendPolicy(sessionSuspendPolicy);
       
   246             entryRequest.enable();
       
   247 
       
   248             /*
       
   249              * Ask for method exit events
       
   250              */
       
   251             MethodExitRequest exitRequest =
       
   252                 eventRequestManager().createMethodExitRequest();
       
   253             exitRequest.addThreadFilter(mainThread);
       
   254             exitRequest.setSuspendPolicy(sessionSuspendPolicy);
       
   255             exitRequest.enable();
       
   256 
       
   257             /*
       
   258              * We are now set up to receive the notifications we want.
       
   259              * Here we go.  This adds 'this' as a listener so
       
   260              * that our handlers above will be called.
       
   261              */
       
   262 
       
   263             listenUntilVMDisconnect();
       
   264             System.out.println("All done...");
       
   265 
       
   266         } catch (Exception ex){
       
   267             ex.printStackTrace();
       
   268             testFailed = true;
       
   269         }
       
   270 
       
   271         if ((methodEntryCount != expectedEntryCount) ||
       
   272             (methodExitCount != expectedExitCount)) {
       
   273             testFailed = true;
       
   274         }
       
   275         if (!testFailed) {
       
   276             System.out.println();
       
   277             System.out.println("MethodEntryExitEvents: passed");
       
   278             System.out.print  ("    Method entry count: ");
       
   279             System.out.println(methodEntryCount);
       
   280             System.out.print  ("    Method exit  count: ");
       
   281             System.out.println(methodExitCount);
       
   282         } else {
       
   283             System.out.println();
       
   284             System.out.println("MethodEntryExitEvents: failed");
       
   285             System.out.print  ("    expected method entry count: ");
       
   286             System.out.println(expectedEntryCount);
       
   287             System.out.print  ("    observed method entry count: ");
       
   288             System.out.println(methodEntryCount);
       
   289             System.out.print  ("    expected method exit  count: ");
       
   290             System.out.println(expectedExitCount);
       
   291             System.out.print  ("    observed method exit  count: ");
       
   292             System.out.println(methodExitCount);
       
   293             throw new Exception("MethodEntryExitEvents: failed");
       
   294         }
       
   295     }
       
   296 }