Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/tools/attach/HotSpotVirtualMachine.java
38918 views
1
/*
2
* Copyright (c) 2005, 2014, 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.stream.Collectors;
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", x);
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
private static final String MANAGMENT_PREFIX = "com.sun.management.";
165
166
private static boolean checkedKeyName(Object key) {
167
if (!(key instanceof String)) {
168
throw new IllegalArgumentException("Invalid option (not a String): "+key);
169
}
170
if (!((String)key).startsWith(MANAGMENT_PREFIX)) {
171
throw new IllegalArgumentException("Invalid option: "+key);
172
}
173
return true;
174
}
175
176
private static String stripKeyName(Object key) {
177
return ((String)key).substring(MANAGMENT_PREFIX.length());
178
}
179
180
@Override
181
public void startManagementAgent(Properties agentProperties) throws IOException {
182
if (agentProperties == null) {
183
throw new NullPointerException("agentProperties cannot be null");
184
}
185
// Convert the arguments into arguments suitable for the Diagnostic Command:
186
// "ManagementAgent.start jmxremote.port=5555 jmxremote.authenticate=false"
187
String args = agentProperties.entrySet().stream()
188
.filter(entry -> checkedKeyName(entry.getKey()))
189
.map(entry -> stripKeyName(entry.getKey()) + "=" + escape(entry.getValue()))
190
.collect(Collectors.joining(" "));
191
executeJCmd("ManagementAgent.start " + args);
192
}
193
194
private String escape(Object arg) {
195
String value = arg.toString();
196
if (value.contains(" ")) {
197
return "'" + value + "'";
198
}
199
return value;
200
}
201
202
@Override
203
public String startLocalManagementAgent() throws IOException {
204
executeJCmd("ManagementAgent.start_local");
205
return getAgentProperties().getProperty("com.sun.management.jmxremote.localConnectorAddress");
206
}
207
208
// --- HotSpot specific methods ---
209
210
// same as SIGQUIT
211
public void localDataDump() throws IOException {
212
executeCommand("datadump").close();
213
}
214
215
// Remote ctrl-break. The output of the ctrl-break actions can
216
// be read from the input stream.
217
public InputStream remoteDataDump(Object ... args) throws IOException {
218
return executeCommand("threaddump", args);
219
}
220
221
// Remote heap dump. The output (error message) can be read from the
222
// returned input stream.
223
public InputStream dumpHeap(Object ... args) throws IOException {
224
return executeCommand("dumpheap", args);
225
}
226
227
// Heap histogram (heap inspection in HotSpot)
228
public InputStream heapHisto(Object ... args) throws IOException {
229
return executeCommand("inspectheap", args);
230
}
231
232
// set JVM command line flag
233
public InputStream setFlag(String name, String value) throws IOException {
234
return executeCommand("setflag", name, value);
235
}
236
237
// print command line flag
238
public InputStream printFlag(String name) throws IOException {
239
return executeCommand("printflag", name);
240
}
241
242
public InputStream executeJCmd(String command) throws IOException {
243
return executeCommand("jcmd", command);
244
}
245
246
// -- Supporting methods
247
248
249
/*
250
* Execute the given command in the target VM - specific platform
251
* implementation must implement this.
252
*/
253
abstract InputStream execute(String cmd, Object ... args)
254
throws AgentLoadException, IOException;
255
256
/*
257
* Convenience method for simple commands
258
*/
259
private InputStream executeCommand(String cmd, Object ... args) throws IOException {
260
try {
261
return execute(cmd, args);
262
} catch (AgentLoadException x) {
263
throw new InternalError("Should not get here", x);
264
}
265
}
266
267
268
/*
269
* Utility method to read an 'int' from the input stream. Ideally
270
* we should be using java.util.Scanner here but this implementation
271
* guarantees not to read ahead.
272
*/
273
int readInt(InputStream in) throws IOException {
274
StringBuilder sb = new StringBuilder();
275
276
// read to \n or EOF
277
int n;
278
byte buf[] = new byte[1];
279
do {
280
n = in.read(buf, 0, 1);
281
if (n > 0) {
282
char c = (char)buf[0];
283
if (c == '\n') {
284
break; // EOL found
285
} else {
286
sb.append(c);
287
}
288
}
289
} while (n > 0);
290
291
if (sb.length() == 0) {
292
throw new IOException("Premature EOF");
293
}
294
295
int value;
296
try {
297
value = Integer.parseInt(sb.toString());
298
} catch (NumberFormatException x) {
299
throw new IOException("Non-numeric value found - int expected");
300
}
301
return value;
302
}
303
304
/*
305
* Utility method to read data into a String.
306
*/
307
String readErrorMessage(InputStream sis) throws IOException {
308
byte b[] = new byte[1024];
309
int n;
310
StringBuffer message = new StringBuffer();
311
while ((n = sis.read(b)) != -1) {
312
message.append(new String(b, 0, n, "UTF-8"));
313
}
314
return message.toString();
315
}
316
317
318
// -- attach timeout support
319
320
private static long defaultAttachTimeout = 5000;
321
private volatile long attachTimeout;
322
323
/*
324
* Return attach timeout based on the value of the sun.tools.attach.attachTimeout
325
* property, or the default timeout if the property is not set to a positive
326
* value.
327
*/
328
long attachTimeout() {
329
if (attachTimeout == 0) {
330
synchronized(this) {
331
if (attachTimeout == 0) {
332
try {
333
String s =
334
System.getProperty("sun.tools.attach.attachTimeout");
335
attachTimeout = Long.parseLong(s);
336
} catch (SecurityException se) {
337
} catch (NumberFormatException ne) {
338
}
339
if (attachTimeout <= 0) {
340
attachTimeout = defaultAttachTimeout;
341
}
342
}
343
}
344
}
345
return attachTimeout;
346
}
347
}
348
349