AttachNotSupported由于 Attach API 中缺少java_pid文件而导致的异常

2022-09-04 06:34:32

构建自己的探查器,我使用 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>


答案 1

我遇到了同样的问题。

线程“main” com.sun.tools.attach.AttachNotSupportedException 中的异常:无法打开套接字文件:目标进程未响应或未加载 HotSpot VM

该解决方案被发现做一些沉重的谷歌搜索。

第一个答案 http://www.jvmmonitor.org/doc/index.html。似乎有一个错误:

如果您看到附加消息“无法打开套接字文件:目标进程无响应或热点虚拟机未加载”,则表示您的应用程序没有响应创建套接字文件,如 /tmp/.java_pid1234(例如,由于挂断、文件系统权限),或者 JVM Monitor 无法找到创建的套接字文件(例如,由于7009828错误)。

然后经过进一步的搜索,我在github上发现了另一个工具的对话,该工具具有相同的症状“无法打开套接字文件”(https://github.com/rhuss/jolokia/issues/34):

jgreen: 由以下原因导致:com.sun.tools.attach.AttachNotSupported异常:无法打开套接字文件:目标进程无响应或未加载 HotSpot VM

jgreen:是的,我有它的工作,但只有当作为与activemq完全相同的用户时。根不起作用

最后一块是解决方案。此 .attach 调用成功的唯一方法是运行 java 代码,该代码以与运行 jvm 的进程的所有者相同的用户身份调用 attach。在我的情况下,它是activemq用户。

System.out.println("HEAP: " + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage());

HEAP: init = 27127296(26491K) used = 3974200(3881K) committed = 26345472(25728K) max = 675086336(659264K)

答案 2

我怀疑您可能正在为正在运行的JVM指定,并且它位于Java 6 Update 23或24上。如果是这种情况,您只需升级到正在运行的实例的 Update 25。-Djava.io.tmpdir

我见过的这个问题的唯一参考是Jstack,Jstat停止了升级到JDK6u23的工作。我确实在更新23和jstack失败中看到了同样的问题,它在23之前工作正常,并且在25中再次工作。我也刚刚尝试了23,如果使用,它会失败。它适用于25。VirtualMachine.attach(pid)-Djava.io.tmpdir


推荐