Building a profiler of my own, I use the JVMTI API to build a native library agent. This agent can be started together with the JVM by using the addition parameter -agentlib. In addition there is the Attach API which allows to inject an agent into a running JVM. I wanted to implement this feature to my profiler using the following code:
try {
String pid = VirtualMachine.list().get(0).id();
VirtualMachine vm = VirtualMachine.attach(pid);
vm.loadAgentLibrary("agent");
} catch (AgentLoadException e1) {
e1.printStackTrace();
} catch (AgentInitializationException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} catch (AttachNotSupportedException e) {
e.printStackTrace();
}
What does it do? From all the available running virtual machines (VirtualMachine.list()
) I choose the first one, attach to it and try to load my agent into it. The agent, on UNIX systems named libagent.so, can be found, but when trying to load the agent the following exception is thrown:
com.sun.tools.attach.AttachNotSupportedException:
Unable to open socket file:
target process not responding or HotSpot VM not loaded.
Looking into the source code, this exception is thrown, because it cannot find a file named .java_pid<pid>
. I haven't found a lot information about this kind of file in the documentation. I often heard this kind of file is not used anymore, but I am running Java 1.6.
I also tried to attach to other JVMs, in fact I kept this attaching process dynamic, for testing reasons I just try to attach to any JVM.
This is the code which leads to the exception, taken from sun.tools.attach: LinuxVirtualMachine.java:
// Return the socket file for the given process.
// Checks working directory of process for .java_pid<pid>. If not
// found it looks in /tmp.
private String findSocketFile(int pid) {
// First check for a .java_pid<pid> file in the working directory
// of the target process
String fn = ".java_pid" + pid;
String path = "/proc/" + pid + "/cwd/" + fn;
File f = new File(path);
if (!f.exists()) {
// Not found, so try /tmp
path = "/tmp/" + fn;
f = new File(path);
if (!f.exists()) {
return null; // not found
}
}
return path;
}
It says, it is looking from root into the /proc/<pid>
directory. Looking at a changeset of the JDK7 it seems they are making changes to the code JDK7 Changeset to LinuxVirtualMachine