< prev index next >

src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -23,12 +23,20 @@
  */
 
 package sun.jvm.hotspot.debugger.linux;
 
 import java.io.File;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.stream.Collectors;
 
 import sun.jvm.hotspot.debugger.Address;
 import sun.jvm.hotspot.debugger.DebuggerBase;
 import sun.jvm.hotspot.debugger.DebuggerException;
 import sun.jvm.hotspot.debugger.DebuggerUtilities;

@@ -70,10 +78,13 @@
 
     // threadList and loadObjectList are filled by attach0 method
     private List threadList;
     private List loadObjectList;
 
+    // PID namespace support
+    private Map<Integer, Integer> nspidMap;
+
     // called by native method lookupByAddress0
     private ClosestSymbol createClosestSymbol(String name, long offset) {
        return new ClosestSymbol(name, offset);
     }
 

@@ -87,11 +98,12 @@
 
     // native methods
 
     private native static void init0()
                                 throws DebuggerException;
-    private native void attach0(int pid)
+    private native void setSAAltRoot0(String altroot);
+    private native void attach0(int pid, boolean isInContainer)
                                 throws DebuggerException;
     private native void attach0(String execName, String coreName)
                                 throws DebuggerException;
     private native void detach0()
                                 throws DebuggerException;

@@ -252,27 +264,72 @@
             // new C++ ABI
             useGCC32ABI = true;
         }
     }
 
+    private int getNamespacePID(Path statusPath) {
+        try (var lines = Files.lines(statusPath)) {
+            return lines.map(s -> s.split("\\s+"))
+                        .filter(a -> a.length == 3)
+                        .filter(a -> a[0].equals("NSpid:"))
+                        .mapToInt(a -> Integer.valueOf(a[2]))
+                        .findFirst()
+                        .getAsInt();
+        } catch (IOException | NoSuchElementException e) {
+            return Integer.valueOf(statusPath.getParent()
+                                             .toFile()
+                                             .getName());
+        }
+    }
+
+    public int getHostPID(int id) {
+        try {
+            return nspidMap.get(id);
+        } catch (NullPointerException e) {
+            return -1;
+        }
+    }
+
+    private void fillNSpidMap(Path proc) {
+        Path task = Paths.get(proc.toString(), "task");
+        try {
+            nspidMap = Files.list(task)
+                            .filter(p -> !p.toString().startsWith("."))
+                            .collect(Collectors.toMap(p -> Integer.valueOf(getNamespacePID(Paths.get(p.toString(), "status"))),
+                                                      p -> Integer.valueOf(p.toFile().getName())));
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
     /** From the Debugger interface via JVMDebugger */
     public synchronized void attach(int processID) throws DebuggerException {
         checkAttached();
         threadList = new ArrayList();
         loadObjectList = new ArrayList();
+
+        Path proc = Paths.get("/proc", Integer.toString(processID));
+        int NSpid = getNamespacePID(Paths.get(proc.toString(), "status"));
+        if (NSpid != processID) {
+            setSAAltRoot0(Paths.get(proc.toString(), "root").toString());
+            fillNSpidMap(proc);
+        }
+
         class AttachTask implements WorkerThreadTask {
            int pid;
+           boolean isInContainer;
            public void doit(LinuxDebuggerLocal debugger) {
-              debugger.attach0(pid);
+              debugger.attach0(pid, isInContainer);
               debugger.attached = true;
               debugger.isCore = false;
               findABIVersion();
            }
         }
 
         AttachTask task = new AttachTask();
         task.pid = processID;
+        task.isInContainer = (processID != NSpid);
         workerThread.execute(task);
     }
 
     /** From the Debugger interface via JVMDebugger */
     public synchronized void attach(String execName, String coreName) {
< prev index next >