< prev index next >

src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java

Print this page




  27 import com.sun.tools.attach.AttachOperationFailedException;
  28 import com.sun.tools.attach.AgentLoadException;
  29 import com.sun.tools.attach.AttachNotSupportedException;
  30 import com.sun.tools.attach.spi.AttachProvider;
  31 
  32 import java.io.InputStream;
  33 import java.io.IOException;
  34 import java.io.File;
  35 
  36 /*
  37  * Linux implementation of HotSpotVirtualMachine
  38  */
  39 public class VirtualMachineImpl extends HotSpotVirtualMachine {
  40     // "/tmp" is used as a global well-known location for the files
  41     // .java_pid<pid>. and .attach_pid<pid>. It is important that this
  42     // location is the same for all processes, otherwise the tools
  43     // will not be able to find all Hotspot processes.
  44     // Any changes to this needs to be synchronized with HotSpot.
  45     private static final String tmpdir = "/tmp";
  46 
  47     // Indicates if this machine uses the old LinuxThreads
  48     static boolean isLinuxThreads;
  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                 // On LinuxThreads each thread is a process and we don't have the
  77                 // pid of the VMThread which has SIGQUIT unblocked. To workaround
  78                 // this we get the pid of the "manager thread" that is created
  79                 // by the first call to pthread_create. This is parent of all
  80                 // threads (except the initial thread).
  81                 if (isLinuxThreads) {
  82                     int mpid;
  83                     try {
  84                         mpid = getLinuxThreadsManager(pid);
  85                     } catch (IOException x) {
  86                         throw new AttachNotSupportedException(x.getMessage());
  87                     }
  88                     assert(mpid >= 1);
  89                     sendQuitToChildrenOf(mpid);
  90                 } else {
  91                     sendQuitTo(pid);
  92                 }
  93 
  94                 // give the target VM time to start the attach mechanism
  95                 int i = 0;
  96                 long delay = 200;
  97                 int retries = (int)(attachTimeout() / delay);

  98                 do {


  99                     try {
 100                         Thread.sleep(delay);
 101                     } catch (InterruptedException x) { }
 102                     path = findSocketFile(pid);
 103                     i++;
 104                 } while (i <= retries && path == null);





 105                 if (path == null) {
 106                     throw new AttachNotSupportedException(
 107                         "Unable to open socket file: target process not responding " +
 108                         "or HotSpot VM not loaded");
 109                 }
 110             } finally {
 111                 f.delete();
 112             }
 113         }
 114 
 115         // Check that the file owner/permission to avoid attaching to
 116         // bogus process
 117         checkPermissions(path);
 118 
 119         // Check that we can connect to the process
 120         // - this ensures we throw the permission denied error now rather than
 121         // later when we attempt to enqueue a command.
 122         int s = socket();
 123         try {
 124             connect(s, path);
 125         } finally {
 126             close(s);
 127         }
 128     }


 323     static native int getLinuxThreadsManager(int pid) throws IOException;
 324 
 325     static native void sendQuitToChildrenOf(int pid) throws IOException;
 326 
 327     static native void sendQuitTo(int pid) throws IOException;
 328 
 329     static native void checkPermissions(String path) throws IOException;
 330 
 331     static native int socket() throws IOException;
 332 
 333     static native void connect(int fd, String path) throws IOException;
 334 
 335     static native void close(int fd) throws IOException;
 336 
 337     static native int read(int fd, byte buf[], int off, int bufLen) throws IOException;
 338 
 339     static native void write(int fd, byte buf[], int off, int bufLen) throws IOException;
 340 
 341     static {
 342         System.loadLibrary("attach");
 343         isLinuxThreads = isLinuxThreads();
 344     }
 345 }


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



  47     // The patch to the socket file created by the target VM
  48     String path;
  49 
  50     /**
  51      * Attaches to the target VM
  52      */
  53     VirtualMachineImpl(AttachProvider provider, String vmid)
  54         throws AttachNotSupportedException, IOException
  55     {
  56         super(provider, vmid);
  57 
  58         // This provider only understands pids
  59         int pid;
  60         try {
  61             pid = Integer.parseInt(vmid);
  62         } catch (NumberFormatException x) {
  63             throw new AttachNotSupportedException("Invalid process identifier");
  64         }
  65 
  66         // Find the socket file. If not found then we attempt to start the
  67         // attach mechanism in the target VM by sending it a QUIT signal.
  68         // Then we attempt to find the socket file again.
  69         path = findSocketFile(pid);
  70         if (path == null) {
  71             File f = createAttachFile(pid);
  72             try {















  73                 sendQuitTo(pid);

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

  97                 }
  98             } finally {
  99                 f.delete();
 100             }
 101       }
 102 
 103         // Check that the file owner/permission to avoid attaching to
 104         // bogus process
 105         checkPermissions(path);
 106 
 107         // Check that we can connect to the process
 108         // - this ensures we throw the permission denied error now rather than
 109         // later when we attempt to enqueue a command.
 110         int s = socket();
 111         try {
 112             connect(s, path);
 113         } finally {
 114             close(s);
 115         }
 116     }


 311     static native int getLinuxThreadsManager(int pid) throws IOException;
 312 
 313     static native void sendQuitToChildrenOf(int pid) throws IOException;
 314 
 315     static native void sendQuitTo(int pid) throws IOException;
 316 
 317     static native void checkPermissions(String path) throws IOException;
 318 
 319     static native int socket() throws IOException;
 320 
 321     static native void connect(int fd, String path) throws IOException;
 322 
 323     static native void close(int fd) throws IOException;
 324 
 325     static native int read(int fd, byte buf[], int off, int bufLen) throws IOException;
 326 
 327     static native void write(int fd, byte buf[], int off, int bufLen) throws IOException;
 328 
 329     static {
 330         System.loadLibrary("attach");

 331     }
 332 }
< prev index next >