agent/test/jdi/VMConnection.java

Thu, 27 May 2010 19:08:38 -0700

author
trims
date
Thu, 27 May 2010 19:08:38 -0700
changeset 1907
c18cbe5936b8
parent 435
a61af66fc99e
child 6876
710a3c8b516e
permissions
-rw-r--r--

6941466: Oracle rebranding changes for Hotspot repositories
Summary: Change all the Sun copyrights to Oracle copyright
Reviewed-by: ohair

     1 /*
     2  * Copyright (c) 2002, 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  */
    25 import com.sun.jdi.*;
    26 import com.sun.jdi.connect.*;
    27 import com.sun.jdi.request.EventRequestManager;
    29 import java.util.*;
    30 import java.io.*;
    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;
    41     private final Connector connector;
    42     private final Map connectorArgs;
    43     private final int traceFlags;
    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() {
    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");
    59         if (srcDir == null) {
    60           srcDir = System.getProperty("user.dir");
    61         }
    62         srcDir = srcDir + File.separator;
    64         File myDir = new File(srcDir);
    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         }
    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     }
   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     }
   134     private Map parseConnectorArgs(Connector connector, String argString) {
   135         StringTokenizer tokenizer = new StringTokenizer(argString, ",");
   136         Map arguments = connector.defaultArguments();
   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     }
   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         }
   170         connector = findConnector(nameString);
   171         if (connector == null) {
   172             throw new IllegalArgumentException("No connector named: " +
   173                                                nameString);
   174         }
   176         connectorArgs = parseConnectorArgs(connector, argString);
   177         this.traceFlags = traceFlags;
   178     }
   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());
   196         return vm;
   197     }
   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         }
   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     }
   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     }
   223     public synchronized VirtualMachine vm() {
   224         if (vm == null) {
   225             throw new InternalError("VM not connected");
   226         } else {
   227             return vm;
   228         }
   229     }
   231     boolean isOpen() {
   232         return (vm != null);
   233     }
   235     boolean isLaunch() {
   236         return (connector instanceof LaunchingConnector);
   237     }
   239     Connector connector() {
   240         return connector;
   241     }
   243     boolean isListen() {
   244         return (connector instanceof ListeningConnector);
   245     }
   247     boolean isAttach() {
   248         return (connector instanceof AttachingConnector);
   249     }
   251     private synchronized void notifyOutputComplete() {
   252         outputCompleteCount++;
   253         notifyAll();
   254     }
   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     }
   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     }
   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     }
   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     }
   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     }
   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     }
   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     }
   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 }

mercurial