--- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java 2018-06-28 21:55:40.176325855 +0900 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java 2018-06-28 21:55:39.979330511 +0900 @@ -1,5 +1,5 @@ /* - * 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 @@ -25,8 +25,16 @@ 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; @@ -72,6 +80,9 @@ private List threadList; private List loadObjectList; + // PID namespace support + private Map nspidMap; + // called by native method lookupByAddress0 private ClosestSymbol createClosestSymbol(String name, long offset) { return new ClosestSymbol(name, offset); @@ -89,7 +100,8 @@ 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; @@ -254,15 +266,59 @@ } } + 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(); @@ -271,6 +327,7 @@ AttachTask task = new AttachTask(); task.pid = processID; + task.isInContainer = (processID != NSpid); workerThread.execute(task); }