blob: 732e2bb61e366cff09cc830b01b7cf1226a53ae3 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2005 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25package sun.tools.attach;
26
27import com.sun.tools.attach.VirtualMachineDescriptor;
28import com.sun.tools.attach.VirtualMachine;
29import com.sun.tools.attach.AttachPermission;
30import com.sun.tools.attach.AttachNotSupportedException;
31import com.sun.tools.attach.spi.AttachProvider;
32
33import java.io.IOException;
34import java.util.List;
35import java.util.Iterator;
36import java.util.ArrayList;
37import java.util.Set;
38import java.net.URISyntaxException;
39
40import sun.jvmstat.monitor.HostIdentifier;
41import sun.jvmstat.monitor.Monitor;
42import sun.jvmstat.monitor.MonitoredHost;
43import sun.jvmstat.monitor.MonitoredVm;
44import sun.jvmstat.monitor.MonitoredVmUtil;
45import sun.jvmstat.monitor.VmIdentifier;
46import sun.jvmstat.monitor.MonitorException;
47
48/*
49 * Platform specific provider implementations extend this
50 */
51public 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 boolean isKernelVM = false;
142 try {
143 VmIdentifier vmid = new VmIdentifier(id);
144 MonitoredHost host = MonitoredHost.getMonitoredHost(vmid);
145 mvm = host.getMonitoredVm(vmid);
146
147 if (MonitoredVmUtil.isAttachable(mvm)) {
148 // it's attachable; so return false
149 return;
150 }
151 isKernelVM = MonitoredVmUtil.isKernelVM(mvm);
152 } catch (Throwable t) {
153 if (t instanceof ThreadDeath) {
154 ThreadDeath td = (ThreadDeath)t;
155 throw td;
156 }
157 // we do not know what this id is
158 return;
159 } finally {
160 if (mvm != null) {
161 mvm.detach();
162 }
163 }
164
165 // we're sure it's not attachable; throw exception
166 if (isKernelVM) {
167 throw new AttachNotSupportedException("Kernel VM does not support the attach mechanism");
168 } else {
169 throw new AttachNotSupportedException("The VM does not support the attach mechanism");
170 }
171 }
172
173
174 /**
175 * A virtual machine descriptor to describe a HotSpot virtual machine.
176 */
177 static class HotSpotVirtualMachineDescriptor extends VirtualMachineDescriptor {
178 HotSpotVirtualMachineDescriptor(AttachProvider provider,
179 String id,
180 String displayName) {
181 super(provider, id, displayName);
182 }
183
184 public boolean isAttachable() {
185 return true;
186 }
187 }
188}