mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-17 17:07:53 +00:00
8046883: com/sun/jdi/ProcessAttachTest.sh gets "java.io.IOException: Invalid process identifier" on windows
Reviewed-by: dcubed, dsamersoff, allwin
This commit is contained in:
parent
463b504956
commit
0139a3b9e7
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
* The "debuggee" used by the unit tests for the ProcessAttachingConnector.
|
||||
* This debuggee binds to a random TCP port and waits for a client to connect.
|
||||
*/
|
||||
import java.net.Socket;
|
||||
import java.net.ServerSocket;
|
||||
import java.nio.file.CopyOption;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
public class ProcessAttachDebuggee {
|
||||
public static void main(String args[]) throws Exception {
|
||||
// bind to a random port
|
||||
ServerSocket ss = new ServerSocket(0);
|
||||
int port = ss.getLocalPort();
|
||||
|
||||
// Write the port number to the given file
|
||||
File partial = new File(args[0] + ".partial");
|
||||
File portFile = new File(args[0]);
|
||||
try (FileOutputStream fos = new FileOutputStream(partial)) {
|
||||
fos.write( Integer.toString(port).getBytes("UTF-8") );
|
||||
}
|
||||
Files.move(partial.toPath(), portFile.toPath(), StandardCopyOption.ATOMIC_MOVE);
|
||||
|
||||
System.out.println("Debuggee bound to port: " + port);
|
||||
System.out.flush();
|
||||
|
||||
// wait for test harness to connect
|
||||
Socket s = ss.accept();
|
||||
s.close();
|
||||
ss.close();
|
||||
|
||||
System.out.println("Debuggee shutdown.");
|
||||
}
|
||||
}
|
||||
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Unit test for ProcessAttachingConnector - this "debugger" attaches to a debuggee
|
||||
* given it's pid. Usage:
|
||||
*
|
||||
* java ProcessAttachDebugger <pid>
|
||||
*/
|
||||
|
||||
import com.sun.jdi.Bootstrap;
|
||||
import com.sun.jdi.VirtualMachine;
|
||||
import com.sun.jdi.ThreadReference;
|
||||
import com.sun.jdi.connect.Connector;
|
||||
import com.sun.jdi.connect.AttachingConnector;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ProcessAttachDebugger {
|
||||
|
||||
public static void main(String main_args[]) throws Exception {
|
||||
String pid = main_args[0];
|
||||
|
||||
// find ProcessAttachingConnector
|
||||
|
||||
List<AttachingConnector> l =
|
||||
Bootstrap.virtualMachineManager().attachingConnectors();
|
||||
AttachingConnector ac = null;
|
||||
for (AttachingConnector c: l) {
|
||||
if (c.name().equals("com.sun.jdi.ProcessAttach")) {
|
||||
ac = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ac == null) {
|
||||
throw new RuntimeException("Unable to locate ProcessAttachingConnector");
|
||||
}
|
||||
|
||||
Map<String,Connector.Argument> args = ac.defaultArguments();
|
||||
Connector.StringArgument arg = (Connector.StringArgument)args.get("pid");
|
||||
arg.setValue(pid);
|
||||
|
||||
System.out.println("Debugger is attaching to: " + pid + " ...");
|
||||
|
||||
VirtualMachine vm = ac.attach(args);
|
||||
|
||||
System.out.println("Attached! Now listing threads ...");
|
||||
|
||||
// list all threads
|
||||
|
||||
for (ThreadReference thr: vm.allThreads()) {
|
||||
System.out.println(thr);
|
||||
}
|
||||
|
||||
System.out.println("Debugger done.");
|
||||
}
|
||||
|
||||
}
|
||||
116
jdk/test/com/sun/jdi/ProcessAttachTest.java
Normal file
116
jdk/test/com/sun/jdi/ProcessAttachTest.java
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import jdk.testlibrary.ProcessTools;
|
||||
|
||||
import com.sun.jdi.Bootstrap;
|
||||
import com.sun.jdi.ThreadReference;
|
||||
import com.sun.jdi.VirtualMachine;
|
||||
import com.sun.jdi.connect.AttachingConnector;
|
||||
import com.sun.jdi.connect.Connector;
|
||||
import com.sun.jdi.connect.IllegalConnectorArgumentsException;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 4527279
|
||||
* @summary Unit test for ProcessAttachingConnector
|
||||
*
|
||||
* @library /lib/testlibrary
|
||||
* @build jdk.testlibrary.* ProcessAttachTest
|
||||
* @run driver ProcessAttachTest
|
||||
*/
|
||||
|
||||
class ProcessAttachTestTarg {
|
||||
public static void main(String args[]) throws Exception {
|
||||
// Write something that can be read by the driver
|
||||
System.out.println("Debuggee started");
|
||||
System.out.flush();
|
||||
for (;;) {
|
||||
Thread.sleep(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ProcessAttachTest {
|
||||
|
||||
public static final String TESTCLASSES = System.getProperty("test.classes");
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
System.out.println("Test 1: Debuggee start with suspend=n");
|
||||
runTest("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n");
|
||||
|
||||
System.out.println("Test 2: Debuggee start with suspend=y");
|
||||
runTest("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y");
|
||||
|
||||
}
|
||||
|
||||
private static void runTest(String jdwpArg) throws Exception {
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
|
||||
jdwpArg,
|
||||
"-classpath", TESTCLASSES,
|
||||
"ProcessAttachTestTarg");
|
||||
Process p = null;
|
||||
try {
|
||||
p = pb.start();
|
||||
|
||||
// Wait for the process to start
|
||||
InputStream is = p.getInputStream();
|
||||
is.read();
|
||||
|
||||
// Attach a debugger
|
||||
tryDebug(p.getPid());
|
||||
} finally {
|
||||
p.destroyForcibly();
|
||||
}
|
||||
}
|
||||
|
||||
private static void tryDebug(long pid) throws IOException,
|
||||
IllegalConnectorArgumentsException {
|
||||
AttachingConnector ac = Bootstrap.virtualMachineManager().attachingConnectors()
|
||||
.stream()
|
||||
.filter(c -> c.name().equals("com.sun.jdi.ProcessAttach"))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new RuntimeException("Unable to locate ProcessAttachingConnector"));
|
||||
|
||||
Map<String, Connector.Argument> args = ac.defaultArguments();
|
||||
Connector.StringArgument arg = (Connector.StringArgument) args
|
||||
.get("pid");
|
||||
arg.setValue("" + pid);
|
||||
|
||||
System.out.println("Debugger is attaching to: " + pid + " ...");
|
||||
VirtualMachine vm = ac.attach(args);
|
||||
|
||||
// list all threads
|
||||
System.out.println("Attached! Now listing threads ...");
|
||||
vm.allThreads().stream().forEach(System.out::println);
|
||||
|
||||
System.out.println("Debugger done.");
|
||||
vm.dispose();
|
||||
}
|
||||
}
|
||||
@ -1,199 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
|
||||
# @test
|
||||
# @bug 4527279
|
||||
# @summary Unit test for ProcessAttachingConnector
|
||||
#
|
||||
# @build ProcessAttachDebugger ProcessAttachDebuggee ShutdownDebuggee
|
||||
# @run shell/timeout=120 ProcessAttachTest.sh
|
||||
|
||||
if [ "${TESTJAVA}" = "" ]
|
||||
then
|
||||
echo "TESTJAVA not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${TESTSRC}" = "" ]
|
||||
then
|
||||
echo "TESTSRC not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${TESTCLASSES}" = "" ]
|
||||
then
|
||||
echo "TESTCLASSES not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
JAVA="${TESTJAVA}/bin/java"
|
||||
|
||||
OS=`uname -s`
|
||||
|
||||
case "$OS" in
|
||||
Windows*)
|
||||
PS=";"
|
||||
OS="Windows"
|
||||
;;
|
||||
CYGWIN*)
|
||||
PS=";"
|
||||
OS="CYGWIN"
|
||||
;;
|
||||
* )
|
||||
PS=":"
|
||||
;;
|
||||
esac
|
||||
|
||||
startDebuggee()
|
||||
{
|
||||
rm -f ${OUTPUTFILE}
|
||||
${JAVA} "$@" > ${OUTPUTFILE} 2>&1 &
|
||||
startpid="$!"
|
||||
pid="${startpid}"
|
||||
|
||||
# CYGWIN startpid is not the native windows PID we want, get the WINPID
|
||||
if [ "${OS}" = "CYGWIN" ]; then
|
||||
sleep 2
|
||||
ps -l -p ${startpid}
|
||||
pid=`ps -l -p ${startpid} | tail -1 | awk '{print $4;}'`
|
||||
fi
|
||||
|
||||
# MKS creates an intermediate shell to launch ${JAVA} so
|
||||
# ${startpid} is not the actual pid. We have put in a small sleep
|
||||
# to give the intermediate shell process time to launch the
|
||||
# "java" process.
|
||||
if [ "$OS" = "Windows" ]; then
|
||||
sleep 2
|
||||
pid=`ps -o pid,ppid,comm | awk '/${startpid}.+java/{ print $1 }'`
|
||||
fi
|
||||
|
||||
echo "Waiting for Debuggee to initialize..."
|
||||
attempts=0
|
||||
while true; do
|
||||
out=`tail -1 ${OUTPUTFILE}`
|
||||
if [ ! -z "$out" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
attempts=`expr $attempts + 1`
|
||||
echo "Waiting $attempts second(s) ..."
|
||||
done
|
||||
|
||||
echo "Debuggee is process $pid (startpid=${startpid})"
|
||||
}
|
||||
|
||||
stopDebuggee()
|
||||
{
|
||||
# We have to make sure the debuggee has written the portfile before
|
||||
# trying to read it.
|
||||
|
||||
echo "Waiting for port file to be written..."
|
||||
attempts=0
|
||||
while true; do
|
||||
attempts=`expr $attempts + 1`
|
||||
if [ -f ${PORTFILE} ]; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
echo "Waiting $attempts second(s) ..."
|
||||
done
|
||||
|
||||
$JAVA -classpath "${TESTCLASSES}" ShutdownDebuggee $1 2>&1
|
||||
if [ $? != 0 ] ; then
|
||||
echo "Error: ShutdownDebuggee failed: $?"
|
||||
failures=`expr $failures + 1`
|
||||
kill -9 ${startpid}
|
||||
fi
|
||||
}
|
||||
|
||||
failures=0
|
||||
|
||||
#########################################################
|
||||
echo "Test 1: Debuggee start with suspend=n"
|
||||
|
||||
PORTFILE=shutdown1.port
|
||||
OUTPUTFILE=Debuggee1.out
|
||||
|
||||
DEBUGGEEFLAGS=
|
||||
if [ -r $TESTCLASSES/@debuggeeVMOptions ] ; then
|
||||
DEBUGGEEFLAGS=`cat $TESTCLASSES/@debuggeeVMOptions`
|
||||
elif [ -r $TESTCLASSES/../@debuggeeVMOptions ] ; then
|
||||
DEBUGGEEFLAGS=`cat $TESTCLASSES/../@debuggeeVMOptions`
|
||||
fi
|
||||
|
||||
startDebuggee \
|
||||
$DEBUGGEEFLAGS \
|
||||
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n \
|
||||
-classpath "${TESTCLASSES}" ProcessAttachDebuggee "${PORTFILE}"
|
||||
|
||||
$JAVA -classpath "${TESTCLASSES}${PS}${TESTJAVA}/lib/tools.jar" \
|
||||
ProcessAttachDebugger $pid 2>&1
|
||||
|
||||
if [ $? != 0 ]; then
|
||||
echo "Error: ProcessAttachDebugger failed: $?"
|
||||
failures=`expr $failures + 1`
|
||||
fi
|
||||
|
||||
# Note that when the debugger disconnects, the debuggee picks another
|
||||
# port and outputs another 'Listening for transport ... ' msg.
|
||||
|
||||
stopDebuggee "${PORTFILE}"
|
||||
|
||||
echo "${OUTPUTFILE}:"
|
||||
cat $OUTPUTFILE
|
||||
echo "-----"
|
||||
|
||||
#########################################################
|
||||
echo "\nTest 2: Debuggee start with suspend=y"
|
||||
|
||||
PORTFILE=shutdown2.port
|
||||
OUTPUTFILE=Debuggee2.out
|
||||
|
||||
startDebuggee \
|
||||
$DEBUGGEEFLAGS \
|
||||
-agentlib:jdwp=transport=dt_socket,server=y,suspend=y \
|
||||
-classpath "${TESTCLASSES}" ProcessAttachDebuggee "${PORTFILE}"
|
||||
|
||||
$JAVA -classpath "${TESTCLASSES}${PS}${TESTJAVA}/lib/tools.jar" \
|
||||
ProcessAttachDebugger $pid 2>&1
|
||||
|
||||
if [ $? != 0 ]; then
|
||||
echo "Error: ProcessAttachDebugger failed: $?"
|
||||
failures=`expr $failures + 1`
|
||||
fi
|
||||
|
||||
stopDebuggee "${PORTFILE}"
|
||||
|
||||
echo $OUTPUTFILE :
|
||||
cat $OUTPUTFILE
|
||||
echo -----
|
||||
|
||||
###
|
||||
if [ $failures = 0 ];
|
||||
then echo "All tests passed.";
|
||||
else echo "$failures test(s) failed."
|
||||
fi
|
||||
exit $failures
|
||||
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Used by the unit tests for the ProcessAttachingConnector. This class is
|
||||
* used to shutdown the debuggee by connecting to its shutdown port.
|
||||
*/
|
||||
import java.net.Socket;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
||||
public class ShutdownDebuggee {
|
||||
public static void main(String args[]) throws Exception {
|
||||
|
||||
// read the (TCP) port number from the given file
|
||||
|
||||
File f = new File(args[0]);
|
||||
FileInputStream fis = new FileInputStream(f);
|
||||
byte b[] = new byte[8];
|
||||
int n = fis.read(b);
|
||||
if (n < 1) {
|
||||
throw new RuntimeException("Empty file");
|
||||
}
|
||||
fis.close();
|
||||
|
||||
String str = new String(b, 0, n, "UTF-8");
|
||||
System.out.println("Port number of debuggee is: " + str);
|
||||
int port = Integer.parseInt(str);
|
||||
|
||||
// Now connect to the port (which will shutdown debuggee)
|
||||
|
||||
System.out.println("Connecting to port " + port +
|
||||
" to shutdown Debuggee ...");
|
||||
|
||||
Socket s = new Socket();
|
||||
s.connect( new InetSocketAddress(port) );
|
||||
s.close();
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user