hotspot/agent/test/jdi/VMConnection.java
changeset 1 489c9b5090e2
child 5547 f4b087cbb361
equal deleted inserted replaced
0:fd16c54261b3 1:489c9b5090e2
       
     1 /*
       
     2  * Copyright 2002 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    21  * have any questions.
       
    22  *
       
    23  */
       
    24 
       
    25 import com.sun.jdi.*;
       
    26 import com.sun.jdi.connect.*;
       
    27 import com.sun.jdi.request.EventRequestManager;
       
    28 
       
    29 import java.util.*;
       
    30 import java.io.*;
       
    31 
       
    32 
       
    33 /**
       
    34  * Manages a VM conection for the JDI test framework.
       
    35  */
       
    36 class VMConnection {
       
    37     private VirtualMachine vm;
       
    38     private Process process = null;
       
    39     private int outputCompleteCount = 0;
       
    40 
       
    41     private final Connector connector;
       
    42     private final Map connectorArgs;
       
    43     private final int traceFlags;
       
    44 
       
    45     /**
       
    46      * Return a String containing VM Options to pass to the debugee
       
    47      * or an empty string if there are none.
       
    48      * These are read from the first non-comment line
       
    49      * in file test/com/sun/jdi/@debuggeeVMOptions.
       
    50      */
       
    51     static public String getDebuggeeVMOptions() {
       
    52 
       
    53         // When we run under jtreg, test.src contains the pathname of
       
    54         // the test/com/sun/jdi dir.
       
    55         BufferedReader reader;
       
    56         final String filename = "@debuggeeVMOptions";
       
    57         String srcDir = System.getProperty("test.src");
       
    58 
       
    59         if (srcDir == null) {
       
    60           srcDir = System.getProperty("user.dir");
       
    61         }
       
    62         srcDir = srcDir + File.separator;
       
    63 
       
    64         File myDir = new File(srcDir);
       
    65 
       
    66         File myFile = new File(myDir, filename);
       
    67         if (!myFile.canRead()) {
       
    68             try {
       
    69                 // We have some subdirs of test/com/sun/jdi so in case we
       
    70                 // are in one of them, look in our parent dir for the file.
       
    71                 myFile = new File(myDir.getCanonicalFile().getParent(),
       
    72                                   filename);
       
    73                 if (!myFile.canRead()) {
       
    74                     return "";
       
    75                 }
       
    76             } catch (IOException ee) {
       
    77                 System.out.println("-- Error 1 trying to access file " +
       
    78                                    myFile.getPath() + ": " + ee);
       
    79                 return "";
       
    80             }
       
    81         }
       
    82         String wholePath = myFile.getPath();
       
    83         try {
       
    84             reader = new BufferedReader(new FileReader(myFile));
       
    85         } catch (FileNotFoundException ee) {
       
    86             System.out.println("-- Error 2 trying to access file " +
       
    87                                wholePath + ": " + ee);
       
    88             return "";
       
    89         }
       
    90 
       
    91         String line;
       
    92         String retVal = "";
       
    93         while (true) {
       
    94             try {
       
    95                 line = reader.readLine();
       
    96             } catch (IOException ee) {
       
    97                 System.out.println("-- Error reading options from file " +
       
    98                                    wholePath + ": " + ee);
       
    99                 break;
       
   100             }
       
   101             if (line == null) {
       
   102                 System.out.println("-- No debuggee VM options found in file " +
       
   103                                    wholePath);
       
   104                 break;
       
   105             }
       
   106             line = line.trim();
       
   107             if (line.length() != 0 && !line.startsWith("#")) {
       
   108                 System.out.println("-- Added debuggeeVM options from file " +
       
   109                                    wholePath + ": " + line);
       
   110                 retVal = line;
       
   111                 break;
       
   112             }
       
   113             // Else, read he next line.
       
   114         }
       
   115         try {
       
   116             reader.close();
       
   117         } catch (IOException ee) {
       
   118         }
       
   119         return retVal;
       
   120     }
       
   121 
       
   122     private Connector findConnector(String name) {
       
   123         List connectors = Bootstrap.virtualMachineManager().allConnectors();
       
   124         Iterator iter = connectors.iterator();
       
   125         while (iter.hasNext()) {
       
   126             Connector connector = (Connector)iter.next();
       
   127             if (connector.name().equals(name)) {
       
   128                 return connector;
       
   129             }
       
   130         }
       
   131         return null;
       
   132     }
       
   133 
       
   134     private Map parseConnectorArgs(Connector connector, String argString) {
       
   135         StringTokenizer tokenizer = new StringTokenizer(argString, ",");
       
   136         Map arguments = connector.defaultArguments();
       
   137 
       
   138         while (tokenizer.hasMoreTokens()) {
       
   139             String token = tokenizer.nextToken();
       
   140             int index = token.indexOf('=');
       
   141             if (index == -1) {
       
   142                 throw new IllegalArgumentException("Illegal connector argument: " +
       
   143                                                    token);
       
   144             }
       
   145             String name = token.substring(0, index);
       
   146             String value = token.substring(index + 1);
       
   147             Connector.Argument argument = (Connector.Argument)arguments.get(name);
       
   148             if (argument == null) {
       
   149                 throw new IllegalArgumentException("Argument " + name +
       
   150                                                "is not defined for connector: " +
       
   151                                                connector.name());
       
   152             }
       
   153             argument.setValue(value);
       
   154         }
       
   155         return arguments;
       
   156     }
       
   157 
       
   158     VMConnection(String connectSpec, int traceFlags) {
       
   159         String nameString;
       
   160         String argString;
       
   161         int index = connectSpec.indexOf(':');
       
   162         if (index == -1) {
       
   163             nameString = connectSpec;
       
   164             argString = "";
       
   165         } else {
       
   166             nameString = connectSpec.substring(0, index);
       
   167             argString = connectSpec.substring(index + 1);
       
   168         }
       
   169 
       
   170         connector = findConnector(nameString);
       
   171         if (connector == null) {
       
   172             throw new IllegalArgumentException("No connector named: " +
       
   173                                                nameString);
       
   174         }
       
   175 
       
   176         connectorArgs = parseConnectorArgs(connector, argString);
       
   177         this.traceFlags = traceFlags;
       
   178     }
       
   179 
       
   180     synchronized VirtualMachine open() {
       
   181         if (connector instanceof LaunchingConnector) {
       
   182             vm = launchTarget();
       
   183         } else if (connector instanceof AttachingConnector) {
       
   184             vm = attachTarget();
       
   185         } else if (connector instanceof ListeningConnector) {
       
   186             vm = listenTarget();
       
   187         } else {
       
   188             throw new InternalError("Invalid connect type");
       
   189         }
       
   190         vm.setDebugTraceMode(traceFlags);
       
   191         System.out.println("JVM version:" + vm.version());
       
   192         System.out.println("JDI version: " + Bootstrap.virtualMachineManager().majorInterfaceVersion() +
       
   193                            "." + Bootstrap.virtualMachineManager().minorInterfaceVersion());
       
   194         System.out.println("JVM description: " + vm.description());
       
   195 
       
   196         return vm;
       
   197     }
       
   198 
       
   199     boolean setConnectorArg(String name, String value) {
       
   200         /*
       
   201          * Too late if the connection already made
       
   202          */
       
   203         if (vm != null) {
       
   204             return false;
       
   205         }
       
   206 
       
   207         Connector.Argument argument = (Connector.Argument)connectorArgs.get(name);
       
   208         if (argument == null) {
       
   209             return false;
       
   210         }
       
   211         argument.setValue(value);
       
   212         return true;
       
   213     }
       
   214 
       
   215     String connectorArg(String name) {
       
   216         Connector.Argument argument = (Connector.Argument)connectorArgs.get(name);
       
   217         if (argument == null) {
       
   218             return "";
       
   219         }
       
   220         return argument.value();
       
   221     }
       
   222 
       
   223     public synchronized VirtualMachine vm() {
       
   224         if (vm == null) {
       
   225             throw new InternalError("VM not connected");
       
   226         } else {
       
   227             return vm;
       
   228         }
       
   229     }
       
   230 
       
   231     boolean isOpen() {
       
   232         return (vm != null);
       
   233     }
       
   234 
       
   235     boolean isLaunch() {
       
   236         return (connector instanceof LaunchingConnector);
       
   237     }
       
   238 
       
   239     Connector connector() {
       
   240         return connector;
       
   241     }
       
   242 
       
   243     boolean isListen() {
       
   244         return (connector instanceof ListeningConnector);
       
   245     }
       
   246 
       
   247     boolean isAttach() {
       
   248         return (connector instanceof AttachingConnector);
       
   249     }
       
   250 
       
   251     private synchronized void notifyOutputComplete() {
       
   252         outputCompleteCount++;
       
   253         notifyAll();
       
   254     }
       
   255 
       
   256     private synchronized void waitOutputComplete() {
       
   257         // Wait for stderr and stdout
       
   258         if (process != null) {
       
   259             while (outputCompleteCount < 2) {
       
   260                 try {wait();} catch (InterruptedException e) {}
       
   261             }
       
   262         }
       
   263     }
       
   264 
       
   265     public void disposeVM() {
       
   266         try {
       
   267             if (vm != null) {
       
   268                 vm.dispose();
       
   269                 vm = null;
       
   270             }
       
   271         } finally {
       
   272             if (process != null) {
       
   273                 process.destroy();
       
   274                 process = null;
       
   275             }
       
   276             waitOutputComplete();
       
   277         }
       
   278     }
       
   279 
       
   280     private void dumpStream(InputStream stream) throws IOException {
       
   281         PrintStream outStream = System.out;
       
   282         BufferedReader in =
       
   283             new BufferedReader(new InputStreamReader(stream));
       
   284         String line;
       
   285         while ((line = in.readLine()) != null) {
       
   286             outStream.println(line);
       
   287         }
       
   288     }
       
   289 
       
   290     /**
       
   291      *  Create a Thread that will retrieve and display any output.
       
   292      *  Needs to be high priority, else debugger may exit before
       
   293      *  it can be displayed.
       
   294      */
       
   295     private void displayRemoteOutput(final InputStream stream) {
       
   296         Thread thr = new Thread("output reader") {
       
   297             public void run() {
       
   298                 try {
       
   299                     dumpStream(stream);
       
   300                 } catch (IOException ex) {
       
   301                     System.err.println("IOException reading output of child java interpreter:"
       
   302                                        + ex.getMessage());
       
   303                 } finally {
       
   304                     notifyOutputComplete();
       
   305                 }
       
   306             }
       
   307         };
       
   308         thr.setPriority(Thread.MAX_PRIORITY-1);
       
   309         thr.start();
       
   310     }
       
   311 
       
   312     private void dumpFailedLaunchInfo(Process process) {
       
   313         try {
       
   314             dumpStream(process.getErrorStream());
       
   315             dumpStream(process.getInputStream());
       
   316         } catch (IOException e) {
       
   317             System.err.println("Unable to display process output: " +
       
   318                                e.getMessage());
       
   319         }
       
   320     }
       
   321 
       
   322     /* launch child target vm */
       
   323     private VirtualMachine launchTarget() {
       
   324         LaunchingConnector launcher = (LaunchingConnector)connector;
       
   325         try {
       
   326             VirtualMachine vm = launcher.launch(connectorArgs);
       
   327             process = vm.process();
       
   328             displayRemoteOutput(process.getErrorStream());
       
   329             displayRemoteOutput(process.getInputStream());
       
   330             return vm;
       
   331         } catch (IOException ioe) {
       
   332             ioe.printStackTrace();
       
   333             System.err.println("\n Unable to launch target VM.");
       
   334         } catch (IllegalConnectorArgumentsException icae) {
       
   335             icae.printStackTrace();
       
   336             System.err.println("\n Internal debugger error.");
       
   337         } catch (VMStartException vmse) {
       
   338             System.err.println(vmse.getMessage() + "\n");
       
   339             dumpFailedLaunchInfo(vmse.process());
       
   340             System.err.println("\n Target VM failed to initialize.");
       
   341         }
       
   342         return null; // Shuts up the compiler
       
   343     }
       
   344 
       
   345     /* attach to running target vm */
       
   346     private VirtualMachine attachTarget() {
       
   347         AttachingConnector attacher = (AttachingConnector)connector;
       
   348         try {
       
   349             return attacher.attach(connectorArgs);
       
   350         } catch (IOException ioe) {
       
   351             ioe.printStackTrace();
       
   352             System.err.println("\n Unable to attach to target VM.");
       
   353         } catch (IllegalConnectorArgumentsException icae) {
       
   354             icae.printStackTrace();
       
   355             System.err.println("\n Internal debugger error.");
       
   356         }
       
   357         return null; // Shuts up the compiler
       
   358     }
       
   359 
       
   360     /* listen for connection from target vm */
       
   361     private VirtualMachine listenTarget() {
       
   362         ListeningConnector listener = (ListeningConnector)connector;
       
   363         try {
       
   364             String retAddress = listener.startListening(connectorArgs);
       
   365             System.out.println("Listening at address: " + retAddress);
       
   366             vm = listener.accept(connectorArgs);
       
   367             listener.stopListening(connectorArgs);
       
   368             return vm;
       
   369         } catch (IOException ioe) {
       
   370             ioe.printStackTrace();
       
   371             System.err.println("\n Unable to attach to target VM.");
       
   372         } catch (IllegalConnectorArgumentsException icae) {
       
   373             icae.printStackTrace();
       
   374             System.err.println("\n Internal debugger error.");
       
   375         }
       
   376         return null; // Shuts up the compiler
       
   377     }
       
   378 }