-
Bug
-
Resolution: Fixed
-
P2
-
6u1
-
b14
-
sparc
-
solaris_2.5.1
-
Verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2149499 | 6u2 | Alan Bateman | P4 | Resolved | Fixed | b03 |
Calling the native method sun.tools.attach.WindowsVirtualMachine.enqueue() repeatedly will cause a leak of Windows handles returned by the call to CreateRemoteThread(). This can be shown by the following simple Java program.
This becomes a real problem when the attach framework is used to repeatedly try to attach to other JVMs in order to automatically discover them and their parameters, which is exactly what JRockit Mission Control 2.0 does since JRockit R27.1 and forward.
If the number of handles allocated by the Java process becomes too large, this will cause the Windows system to hang and become unresponsive.
Reproducer code:
package sun.tools.attach;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import sun.tools.attach.HotSpotVirtualMachine;
import sun.tools.attach.HotSpotVirtualMachineAccess;
import com.sun.tools.attach.AgentLoadException;
import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
public class AttachTester
{
public static void main(String[] args) throws AttachNotSupportedException, Exception, AgentLoadException
{
String pid = args[0];
int times = Integer.parseInt(args[1]);
int sleepmillis = Integer.parseInt(args[2]);
boolean executeCommand = Boolean.parseBoolean(args[3]);
for (int i = 0; i < times; i++)
{
Iterator it = VirtualMachine.list().iterator();
while (it.hasNext())
{
VirtualMachineDescriptor descriptor = (VirtualMachineDescriptor) it.next();
if (pid.equals(descriptor.id()))
{
System.out.println("Iteration " + i);
System.out.println("Attaching to pid " +pid);
VirtualMachine machine = VirtualMachine.attach(descriptor);
HotSpotVirtualMachine hvm = (HotSpotVirtualMachine) machine;
if (executeCommand)
{
InputStream in = HotSpotVirtualMachineAccess.execute(hvm, "printflag", "hello" );
byte b[] = new byte[256];
int n;
StringBuffer buf = new StringBuffer();
do
{
n = in.read(b);
if (n > 0)
{
String s = new String(b, 0, n, "UTF-8"); //$NON-NLS-1$
buf.append(s);
}
}
while (n > 0);
try
{
in.close();
}
catch (IOException ex)
{
System.out.println("Could not close stream.");
}
System.out.println(i + " " + buf.toString());
}
System.out.println("Detaching from pid " +pid);
machine.detach();
}
}
System.out.println("Sleeping "+ sleepmillis + " ms");
System.out.println();
System.out.println();
Thread.sleep(sleepmillis);
}
}
}
/**
* This class only exists because HotSpotVirtualMachine.execute() is made
* package-private by Sun.
*/
public class HotSpotVirtualMachineAccess
{
public static InputStream execute(HotSpotVirtualMachine vm, String cmd, Object ... args)
throws AgentLoadException, IOException
{
return vm.execute(cmd, args);
}
}
Note: <jdkhome>/lib/tools.jar must be in classpath in order for the test program to compile and to be executed.
Usage: java -cp <jdkhome>/lib/tools.jar;. sun.tools.attach.AttachTester 278 1200 10 false:
278 = pid of jvm to attach
1200 = number of iterations to run
10 = sleeptime between iterations
false = don't execute version command
This becomes a real problem when the attach framework is used to repeatedly try to attach to other JVMs in order to automatically discover them and their parameters, which is exactly what JRockit Mission Control 2.0 does since JRockit R27.1 and forward.
If the number of handles allocated by the Java process becomes too large, this will cause the Windows system to hang and become unresponsive.
Reproducer code:
package sun.tools.attach;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import sun.tools.attach.HotSpotVirtualMachine;
import sun.tools.attach.HotSpotVirtualMachineAccess;
import com.sun.tools.attach.AgentLoadException;
import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
public class AttachTester
{
public static void main(String[] args) throws AttachNotSupportedException, Exception, AgentLoadException
{
String pid = args[0];
int times = Integer.parseInt(args[1]);
int sleepmillis = Integer.parseInt(args[2]);
boolean executeCommand = Boolean.parseBoolean(args[3]);
for (int i = 0; i < times; i++)
{
Iterator it = VirtualMachine.list().iterator();
while (it.hasNext())
{
VirtualMachineDescriptor descriptor = (VirtualMachineDescriptor) it.next();
if (pid.equals(descriptor.id()))
{
System.out.println("Iteration " + i);
System.out.println("Attaching to pid " +pid);
VirtualMachine machine = VirtualMachine.attach(descriptor);
HotSpotVirtualMachine hvm = (HotSpotVirtualMachine) machine;
if (executeCommand)
{
InputStream in = HotSpotVirtualMachineAccess.execute(hvm, "printflag", "hello" );
byte b[] = new byte[256];
int n;
StringBuffer buf = new StringBuffer();
do
{
n = in.read(b);
if (n > 0)
{
String s = new String(b, 0, n, "UTF-8"); //$NON-NLS-1$
buf.append(s);
}
}
while (n > 0);
try
{
in.close();
}
catch (IOException ex)
{
System.out.println("Could not close stream.");
}
System.out.println(i + " " + buf.toString());
}
System.out.println("Detaching from pid " +pid);
machine.detach();
}
}
System.out.println("Sleeping "+ sleepmillis + " ms");
System.out.println();
System.out.println();
Thread.sleep(sleepmillis);
}
}
}
/**
* This class only exists because HotSpotVirtualMachine.execute() is made
* package-private by Sun.
*/
public class HotSpotVirtualMachineAccess
{
public static InputStream execute(HotSpotVirtualMachine vm, String cmd, Object ... args)
throws AgentLoadException, IOException
{
return vm.execute(cmd, args);
}
}
Note: <jdkhome>/lib/tools.jar must be in classpath in order for the test program to compile and to be executed.
Usage: java -cp <jdkhome>/lib/tools.jar;. sun.tools.attach.AttachTester 278 1200 10 false:
278 = pid of jvm to attach
1200 = number of iterations to run
10 = sleeptime between iterations
false = don't execute version command
- backported by
-
JDK-2149499 Attach mechanism leaks tool-side handle per command
-
- Resolved
-