1 /* 2 * Copyright (c) 2007, 2018, 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 package nsk.jdi.AttachingConnector.attachnosuspend; 25 26 import com.sun.jdi.Bootstrap; 27 import com.sun.jdi.connect.*; 28 import com.sun.jdi.VirtualMachine; 29 import com.sun.jdi.ReferenceType; 30 31 import java.io.*; 32 33 import java.util.Iterator; 34 import java.util.List; 35 import java.util.Map; 36 37 import nsk.share.*; 38 import nsk.share.jpda.*; 39 import nsk.share.jdi.*; 40 41 42 /** 43 * The test checks that debugger may establish connection with 44 * a target VM via <code>com.sun.jdi.SocketAttach</code> connector. 45 */ 46 public class attachnosuspend001 { 47 static final int PASSED = 0; 48 static final int FAILED = 2; 49 static final int JCK_STATUS_BASE = 95; 50 static final String DEBUGEE_CLASS = 51 "nsk.jdi.AttachingConnector.attachnosuspend.attachnosuspend001t"; 52 53 private Log log; 54 55 private VirtualMachine vm; 56 57 private int attempts; // attempts to connect to the debugee VM 58 private int delay = 4000; // delay between connection attempts 59 60 IORedirector outRedirector; 61 IORedirector errRedirector; 62 main(String argv[])63 public static void main (String argv[]) { 64 System.exit(run(argv,System.out) + JCK_STATUS_BASE); 65 } 66 run(String argv[], PrintStream out)67 public static int run(String argv[], PrintStream out) { 68 return new attachnosuspend001().runIt(argv, out); 69 } 70 runIt(String argv[], PrintStream out)71 private int runIt(String argv[], PrintStream out) { 72 String port; 73 String listenPort; 74 Process proc; 75 ArgumentHandler argHandler = new ArgumentHandler(argv); 76 77 // pass if "com.sun.jdi.SocketAttach" is not implemented 78 // on this platform 79 if (argHandler.shouldPass("com.sun.jdi.SocketAttach")) 80 return PASSED; 81 82 log = new Log(out, argHandler); 83 84 String args[] = argHandler.getArguments(); 85 86 // treat second positional argument as delay between connection attempts 87 try { 88 delay = Integer.parseInt(args[1]); 89 } catch (NumberFormatException e) { 90 log.complain("Incorrect test parameter: timeout value must be an integer"); 91 return FAILED; 92 } catch (ArrayIndexOutOfBoundsException e) { 93 // ignore: default delay will be used if no second argument present 94 } 95 // calculate number of connection attempts to not exceed WAITTIME 96 long timeout = argHandler.getWaitTime() * 60 * 1000; 97 attempts = (int)(timeout / delay); 98 99 port = argHandler.getTransportPort(); 100 listenPort = argHandler.getTransportPort(); 101 102 String java = argHandler.getLaunchExecPath() 103 + " " + argHandler.getLaunchOptions(); 104 String cmd = java + 105 " -Xdebug -Xnoagent -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=" + 106 listenPort + " " + DEBUGEE_CLASS; 107 108 Binder binder = new Binder(argHandler, log); 109 log.display("command: " + cmd); 110 Debugee debugee = binder.startLocalDebugee(cmd); 111 debugee.redirectOutput(log); 112 113 if ((vm = attachTarget(argHandler.getTestHost(), port)) == null) { 114 log.complain("TEST: Unable to attach the debugee VM"); 115 debugee.close(); 116 return FAILED; 117 } 118 119 log.display("debugee VM: name=" + vm.name() + " JRE version=" + 120 vm.version() + "\n\tdescription=" + vm.description()); 121 122 debugee.setupVM(vm); 123 //debugee.waitForVMInit(timeout); 124 125 //log.display("\nresuming debugee VM"); 126 //debugee.resume(); 127 128 log.display("\nwaiting for debugee VM exit"); 129 int code = debugee.waitFor(); 130 if (code != (JCK_STATUS_BASE+PASSED)) { 131 log.complain("Debugee VM has crashed: exit code=" + 132 code); 133 return FAILED; 134 } 135 log.display("debugee VM: exit code=" + code); 136 return PASSED; 137 } 138 attachTarget(String host, String port)139 private VirtualMachine attachTarget(String host, String port) { 140 Connector.Argument arg; 141 142 if (port == null) { 143 log.complain("TEST: port number is required!"); 144 return null; 145 } 146 147 AttachingConnector connector = 148 (AttachingConnector) findConnector("com.sun.jdi.SocketAttach"); 149 150 Map<java.lang.String,? extends com.sun.jdi.connect.Connector.Argument> cArgs = connector.defaultArguments(); 151 Iterator cArgsValIter = cArgs.keySet().iterator(); 152 while (cArgsValIter.hasNext()) { 153 String argKey = (String) cArgsValIter.next(); 154 String argVal = null; 155 156 if ((arg = (Connector.Argument) cArgs.get(argKey)) == null) { 157 log.complain("Argument " + argKey.toString() + 158 "is not defined for the connector: " + connector.name()); 159 } 160 if (arg.name().equals("hostname") && host != null) 161 arg.setValue(host); 162 if (arg.name().equals("port")) 163 arg.setValue(port); 164 165 log.display("\targument name=" + arg.name()); 166 if ((argVal = arg.value()) != null) 167 log.display("\t\tvalue="+argVal); 168 else log.display("\t\tvalue=NULL"); 169 } 170 171 // make several attemts to connect to the debugee VM until WAITTIME exceeds 172 for (int i = 0; i < attempts; i++) { 173 try { 174 return connector.attach(cArgs); 175 } catch (IOException e) { 176 // could not connect; sleep a few and make new attempt 177 log.display("Connection attempt #" + i + " failed: " + e); 178 try { 179 Thread.currentThread().sleep(delay); 180 } catch (InterruptedException ie) { 181 log.complain("TEST INCOMPLETE: interrupted sleep: " + ie); 182 } 183 } catch (IllegalConnectorArgumentsException e) { 184 log.complain("TEST: Illegal connector arguments: " + 185 e.getMessage()); 186 return null; 187 } catch (Exception e) { 188 log.complain("TEST: Internal error: " + e.getMessage()); 189 return null; 190 } 191 } 192 // return null after all attempts failed 193 log.complain("FAILURE: all attempts to connect to the debugee VM failed"); 194 return null; 195 } 196 findConnector(String connectorName)197 private Connector findConnector(String connectorName) { 198 List connectors = Bootstrap.virtualMachineManager().allConnectors(); 199 Iterator iter = connectors.iterator(); 200 201 while (iter.hasNext()) { 202 Connector connector = (Connector) iter.next(); 203 if (connector.name().equals(connectorName)) { 204 log.display("Connector name=" + connector.name() + 205 "\n\tdescription=" + connector.description() + 206 "\n\ttransport=" + connector.transport().name()); 207 return connector; 208 } 209 } 210 throw new Error("No appropriate connector"); 211 } 212 } 213