< prev index next >

open/src/jdk.attach/aix/classes/sun/tools/attach/VirtualMachineImpl.java

Print this page


   1 /*
   2  * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2015 SAP SE. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.  Oracle designates this
   9  * particular file as subject to the "Classpath" exception as provided
  10  * by Oracle in the LICENSE file that accompanied this code.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA


  29 import com.sun.tools.attach.AgentLoadException;
  30 import com.sun.tools.attach.AttachNotSupportedException;
  31 import com.sun.tools.attach.spi.AttachProvider;
  32 
  33 import java.io.InputStream;
  34 import java.io.IOException;
  35 import java.io.File;
  36 
  37 // Based on linux/classes/sun/tools/attach/VirtualMachineImpl.java.
  38 
  39 /*
  40  * Aix implementation of HotSpotVirtualMachine
  41  */
  42 public class VirtualMachineImpl extends HotSpotVirtualMachine {
  43     // "/tmp" is used as a global well-known location for the files
  44     // .java_pid<pid>. and .attach_pid<pid>. It is important that this
  45     // location is the same for all processes, otherwise the tools
  46     // will not be able to find all Hotspot processes.
  47     // Any changes to this needs to be synchronized with HotSpot.
  48     private static final String tmpdir = "/tmp";
  49 
  50     // The patch to the socket file created by the target VM
  51     String path;
  52 
  53     /**
  54      * Attaches to the target VM
  55      */
  56     VirtualMachineImpl(AttachProvider provider, String vmid)
  57         throws AttachNotSupportedException, IOException
  58     {
  59         super(provider, vmid);
  60 
  61         // This provider only understands pids
  62         int pid;
  63         try {
  64             pid = Integer.parseInt(vmid);
  65         } catch (NumberFormatException x) {
  66             throw new AttachNotSupportedException("Invalid process identifier");
  67         }
  68 
  69         // Find the socket file. If not found then we attempt to start the
  70         // attach mechanism in the target VM by sending it a QUIT signal.
  71         // Then we attempt to find the socket file again.
  72         path = findSocketFile(pid);
  73         if (path == null) {

  74             File f = createAttachFile(pid);
  75             try {
  76                 sendQuitTo(pid);
  77 
  78                 // give the target VM time to start the attach mechanism
  79                 final int delay_step = 100;
  80                 final long timeout = attachTimeout();
  81                 long time_spend = 0;
  82                 long delay = 0;
  83                 do {
  84                     // Increase timeout on each attempt to reduce polling
  85                     delay += delay_step;
  86                     try {
  87                         Thread.sleep(delay);
  88                     } catch (InterruptedException x) { }
  89                     path = findSocketFile(pid);
  90 
  91                     time_spend += delay;
  92                     if (time_spend > timeout/2 && path == null) {
  93                         // Send QUIT again to give target VM the last chance to react
  94                         sendQuitTo(pid);
  95                     }
  96                 } while (time_spend <= timeout && path == null);
  97                 if (path == null) {
  98                     throw new AttachNotSupportedException(
  99                         String.format("Unable to open socket file %s: " +
 100                           "target process %d doesn't respond within %dms " +
 101                           "or HotSpot VM not loaded", f.getPath(), pid, time_spend));

 102                 }
 103             } finally {
 104                 f.delete();
 105             }
 106         }
 107 
 108         // Check that the file owner/permission to avoid attaching to
 109         // bogus process
 110         checkPermissions(path);
 111 
 112         // Check that we can connect to the process
 113         // - this ensures we throw the permission denied error now rather than
 114         // later when we attempt to enqueue a command.
 115         int s = socket();
 116         try {
 117             connect(s, path);
 118         } finally {
 119             close(s);
 120         }
 121     }
 122 
 123     /**
 124      * Detach from the target VM
 125      */
 126     public void detach() throws IOException {
 127         synchronized (this) {
 128             if (this.path != null) {
 129                 this.path = null;
 130             }
 131         }
 132     }
 133 
 134     // protocol version
 135     private final static String PROTOCOL_VERSION = "1";
 136 
 137     // known errors


 245             if (n == 1) {
 246                 return b[0] & 0xff;
 247             } else {
 248                 return -1;
 249             }
 250         }
 251 
 252         public synchronized int read(byte[] bs, int off, int len) throws IOException {
 253             if ((off < 0) || (off > bs.length) || (len < 0) ||
 254                 ((off + len) > bs.length) || ((off + len) < 0)) {
 255                 throw new IndexOutOfBoundsException();
 256             } else if (len == 0)
 257                 return 0;
 258 
 259             return VirtualMachineImpl.read(s, bs, off, len);
 260         }
 261 
 262         public void close() throws IOException {
 263             VirtualMachineImpl.close(s);
 264         }
 265     }
 266 
 267     // Return the socket file for the given process.
 268     private String findSocketFile(int pid) {
 269         File f = new File(tmpdir, ".java_pid" + pid);
 270         if (!f.exists()) {
 271             return null;
 272         }
 273         return f.getPath();
 274     }
 275 
 276     // On Solaris/Linux/Aix a simple handshake is used to start the attach mechanism
 277     // if not already started. The client creates a .attach_pid<pid> file in the
 278     // target VM's working directory (or temp directory), and the SIGQUIT handler
 279     // checks for the file.
 280     private File createAttachFile(int pid) throws IOException {
 281         String fn = ".attach_pid" + pid;
 282         String path = "/proc/" + pid + "/cwd/" + fn;
 283         File f = new File(path);
 284         try {
 285             f.createNewFile();
 286         } catch (IOException x) {
 287             f = new File(tmpdir, fn);
 288             f.createNewFile();
 289         }
 290         return f;
 291     }
 292 
 293     /*


   1 /*
   2  * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2015 SAP SE. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.  Oracle designates this
   9  * particular file as subject to the "Classpath" exception as provided
  10  * by Oracle in the LICENSE file that accompanied this code.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA


  29 import com.sun.tools.attach.AgentLoadException;
  30 import com.sun.tools.attach.AttachNotSupportedException;
  31 import com.sun.tools.attach.spi.AttachProvider;
  32 
  33 import java.io.InputStream;
  34 import java.io.IOException;
  35 import java.io.File;
  36 
  37 // Based on linux/classes/sun/tools/attach/VirtualMachineImpl.java.
  38 
  39 /*
  40  * Aix implementation of HotSpotVirtualMachine
  41  */
  42 public class VirtualMachineImpl extends HotSpotVirtualMachine {
  43     // "/tmp" is used as a global well-known location for the files
  44     // .java_pid<pid>. and .attach_pid<pid>. It is important that this
  45     // location is the same for all processes, otherwise the tools
  46     // will not be able to find all Hotspot processes.
  47     // Any changes to this needs to be synchronized with HotSpot.
  48     private static final String tmpdir = "/tmp";
  49     String socket_name;


  50 
  51     /**
  52      * Attaches to the target VM
  53      */
  54     VirtualMachineImpl(AttachProvider provider, String vmid)
  55         throws AttachNotSupportedException, IOException
  56     {
  57         super(provider, vmid);
  58 
  59         // This provider only understands pids
  60         int pid;
  61         try {
  62             pid = Integer.parseInt(vmid);
  63         } catch (NumberFormatException x) {
  64             throw new AttachNotSupportedException("Invalid process identifier");
  65         }
  66 
  67         // Find the socket file. If not found then we attempt to start the
  68         // attach mechanism in the target VM by sending it a QUIT signal.
  69         // Then we attempt to find the socket file again.
  70         File path = new File(tmpdir, ".java_pid" + pid);
  71         socket_name = path.getPath();
  72         if (!path.exists()) {
  73             File f = createAttachFile(pid);
  74             try {
  75                 sendQuitTo(pid);
  76 
  77                 // give the target VM time to start the attach mechanism
  78                 final int delay_step = 100;
  79                 final long timeout = attachTimeout();
  80                 long time_spend = 0;
  81                 long delay = 0;
  82                 do {
  83                     // Increase timeout on each attempt to reduce polling
  84                     delay += delay_step;
  85                     try {
  86                         Thread.sleep(delay);
  87                     } catch (InterruptedException x) { }

  88 
  89                     time_spend += delay;
  90                     if (time_spend > timeout/2 && !path.exists()) {
  91                         // Send QUIT again to give target VM the last chance to react
  92                         sendQuitTo(pid);
  93                     }
  94                 } while (time_spend <= timeout && !path.exists());
  95                 if (!path.exists()) {
  96                     throw new AttachNotSupportedException(
  97                         String.format("Unable to open socket file %s: " +
  98                           "target process %d doesn't respond within %dms " +
  99                            "or HotSpot VM not loaded", socket_name, pid,
 100                                       time_spend));
 101                 }
 102             } finally {
 103                 f.delete();
 104             }
 105         }
 106 
 107         // Check that the file owner/permission to avoid attaching to
 108         // bogus process
 109         checkPermissions(socket_name);
 110 
 111         // Check that we can connect to the process
 112         // - this ensures we throw the permission denied error now rather than
 113         // later when we attempt to enqueue a command.
 114         int s = socket();
 115         try {
 116             connect(s, socket_name);
 117         } finally {
 118             close(s);
 119         }
 120     }
 121 
 122     /**
 123      * Detach from the target VM
 124      */
 125     public void detach() throws IOException {
 126         synchronized (this) {
 127             if (this.path != null) {
 128                 this.path = null;
 129             }
 130         }
 131     }
 132 
 133     // protocol version
 134     private final static String PROTOCOL_VERSION = "1";
 135 
 136     // known errors


 244             if (n == 1) {
 245                 return b[0] & 0xff;
 246             } else {
 247                 return -1;
 248             }
 249         }
 250 
 251         public synchronized int read(byte[] bs, int off, int len) throws IOException {
 252             if ((off < 0) || (off > bs.length) || (len < 0) ||
 253                 ((off + len) > bs.length) || ((off + len) < 0)) {
 254                 throw new IndexOutOfBoundsException();
 255             } else if (len == 0)
 256                 return 0;
 257 
 258             return VirtualMachineImpl.read(s, bs, off, len);
 259         }
 260 
 261         public void close() throws IOException {
 262             VirtualMachineImpl.close(s);
 263         }









 264     }
 265 
 266     // On Solaris/Linux/Aix a simple handshake is used to start the attach mechanism
 267     // if not already started. The client creates a .attach_pid<pid> file in the
 268     // target VM's working directory (or temp directory), and the SIGQUIT handler
 269     // checks for the file.
 270     private File createAttachFile(int pid) throws IOException {
 271         String fn = ".attach_pid" + pid;
 272         String path = "/proc/" + pid + "/cwd/" + fn;
 273         File f = new File(path);
 274         try {
 275             f.createNewFile();
 276         } catch (IOException x) {
 277             f = new File(tmpdir, fn);
 278             f.createNewFile();
 279         }
 280         return f;
 281     }
 282 
 283     /*


< prev index next >