aboutsummaryrefslogtreecommitdiff
path: root/kamon-autoweave/src/main/java/sun/tools/attach/HotSpotVirtualMachine.java
diff options
context:
space:
mode:
Diffstat (limited to 'kamon-autoweave/src/main/java/sun/tools/attach/HotSpotVirtualMachine.java')
-rw-r--r--kamon-autoweave/src/main/java/sun/tools/attach/HotSpotVirtualMachine.java289
1 files changed, 289 insertions, 0 deletions
diff --git a/kamon-autoweave/src/main/java/sun/tools/attach/HotSpotVirtualMachine.java b/kamon-autoweave/src/main/java/sun/tools/attach/HotSpotVirtualMachine.java
new file mode 100644
index 00000000..0bc04b04
--- /dev/null
+++ b/kamon-autoweave/src/main/java/sun/tools/attach/HotSpotVirtualMachine.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2005, 2011, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.tools.attach;
+
+import com.sun.tools.attach.VirtualMachine;
+import com.sun.tools.attach.AgentLoadException;
+import com.sun.tools.attach.AgentInitializationException;
+import com.sun.tools.attach.spi.AttachProvider;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.Properties;
+import java.util.Map;
+
+/*
+ * The HotSpot implementation of com.sun.tools.attach.VirtualMachine.
+ */
+
+public abstract class HotSpotVirtualMachine extends VirtualMachine {
+
+ HotSpotVirtualMachine(AttachProvider provider, String id) {
+ super(provider, id);
+ }
+
+ /*
+ * Load agent library
+ * If isAbsolute is true then the agent library is the absolute path
+ * to the library and thus will not be expanded in the target VM.
+ * if isAbsolute is false then the agent library is just a library
+ * name and it will be expended in the target VM.
+ */
+ private void loadAgentLibrary(String agentLibrary, boolean isAbsolute, String options)
+ throws AgentLoadException, AgentInitializationException, IOException
+ {
+ InputStream in = execute("load",
+ agentLibrary,
+ isAbsolute ? "true" : "false",
+ options);
+ try {
+ int result = readInt(in);
+ if (result != 0) {
+ throw new AgentInitializationException("Agent_OnAttach failed", result);
+ }
+ } finally {
+ in.close();
+
+ }
+ }
+
+ /*
+ * Load agent library - library name will be expanded in target VM
+ */
+ public void loadAgentLibrary(String agentLibrary, String options)
+ throws AgentLoadException, AgentInitializationException, IOException
+ {
+ loadAgentLibrary(agentLibrary, false, options);
+ }
+
+ /*
+ * Load agent - absolute path of library provided to target VM
+ */
+ public void loadAgentPath(String agentLibrary, String options)
+ throws AgentLoadException, AgentInitializationException, IOException
+ {
+ loadAgentLibrary(agentLibrary, true, options);
+ }
+
+ /*
+ * Load JPLIS agent which will load the agent JAR file and invoke
+ * the agentmain method.
+ */
+ public void loadAgent(String agent, String options)
+ throws AgentLoadException, AgentInitializationException, IOException
+ {
+ String args = agent;
+ if (options != null) {
+ args = args + "=" + options;
+ }
+ try {
+ loadAgentLibrary("instrument", args);
+ } catch (AgentLoadException x) {
+ throw new InternalError("instrument library is missing in target VM");
+ } catch (AgentInitializationException x) {
+ /*
+ * Translate interesting errors into the right exception and
+ * message (FIXME: create a better interface to the instrument
+ * implementation so this isn't necessary)
+ */
+ int rc = x.returnValue();
+ switch (rc) {
+ case JNI_ENOMEM:
+ throw new AgentLoadException("Insuffient memory");
+ case ATTACH_ERROR_BADJAR:
+ throw new AgentLoadException("Agent JAR not found or no Agent-Class attribute");
+ case ATTACH_ERROR_NOTONCP:
+ throw new AgentLoadException("Unable to add JAR file to system class path");
+ case ATTACH_ERROR_STARTFAIL:
+ throw new AgentInitializationException("Agent JAR loaded but agent failed to initialize");
+ default :
+ throw new AgentLoadException("Failed to load agent - unknown reason: " + rc);
+ }
+ }
+ }
+
+ /*
+ * The possible errors returned by JPLIS's agentmain
+ */
+ private static final int JNI_ENOMEM = -4;
+ private static final int ATTACH_ERROR_BADJAR = 100;
+ private static final int ATTACH_ERROR_NOTONCP = 101;
+ private static final int ATTACH_ERROR_STARTFAIL = 102;
+
+
+ /*
+ * Send "properties" command to target VM
+ */
+ public Properties getSystemProperties() throws IOException {
+ InputStream in = null;
+ Properties props = new Properties();
+ try {
+ in = executeCommand("properties");
+ props.load(in);
+ } finally {
+ if (in != null) in.close();
+ }
+ return props;
+ }
+
+ public Properties getAgentProperties() throws IOException {
+ InputStream in = null;
+ Properties props = new Properties();
+ try {
+ in = executeCommand("agentProperties");
+ props.load(in);
+ } finally {
+ if (in != null) in.close();
+ }
+ return props;
+ }
+
+ // --- HotSpot specific methods ---
+
+ // same as SIGQUIT
+ public void localDataDump() throws IOException {
+ executeCommand("datadump").close();
+ }
+
+ // Remote ctrl-break. The output of the ctrl-break actions can
+ // be read from the input stream.
+ public InputStream remoteDataDump(Object ... args) throws IOException {
+ return executeCommand("threaddump", args);
+ }
+
+ // Remote heap dump. The output (error message) can be read from the
+ // returned input stream.
+ public InputStream dumpHeap(Object ... args) throws IOException {
+ return executeCommand("dumpheap", args);
+ }
+
+ // Heap histogram (heap inspection in HotSpot)
+ public InputStream heapHisto(Object ... args) throws IOException {
+ return executeCommand("inspectheap", args);
+ }
+
+ // set JVM command line flag
+ public InputStream setFlag(String name, String value) throws IOException {
+ return executeCommand("setflag", name, value);
+ }
+
+ // print command line flag
+ public InputStream printFlag(String name) throws IOException {
+ return executeCommand("printflag", name);
+ }
+
+ public InputStream executeJCmd(String command) throws IOException {
+ return executeCommand("jcmd", command);
+ }
+
+ // -- Supporting methods
+
+
+ /*
+ * Execute the given command in the target VM - specific platform
+ * implementation must implement this.
+ */
+ abstract InputStream execute(String cmd, Object ... args)
+ throws AgentLoadException, IOException;
+
+ /*
+ * Convenience method for simple commands
+ */
+ private InputStream executeCommand(String cmd, Object ... args) throws IOException {
+ try {
+ return execute(cmd, args);
+ } catch (AgentLoadException x) {
+ throw new InternalError("Should not get here");
+ }
+ }
+
+
+ /*
+ * Utility method to read an 'int' from the input stream. Ideally
+ * we should be using java.util.Scanner here but this implementation
+ * guarantees not to read ahead.
+ */
+ int readInt(InputStream in) throws IOException {
+ StringBuilder sb = new StringBuilder();
+
+ // read to \n or EOF
+ int n;
+ byte buf[] = new byte[1];
+ do {
+ n = in.read(buf, 0, 1);
+ if (n > 0) {
+ char c = (char)buf[0];
+ if (c == '\n') {
+ break; // EOL found
+ } else {
+ sb.append(c);
+ }
+ }
+ } while (n > 0);
+
+ if (sb.length() == 0) {
+ throw new IOException("Premature EOF");
+ }
+
+ int value;
+ try {
+ value = Integer.parseInt(sb.toString());
+ } catch (NumberFormatException x) {
+ throw new IOException("Non-numeric value found - int expected");
+ }
+ return value;
+ }
+
+ // -- attach timeout support
+
+ private static long defaultAttachTimeout = 5000;
+ private volatile long attachTimeout;
+
+ /*
+ * Return attach timeout based on the value of the sun.tools.attach.attachTimeout
+ * property, or the default timeout if the property is not set to a positive
+ * value.
+ */
+ long attachTimeout() {
+ if (attachTimeout == 0) {
+ synchronized(this) {
+ if (attachTimeout == 0) {
+ try {
+ String s =
+ System.getProperty("sun.tools.attach.attachTimeout");
+ attachTimeout = Long.parseLong(s);
+ } catch (SecurityException se) {
+ } catch (NumberFormatException ne) {
+ }
+ if (attachTimeout <= 0) {
+ attachTimeout = defaultAttachTimeout;
+ }
+ }
+ }
+ }
+ return attachTimeout;
+ }
+}