1 /* 2 * Copyright (c) 2005, 2014, 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 /* @test 25 * @bug 6306165 6432567 26 * @summary Check that a bad handshake doesn't cause a debuggee to abort 27 * @library /lib/testlibrary 28 * 29 * @build jdk.testlibrary.* VMConnection BadHandshakeTest Exit0 30 * @run main BadHandshakeTest 31 * 32 */ 33 import java.net.Socket; 34 import java.net.InetAddress; 35 import com.sun.jdi.Bootstrap; 36 import com.sun.jdi.VirtualMachine; 37 import com.sun.jdi.event.*; 38 import com.sun.jdi.connect.Connector; 39 import com.sun.jdi.connect.AttachingConnector; 40 import java.util.Map; 41 import java.util.List; 42 import java.util.Iterator; 43 import java.util.concurrent.TimeUnit; 44 import java.util.concurrent.atomic.AtomicBoolean; 45 46 import jdk.testlibrary.Utils; 47 import jdk.testlibrary.ProcessTools; 48 49 public class BadHandshakeTest { 50 /* 51 * Find a connector by name 52 */ 53 private static Connector findConnector(String name) { 54 List connectors = Bootstrap.virtualMachineManager().allConnectors(); 55 Iterator iter = connectors.iterator(); 56 while (iter.hasNext()) { 57 Connector connector = (Connector)iter.next(); 58 if (connector.name().equals(name)) { 59 return connector; 60 } 61 } 62 return null; 63 } 64 65 /* 66 * Launch a server debuggee with the given address 67 */ 68 private static Process launch(String address, String class_name) throws Exception { 69 String[] args = VMConnection.insertDebuggeeVMOptions(new String[] { 70 "-agentlib:jdwp=transport=dt_socket" + 71 ",server=y" + ",suspend=y" + ",address=" + address, 72 class_name 73 }); 74 75 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args); 76 77 final AtomicBoolean success = new AtomicBoolean(); 78 Process p = ProcessTools.startProcess( 79 class_name, 80 pb, 81 (line) -> { 82 // The first thing that will get read is 83 // Listening for transport dt_socket at address: xxxxx 84 // which shows the debuggee is ready to accept connections. 85 success.set(line.contains("Listening for transport dt_socket at address:")); 86 return true; 87 }, 88 Integer.MAX_VALUE, 89 TimeUnit.MILLISECONDS 90 ); 91 92 return success.get() ? p : null; 93 } 94 95 /* 96 * - pick a TCP port 97 * - Launch a server debuggee: server=y,suspend=y,address=${port} 98 * - run it to VM death 99 * - verify we saw no error 100 */ 101 public static void main(String args[]) throws Exception { 102 int port = Utils.getFreePort(); 103 104 String address = String.valueOf(port); 105 106 // launch the server debuggee 107 Process process = launch(address, "Exit0"); 108 if (process == null) { 109 throw new RuntimeException("Unable to start debugee"); 110 } 111 112 // Connect to the debuggee and handshake with garbage 113 Socket s = new Socket(InetAddress.getLocalHost(), port); 114 s.getOutputStream().write("Here's a poke in the eye".getBytes("UTF-8")); 115 s.close(); 116 117 // Re-connect and to a partial handshake - don't disconnect 118 s = new Socket(InetAddress.getLocalHost(), port); 119 s.getOutputStream().write("JDWP-".getBytes("UTF-8")); 120 121 122 // attach to server debuggee and resume it so it can exit 123 AttachingConnector conn = (AttachingConnector)findConnector("com.sun.jdi.SocketAttach"); 124 Map conn_args = conn.defaultArguments(); 125 Connector.IntegerArgument port_arg = 126 (Connector.IntegerArgument)conn_args.get("port"); 127 port_arg.setValue(port); 128 VirtualMachine vm = conn.attach(conn_args); 129 130 // The first event is always a VMStartEvent, and it is always in 131 // an EventSet by itself. Wait for it. 132 EventSet evtSet = vm.eventQueue().remove(); 133 for (Event event: evtSet) { 134 if (event instanceof VMStartEvent) { 135 break; 136 } 137 throw new RuntimeException("Test failed - debuggee did not start properly"); 138 } 139 140 vm.eventRequestManager().deleteAllBreakpoints(); 141 vm.resume(); 142 143 process.waitFor(); 144 } 145 146 }