1 /*
   2  * Copyright (c) 2000, 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 4334008
  27  * @summary RepStep detects missed step events due to lack of
  28  * frame pop events (in back-end).
  29  * @author Robert Field
  30  *
  31  * @run compile -g RepStepTarg.java
  32  * @run build VMConnection RepStep
  33  *
  34  * @run driver RepStep
  35  */
  36 import com.sun.jdi.*;
  37 import com.sun.jdi.event.*;
  38 import com.sun.jdi.request.*;
  39 import com.sun.jdi.connect.*;
  40 
  41 import java.util.*;
  42 
  43 public class RepStep {
  44     static final String TARGET = "RepStepTarg";
  45     static final int GRANULARITY = StepRequest.STEP_LINE;
  46     static final int DEPTH = StepRequest.STEP_INTO;
  47     static final int SUCCESS_COUNT = 30;
  48 
  49     VirtualMachine vm;
  50     final EventRequestManager requestManager;
  51     int stepNum = 0;
  52     boolean passed = false;
  53 
  54     public static void main(String args[]) throws Exception {
  55         new RepStep(args);
  56     }
  57 
  58     RepStep(String args[]) throws Exception {
  59         if (args.length > 0) {
  60             attachTarget(args[0]);
  61         } else {
  62             launchTarget();
  63         }
  64         //        vm.setDebugTraceMode(VirtualMachine.TRACE_ALL);
  65         requestManager = vm.eventRequestManager();
  66         runTests();
  67         dieNice();
  68     }
  69 
  70     private void createStep(ThreadReference thread) {
  71         final StepRequest sr =
  72                   requestManager.createStepRequest(thread,
  73                                                    GRANULARITY,
  74                                                    DEPTH);
  75 
  76         sr.addClassExclusionFilter("java.*");
  77         sr.addClassExclusionFilter("javax.*");
  78         sr.addClassExclusionFilter("sun.*");
  79         sr.addClassExclusionFilter("com.sun.*");
  80         sr.addClassExclusionFilter("com.oracle.*");
  81         sr.addClassExclusionFilter("oracle.*");
  82         sr.addClassExclusionFilter("jdk.internal.*");
  83         sr.enable();
  84     }
  85 
  86     private void runTests() throws Exception {
  87         ThreadReference thread = null;
  88         EventQueue queue = vm.eventQueue();
  89         while (true) {
  90             EventSet set = queue.remove();
  91             for (EventIterator it = set.eventIterator(); it.hasNext(); ) {
  92                 Event event = it.nextEvent();
  93                 if (event instanceof VMStartEvent) {
  94                     // get thread for setting step later
  95                     thread = ((VMStartEvent)event).thread();
  96                     ClassPrepareRequest cpReq
  97                         = requestManager.createClassPrepareRequest();
  98                     cpReq.addClassFilter(TARGET);
  99                     cpReq.enable();
 100                 } else if (event instanceof ClassPrepareEvent) {
 101                     createStep(thread);
 102                     event.request().disable();
 103                 } else if (event instanceof StepEvent) {
 104                     // StepEvent stepEvent = (StepEvent)event;
 105                     // System.out.println(stepEvent);
 106                     System.out.println(++stepNum);
 107                     if (stepNum >= SUCCESS_COUNT) {
 108                         // would have failed by now (> 4)
 109                         System.out.println("RepStep passed");
 110                         event.request().disable();
 111                         set.resume();
 112                         return; // Success exit
 113                     }
 114                 } else if (event instanceof VMDeathEvent) {
 115                     throw new Exception("RepStep failed: steps missed");
 116                 } else {
 117                     throw new Exception("Unexpected event: " + event);
 118                 }
 119             }
 120             set.resume();
 121        }
 122     }
 123 
 124     private void dieNice() throws Exception {
 125         EventQueue queue = vm.eventQueue();
 126         while (true) {
 127             EventSet set = queue.remove();
 128             for (EventIterator it = set.eventIterator(); it.hasNext(); ) {
 129                 Event event = it.nextEvent();
 130                 if (event instanceof VMDeathEvent) {
 131                     // ignore
 132                 } else if (event instanceof VMDisconnectEvent) {
 133                     set.resume();
 134                     return; // Success exit
 135                 } else {
 136                     throw new Exception("Unexpected event: " + event);
 137                 }
 138             }
 139             set.resume();
 140        }
 141     }
 142 
 143     private Connector findConnector(String name) throws Exception {
 144         List connectors = Bootstrap.virtualMachineManager().allConnectors();
 145         Iterator iter = connectors.iterator();
 146         while (iter.hasNext()) {
 147             Connector connector = (Connector)iter.next();
 148             if (connector.name().equals(name)) {
 149                 return connector;
 150             }
 151         }
 152         throw new Exception("No connector: " + name);
 153     }
 154 
 155     /* launch child target vm */
 156     private void launchTarget() throws Exception {
 157         LaunchingConnector launcher =
 158           (LaunchingConnector)findConnector("com.sun.jdi.CommandLineLaunch");
 159         Map connectorArgs = launcher.defaultArguments();
 160         Connector.Argument mainArg =
 161             (Connector.Argument)connectorArgs.get("main");
 162         mainArg.setValue(TARGET);
 163         Connector.Argument optionsArg =
 164             (Connector.Argument)connectorArgs.get("options");
 165         optionsArg.setValue(VMConnection.getDebuggeeVMOptions());
 166 
 167         vm = launcher.launch(connectorArgs);
 168         System.out.println("launched: " + TARGET);
 169     }
 170 
 171     private void attachTarget(String portNum) throws Exception {
 172         AttachingConnector conn =
 173             (AttachingConnector)findConnector("com.sun.jdi.SocketAttach");
 174         Map connectorArgs = conn.defaultArguments();
 175         Connector.Argument portArg =
 176             (Connector.Argument)connectorArgs.get("port");
 177         portArg.setValue(portNum);
 178         vm = conn.attach(connectorArgs);
 179         System.out.println("attached to: " + portNum);
 180     }
 181 
 182 }