1 /* 2 * Copyright (c) 2005, 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 package sun.tools.attach; 26 27 import com.sun.tools.attach.VirtualMachineDescriptor; 28 import com.sun.tools.attach.VirtualMachine; 29 import com.sun.tools.attach.AttachPermission; 30 import com.sun.tools.attach.AttachNotSupportedException; 31 import com.sun.tools.attach.spi.AttachProvider; 32 33 import java.io.IOException; 34 import java.util.List; 35 import java.util.Iterator; 36 import java.util.ArrayList; 37 import java.util.Set; 38 import java.net.URISyntaxException; 39 40 import sun.jvmstat.monitor.HostIdentifier; 41 import sun.jvmstat.monitor.Monitor; 42 import sun.jvmstat.monitor.MonitoredHost; 43 import sun.jvmstat.monitor.MonitoredVm; 44 import sun.jvmstat.monitor.MonitoredVmUtil; 45 import sun.jvmstat.monitor.VmIdentifier; 46 import sun.jvmstat.monitor.MonitorException; 47 48 /* 49 * Platform specific provider implementations extend this 50 */ 51 public abstract class HotSpotAttachProvider extends AttachProvider { 52 53 // perf count name for the JVM version 54 private static final String JVM_VERSION = "java.property.java.vm.version"; 55 56 public HotSpotAttachProvider() { 57 } 58 59 public void checkAttachPermission() { 60 SecurityManager sm = System.getSecurityManager(); 61 if (sm != null) { 62 sm.checkPermission( 63 new AttachPermission("attachVirtualMachine") 64 ); 65 } 66 } 67 68 /* 69 * This listVirtualMachines implementation is based on jvmstat. Can override 70 * this in platform implementations when there is a more efficient mechanism 71 * available. 72 */ 73 public List<VirtualMachineDescriptor> listVirtualMachines() { 74 ArrayList<VirtualMachineDescriptor> result = 75 new ArrayList<VirtualMachineDescriptor>(); 76 77 MonitoredHost host; 78 Set vms; 79 try { 80 host = MonitoredHost.getMonitoredHost(new HostIdentifier((String)null)); 81 vms = host.activeVms(); 82 } catch (Throwable t) { 83 if (t instanceof ExceptionInInitializerError) { 84 t = t.getCause(); 85 } 86 if (t instanceof ThreadDeath) { 87 throw (ThreadDeath)t; 88 } 89 if (t instanceof SecurityException) { 90 return result; 91 } 92 throw new InternalError(); // shouldn't happen 93 } 94 95 for (Object vmid: vms) { 96 if (vmid instanceof Integer) { 97 String pid = vmid.toString(); 98 String name = pid; // default to pid if name not available 99 boolean isAttachable = false; 100 MonitoredVm mvm = null; 101 try { 102 mvm = host.getMonitoredVm(new VmIdentifier(pid)); 103 try { 104 isAttachable = MonitoredVmUtil.isAttachable(mvm); 105 // use the command line as the display name 106 name = MonitoredVmUtil.commandLine(mvm); 107 } catch (Exception e) { 108 } 109 if (isAttachable) { 110 result.add(new HotSpotVirtualMachineDescriptor(this, pid, name)); 111 } 112 } catch (Throwable t) { 113 if (t instanceof ThreadDeath) { 114 throw (ThreadDeath)t; 115 } 116 } finally { 117 if (mvm != null) { 118 mvm.detach(); 119 } 120 } 121 } 122 } 123 return result; 124 } 125 126 /** 127 * Test if a VM is attachable. If it's not attachable, 128 * an AttachNotSupportedException will be thrown. For example, 129 * 1.4.2 or 5.0 VM are not attachable. There are cases that 130 * we can't determine if a VM is attachable or not and this method 131 * will just return. 132 * 133 * This method uses the jvmstat counter to determine if a VM 134 * is attachable. If the target VM does not have a jvmstat 135 * share memory buffer, this method returns. 136 * 137 * @exception AttachNotSupportedException if it's not attachable 138 */ 139 void testAttachable(String id) throws AttachNotSupportedException { 140 MonitoredVm mvm = null; 141 try { 142 VmIdentifier vmid = new VmIdentifier(id); 143 MonitoredHost host = MonitoredHost.getMonitoredHost(vmid); 144 mvm = host.getMonitoredVm(vmid); 145 146 if (MonitoredVmUtil.isAttachable(mvm)) { 147 // it's attachable; so return false 148 return; 149 } 150 } catch (Throwable t) { 151 if (t instanceof ThreadDeath) { 152 ThreadDeath td = (ThreadDeath)t; 153 throw td; 154 } 155 // we do not know what this id is 156 return; 157 } finally { 158 if (mvm != null) { 159 mvm.detach(); 160 } 161 } 162 163 // we're sure it's not attachable; throw exception 164 throw new AttachNotSupportedException( 165 "The VM does not support the attach mechanism"); 166 } 167 168 169 /** 170 * A virtual machine descriptor to describe a HotSpot virtual machine. 171 */ 172 static class HotSpotVirtualMachineDescriptor extends VirtualMachineDescriptor { 173 HotSpotVirtualMachineDescriptor(AttachProvider provider, 174 String id, 175 String displayName) { 176 super(provider, id, displayName); 177 } 178 179 public boolean isAttachable() { 180 return true; 181 } 182 } 183 }