Save This Page
Home » openjdk-7 » sun.tools » attach » [javadoc | source]
    1   /*
    2    * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package sun.tools.attach;
   27   
   28   import com.sun.tools.attach.VirtualMachine;
   29   import com.sun.tools.attach.AgentLoadException;
   30   import com.sun.tools.attach.AgentInitializationException;
   31   import com.sun.tools.attach.spi.AttachProvider;
   32   
   33   import java.io.InputStream;
   34   import java.io.IOException;
   35   import java.util.Properties;
   36   import java.util.Map;
   37   
   38   /*
   39    * The HotSpot implementation of com.sun.tools.attach.VirtualMachine.
   40    */
   41   
   42   public abstract class HotSpotVirtualMachine extends VirtualMachine {
   43   
   44       HotSpotVirtualMachine(AttachProvider provider, String id) {
   45           super(provider, id);
   46       }
   47   
   48       /*
   49        * Load agent library
   50        * If isAbsolute is true then the agent library is the absolute path
   51        * to the library and thus will not be expanded in the target VM.
   52        * if isAbsolute is false then the agent library is just a library
   53        * name and it will be expended in the target VM.
   54        */
   55       private void loadAgentLibrary(String agentLibrary, boolean isAbsolute, String options)
   56           throws AgentLoadException, AgentInitializationException, IOException
   57       {
   58           InputStream in = execute("load",
   59                                    agentLibrary,
   60                                    isAbsolute ? "true" : "false",
   61                                    options);
   62           try {
   63               int result = readInt(in);
   64               if (result != 0) {
   65                   throw new AgentInitializationException("Agent_OnAttach failed", result);
   66               }
   67           } finally {
   68               in.close();
   69   
   70           }
   71       }
   72   
   73       /*
   74        * Load agent library - library name will be expanded in target VM
   75        */
   76       public void loadAgentLibrary(String agentLibrary, String options)
   77           throws AgentLoadException, AgentInitializationException, IOException
   78       {
   79           loadAgentLibrary(agentLibrary, false, options);
   80       }
   81   
   82       /*
   83        * Load agent - absolute path of library provided to target VM
   84        */
   85       public void loadAgentPath(String agentLibrary, String options)
   86           throws AgentLoadException, AgentInitializationException, IOException
   87       {
   88           loadAgentLibrary(agentLibrary, true, options);
   89       }
   90   
   91       /*
   92        * Load JPLIS agent which will load the agent JAR file and invoke
   93        * the agentmain method.
   94        */
   95       public void loadAgent(String agent, String options)
   96           throws AgentLoadException, AgentInitializationException, IOException
   97       {
   98           String args = agent;
   99           if (options != null) {
  100               args = args + "=" + options;
  101           }
  102           try {
  103               loadAgentLibrary("instrument", args);
  104           } catch (AgentLoadException x) {
  105               throw new InternalError("instrument library is missing in target VM");
  106           } catch (AgentInitializationException x) {
  107               /*
  108                * Translate interesting errors into the right exception and
  109                * message (FIXME: create a better interface to the instrument
  110                * implementation so this isn't necessary)
  111                */
  112               int rc = x.returnValue();
  113               switch (rc) {
  114                   case JNI_ENOMEM:
  115                       throw new AgentLoadException("Insuffient memory");
  116                   case ATTACH_ERROR_BADJAR:
  117                       throw new AgentLoadException("Agent JAR not found or no Agent-Class attribute");
  118                   case ATTACH_ERROR_NOTONCP:
  119                       throw new AgentLoadException("Unable to add JAR file to system class path");
  120                   case ATTACH_ERROR_STARTFAIL:
  121                       throw new AgentInitializationException("Agent JAR loaded but agent failed to initialize");
  122                   default :
  123                       throw new AgentLoadException("Failed to load agent - unknown reason: " + rc);
  124               }
  125           }
  126       }
  127   
  128       /*
  129        * The possible errors returned by JPLIS's agentmain
  130        */
  131       private static final int JNI_ENOMEM                 = -4;
  132       private static final int ATTACH_ERROR_BADJAR        = 100;
  133       private static final int ATTACH_ERROR_NOTONCP       = 101;
  134       private static final int ATTACH_ERROR_STARTFAIL     = 102;
  135   
  136   
  137       /*
  138        * Send "properties" command to target VM
  139        */
  140       public Properties getSystemProperties() throws IOException {
  141           InputStream in = null;
  142           Properties props = new Properties();
  143           try {
  144               in = executeCommand("properties");
  145               props.load(in);
  146           } finally {
  147               if (in != null) in.close();
  148           }
  149           return props;
  150       }
  151   
  152       public Properties getAgentProperties() throws IOException {
  153           InputStream in = null;
  154           Properties props = new Properties();
  155           try {
  156               in = executeCommand("agentProperties");
  157               props.load(in);
  158           } finally {
  159               if (in != null) in.close();
  160           }
  161           return props;
  162       }
  163   
  164       // --- HotSpot specific methods ---
  165   
  166       // same as SIGQUIT
  167       public void localDataDump() throws IOException {
  168           executeCommand("datadump").close();
  169       }
  170   
  171       // Remote ctrl-break. The output of the ctrl-break actions can
  172       // be read from the input stream.
  173       public InputStream remoteDataDump(Object ... args) throws IOException {
  174           return executeCommand("threaddump", args);
  175       }
  176   
  177       // Remote heap dump. The output (error message) can be read from the
  178       // returned input stream.
  179       public InputStream dumpHeap(Object ... args) throws IOException {
  180           return executeCommand("dumpheap", args);
  181       }
  182   
  183       // Heap histogram (heap inspection in HotSpot)
  184       public InputStream heapHisto(Object ... args) throws IOException {
  185           return executeCommand("inspectheap", args);
  186       }
  187   
  188       // set JVM command line flag
  189       public InputStream setFlag(String name, String value) throws IOException {
  190           return executeCommand("setflag", name, value);
  191       }
  192   
  193       // print command line flag
  194       public InputStream printFlag(String name) throws IOException {
  195           return executeCommand("printflag", name);
  196       }
  197   
  198       // -- Supporting methods
  199   
  200   
  201       /*
  202        * Execute the given command in the target VM - specific platform
  203        * implementation must implement this.
  204        */
  205       abstract InputStream execute(String cmd, Object ... args)
  206           throws AgentLoadException, IOException;
  207   
  208       /*
  209        * Convenience method for simple commands
  210        */
  211       private InputStream executeCommand(String cmd, Object ... args) throws IOException {
  212           try {
  213               return execute(cmd, args);
  214           } catch (AgentLoadException x) {
  215               throw new InternalError("Should not get here");
  216           }
  217       }
  218   
  219   
  220       /*
  221        * Utility method to read an 'int' from the input stream. Ideally
  222        * we should be using java.util.Scanner here but this implementation
  223        * guarantees not to read ahead.
  224        */
  225       int readInt(InputStream in) throws IOException {
  226           StringBuilder sb = new StringBuilder();
  227   
  228           // read to \n or EOF
  229           int n;
  230           byte buf[] = new byte[1];
  231           do {
  232               n = in.read(buf, 0, 1);
  233               if (n > 0) {
  234                   char c = (char)buf[0];
  235                   if (c == '\n') {
  236                       break;                  // EOL found
  237                   } else {
  238                       sb.append(c);
  239                   }
  240               }
  241           } while (n > 0);
  242   
  243           if (sb.length() == 0) {
  244               throw new IOException("Premature EOF");
  245           }
  246   
  247           int value;
  248           try {
  249               value = Integer.parseInt(sb.toString());
  250           } catch (NumberFormatException x) {
  251               throw new IOException("Non-numeric value found - int expected");
  252           }
  253           return value;
  254       }
  255   
  256       // -- attach timeout support
  257   
  258       private static long defaultAttachTimeout = 5000;
  259       private volatile long attachTimeout;
  260   
  261       /*
  262        * Return attach timeout based on the value of the sun.tools.attach.attachTimeout
  263        * property, or the default timeout if the property is not set to a positive
  264        * value.
  265        */
  266       long attachTimeout() {
  267           if (attachTimeout == 0) {
  268               synchronized(this) {
  269                   if (attachTimeout == 0) {
  270                       try {
  271                           String s =
  272                               System.getProperty("sun.tools.attach.attachTimeout");
  273                           attachTimeout = Long.parseLong(s);
  274                       } catch (SecurityException se) {
  275                       } catch (NumberFormatException ne) {
  276                       }
  277                       if (attachTimeout <= 0) {
  278                          attachTimeout = defaultAttachTimeout;
  279                       }
  280                   }
  281               }
  282           }
  283           return attachTimeout;
  284       }
  285   }

Save This Page
Home » openjdk-7 » sun.tools » attach » [javadoc | source]