AttachNotSupported由于 Attach API 中缺少java_pid文件而导致的异常
构建自己的探查器,我使用 JVMTI API 构建本机库代理。此代理程序可以通过使用 add 参数 -agentlib 与 JVM 一起启动。此外,还有 Attach API,它允许将代理注入到正在运行的 JVM 中。我想使用以下代码将此功能实现到我的探查器:
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();
}
它有什么作用?从所有可用的正在运行的虚拟机()中,我选择第一个虚拟机,附加到它并尝试将我的代理加载到其中。可以在名为 libagent.so 的 UNIX 系统上找到代理程序,但在尝试加载代理程序时,将引发以下异常:VirtualMachine.list()
com.sun.tools.attach.AttachNotSupportedException:
Unable to open socket file:
target process not responding or HotSpot VM not loaded.
查看源代码,会引发此异常,因为它找不到名为 .我没有在文档中找到有关此类文件的很多信息。我经常听说这种文件不再使用,但我运行的是Java 1.6。.java_pid<pid>
我还尝试附加到其他JVM,实际上我保持了这个附加过程动态,出于测试原因,我只是尝试附加到任何JVM。
这是导致异常的代码,取自 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;
}
它说,它正在从根目录查看。看看JDK7的变更集,他们似乎正在对代码JDK7 Changeset进行LinuxVirtualMachine的更改。/proc/<pid>