Hi,

A short update on this. This is a known regression in more recent versions of Java: https://bugs.openjdk.org/browse/JDK-8226919

One of my colleagues (thanks, Sebastian!) managed to workaround this by patching the JDK 17 sources to make it use plain /tmp in this case (when ns_pid == pid), and also added some better error handling in case this fails.

We are currently working on getting this submitted upstream to OpenJDK, but I wanted to share it with you as well. One option would be to include this in Debian's set of local JDK patches (https://salsa.debian.org/openjdk-team/openjdk/-/tree/master/debian/patches), but I don't know how conservative the project is re. fixes like this? I'll leave this up to the debian-java maintainers to decide.

Best regards,
Per
--- a/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java
+++ b/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java
@@ -209,11 +209,8 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
     }
 
     // Return the socket file for the given process.
-    private File findSocketFile(int pid, int ns_pid) {
-        // A process may not exist in the same mount namespace as the caller.
-        // Instead, attach relative to the target root filesystem as exposed by
-        // procfs regardless of namespaces.
-        String root = "/proc/" + pid + "/root/" + tmpdir;
+    private File findSocketFile(int pid, int ns_pid) throws IOException {
+        String root = findTargetProcessTmpDirectory(pid, ns_pid);
         return new File(root, ".java_pid" + ns_pid);
     }
 
@@ -229,21 +226,33 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
             // Do not canonicalize the file path, or we will fail to attach to a VM in a container.
             f.createNewFile();
         } catch (IOException x) {
-            String root;
-            if (pid != ns_pid) {
-                // A process may not exist in the same mount namespace as the caller.
-                // Instead, attach relative to the target root filesystem as exposed by
-                // procfs regardless of namespaces.
-                root = "/proc/" + pid + "/root/" + tmpdir;
-            } else {
-                root = tmpdir;
-            }
+            String root = findTargetProcessTmpDirectory(pid, ns_pid);
             f = new File(root, fn);
             f.createNewFile();
         }
         return f;
     }
 
+    private String findTargetProcessTmpDirectory(int pid, int ns_pid) throws IOException {
+        String root;
+        if (pid != ns_pid) {
+            // A process may not exist in the same mount namespace as the caller.
+            // Instead, attach relative to the target root filesystem as exposed by
+            // procfs regardless of namespaces.
+            String procRootDirectory = "/proc/" + pid + "/root";
+            if (!Files.isReadable(Path.of(procRootDirectory))) {
+                throw new IOException(
+                        String.format("Unable to access root directory %s " +
+                          "of target process %d", procRootDirectory, pid));
+            }
+
+            root = procRootDirectory + "/" + tmpdir;
+        } else {
+            root = tmpdir;
+        }
+        return root;
+    }
+
     /*
      * Write/sends the given to the target VM. String is transmitted in
      * UTF-8 encoding.

Reply via email to