Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/agent/test/jdi/VMConnection.java
38764 views
/*1* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324import com.sun.jdi.*;25import com.sun.jdi.connect.*;26import com.sun.jdi.request.EventRequestManager;2728import java.util.*;29import java.io.*;303132/**33* Manages a VM conection for the JDI test framework.34*/35class VMConnection {36private VirtualMachine vm;37private Process process = null;38private int outputCompleteCount = 0;3940private final Connector connector;41private final Map connectorArgs;42private final int traceFlags;4344/**45* Return a String containing VM Options to pass to the debugee46* or an empty string if there are none.47* These are read from the first non-comment line48* in file test/com/sun/jdi/@debuggeeVMOptions.49*/50static public String getDebuggeeVMOptions() {5152// When we run under jtreg, test.src contains the pathname of53// the test/com/sun/jdi dir.54BufferedReader reader;55final String filename = "@debuggeeVMOptions";56String srcDir = System.getProperty("test.src");5758if (srcDir == null) {59srcDir = System.getProperty("user.dir");60}61srcDir = srcDir + File.separator;6263File myDir = new File(srcDir);6465File myFile = new File(myDir, filename);66if (!myFile.canRead()) {67try {68// We have some subdirs of test/com/sun/jdi so in case we69// are in one of them, look in our parent dir for the file.70myFile = new File(myDir.getCanonicalFile().getParent(),71filename);72if (!myFile.canRead()) {73return "";74}75} catch (IOException ee) {76System.out.println("-- Error 1 trying to access file " +77myFile.getPath() + ": " + ee);78return "";79}80}81String wholePath = myFile.getPath();82try {83reader = new BufferedReader(new FileReader(myFile));84} catch (FileNotFoundException ee) {85System.out.println("-- Error 2 trying to access file " +86wholePath + ": " + ee);87return "";88}8990String line;91String retVal = "";92while (true) {93try {94line = reader.readLine();95} catch (IOException ee) {96System.out.println("-- Error reading options from file " +97wholePath + ": " + ee);98break;99}100if (line == null) {101System.out.println("-- No debuggee VM options found in file " +102wholePath);103break;104}105line = line.trim();106if (line.length() != 0 && !line.startsWith("#")) {107System.out.println("-- Added debuggeeVM options from file " +108wholePath + ": " + line);109retVal = line;110break;111}112// Else, read he next line.113}114try {115reader.close();116} catch (IOException ee) {117}118return retVal;119}120121private Connector findConnector(String name) {122List connectors = Bootstrap.virtualMachineManager().allConnectors();123Iterator iter = connectors.iterator();124while (iter.hasNext()) {125Connector connector = (Connector)iter.next();126if (connector.name().equals(name)) {127return connector;128}129}130return null;131}132133private Map parseConnectorArgs(Connector connector, String argString) {134StringTokenizer tokenizer = new StringTokenizer(argString, ",");135Map arguments = connector.defaultArguments();136137while (tokenizer.hasMoreTokens()) {138String token = tokenizer.nextToken();139int index = token.indexOf('=');140if (index == -1) {141throw new IllegalArgumentException("Illegal connector argument: " +142token);143}144String name = token.substring(0, index);145String value = token.substring(index + 1);146Connector.Argument argument = (Connector.Argument)arguments.get(name);147if (argument == null) {148throw new IllegalArgumentException("Argument " + name +149"is not defined for connector: " +150connector.name());151}152argument.setValue(value);153}154return arguments;155}156157VMConnection(String connectSpec, int traceFlags) {158String nameString;159String argString;160int index = connectSpec.indexOf(':');161if (index == -1) {162nameString = connectSpec;163argString = "";164} else {165nameString = connectSpec.substring(0, index);166argString = connectSpec.substring(index + 1);167}168169connector = findConnector(nameString);170if (connector == null) {171throw new IllegalArgumentException("No connector named: " +172nameString);173}174175connectorArgs = parseConnectorArgs(connector, argString);176this.traceFlags = traceFlags;177}178179synchronized VirtualMachine open() {180if (connector instanceof LaunchingConnector) {181vm = launchTarget();182} else if (connector instanceof AttachingConnector) {183vm = attachTarget();184} else if (connector instanceof ListeningConnector) {185vm = listenTarget();186} else {187throw new InternalError("Invalid connect type");188}189vm.setDebugTraceMode(traceFlags);190System.out.println("JVM version:" + vm.version());191System.out.println("JDI version: " + Bootstrap.virtualMachineManager().majorInterfaceVersion() +192"." + Bootstrap.virtualMachineManager().minorInterfaceVersion());193System.out.println("JVM description: " + vm.description());194195return vm;196}197198boolean setConnectorArg(String name, String value) {199/*200* Too late if the connection already made201*/202if (vm != null) {203return false;204}205206Connector.Argument argument = (Connector.Argument)connectorArgs.get(name);207if (argument == null) {208return false;209}210argument.setValue(value);211return true;212}213214String connectorArg(String name) {215Connector.Argument argument = (Connector.Argument)connectorArgs.get(name);216if (argument == null) {217return "";218}219return argument.value();220}221222public synchronized VirtualMachine vm() {223if (vm == null) {224throw new InternalError("VM not connected");225} else {226return vm;227}228}229230boolean isOpen() {231return (vm != null);232}233234boolean isLaunch() {235return (connector instanceof LaunchingConnector);236}237238Connector connector() {239return connector;240}241242boolean isListen() {243return (connector instanceof ListeningConnector);244}245246boolean isAttach() {247return (connector instanceof AttachingConnector);248}249250private synchronized void notifyOutputComplete() {251outputCompleteCount++;252notifyAll();253}254255private synchronized void waitOutputComplete() {256// Wait for stderr and stdout257if (process != null) {258while (outputCompleteCount < 2) {259try {wait();} catch (InterruptedException e) {}260}261}262}263264public void disposeVM() {265try {266if (vm != null) {267vm.dispose();268vm = null;269}270} finally {271if (process != null) {272process.destroy();273process = null;274}275waitOutputComplete();276}277}278279private void dumpStream(InputStream stream) throws IOException {280PrintStream outStream = System.out;281BufferedReader in =282new BufferedReader(new InputStreamReader(stream));283String line;284while ((line = in.readLine()) != null) {285outStream.println(line);286}287}288289/**290* Create a Thread that will retrieve and display any output.291* Needs to be high priority, else debugger may exit before292* it can be displayed.293*/294private void displayRemoteOutput(final InputStream stream) {295Thread thr = new Thread("output reader") {296public void run() {297try {298dumpStream(stream);299} catch (IOException ex) {300System.err.println("IOException reading output of child java interpreter:"301+ ex.getMessage());302} finally {303notifyOutputComplete();304}305}306};307thr.setPriority(Thread.MAX_PRIORITY-1);308thr.start();309}310311private void dumpFailedLaunchInfo(Process process) {312try {313dumpStream(process.getErrorStream());314dumpStream(process.getInputStream());315} catch (IOException e) {316System.err.println("Unable to display process output: " +317e.getMessage());318}319}320321/* launch child target vm */322private VirtualMachine launchTarget() {323LaunchingConnector launcher = (LaunchingConnector)connector;324try {325VirtualMachine vm = launcher.launch(connectorArgs);326process = vm.process();327displayRemoteOutput(process.getErrorStream());328displayRemoteOutput(process.getInputStream());329return vm;330} catch (IOException ioe) {331ioe.printStackTrace();332System.err.println("\n Unable to launch target VM.");333} catch (IllegalConnectorArgumentsException icae) {334icae.printStackTrace();335System.err.println("\n Internal debugger error.");336} catch (VMStartException vmse) {337System.err.println(vmse.getMessage() + "\n");338dumpFailedLaunchInfo(vmse.process());339System.err.println("\n Target VM failed to initialize.");340}341return null; // Shuts up the compiler342}343344/* attach to running target vm */345private VirtualMachine attachTarget() {346AttachingConnector attacher = (AttachingConnector)connector;347try {348return attacher.attach(connectorArgs);349} catch (IOException ioe) {350ioe.printStackTrace();351System.err.println("\n Unable to attach to target VM.");352} catch (IllegalConnectorArgumentsException icae) {353icae.printStackTrace();354System.err.println("\n Internal debugger error.");355}356return null; // Shuts up the compiler357}358359/* listen for connection from target vm */360private VirtualMachine listenTarget() {361ListeningConnector listener = (ListeningConnector)connector;362try {363String retAddress = listener.startListening(connectorArgs);364System.out.println("Listening at address: " + retAddress);365vm = listener.accept(connectorArgs);366listener.stopListening(connectorArgs);367return vm;368} catch (IOException ioe) {369ioe.printStackTrace();370System.err.println("\n Unable to attach to target VM.");371} catch (IllegalConnectorArgumentsException icae) {372icae.printStackTrace();373System.err.println("\n Internal debugger error.");374}375return null; // Shuts up the compiler376}377}378379380