1:
38:
39:
40: package ;
41:
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52:
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60:
61:
66: public class VirtualMachineCommandSet
67: extends CommandSet
68: {
69: public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command)
70: throws JdwpException
71: {
72: boolean shutdown = false;
73: try
74: {
75: switch (command)
76: {
77: case JdwpConstants.CommandSet.VirtualMachine.VERSION:
78: executeVersion(bb, os);
79: break;
80: case JdwpConstants.CommandSet.VirtualMachine.CLASSES_BY_SIGNATURE:
81: executeClassesBySignature(bb, os);
82: break;
83: case JdwpConstants.CommandSet.VirtualMachine.ALL_CLASSES:
84: executeAllClasses(bb, os);
85: break;
86: case JdwpConstants.CommandSet.VirtualMachine.ALL_THREADS:
87: executeAllThreads(bb, os);
88: break;
89: case JdwpConstants.CommandSet.VirtualMachine.TOP_LEVEL_THREAD_GROUPS:
90: executeTopLevelThreadGroups(bb, os);
91: break;
92: case JdwpConstants.CommandSet.VirtualMachine.IDSIZES:
93: executeIDsizes(bb, os);
94: break;
95: case JdwpConstants.CommandSet.VirtualMachine.DISPOSE:
96: shutdown = true;
97: executeDispose(bb, os);
98: break;
99: case JdwpConstants.CommandSet.VirtualMachine.SUSPEND:
100: executeSuspend(bb, os);
101: break;
102: case JdwpConstants.CommandSet.VirtualMachine.RESUME:
103: executeResume(bb, os);
104: break;
105: case JdwpConstants.CommandSet.VirtualMachine.EXIT:
106: shutdown = true;
107: executeExit(bb, os);
108: break;
109: case JdwpConstants.CommandSet.VirtualMachine.CREATE_STRING:
110: executeCreateString(bb, os);
111: break;
112: case JdwpConstants.CommandSet.VirtualMachine.CAPABILITIES:
113: executeCapabilities(bb, os);
114: break;
115: case JdwpConstants.CommandSet.VirtualMachine.CLASS_PATHS:
116: executeClassPaths(bb, os);
117: break;
118: case JdwpConstants.CommandSet.VirtualMachine.DISPOSE_OBJECTS:
119: executeDisposeObjects(bb, os);
120: break;
121: case JdwpConstants.CommandSet.VirtualMachine.HOLD_EVENTS:
122: executeHoldEvents(bb, os);
123: break;
124: case JdwpConstants.CommandSet.VirtualMachine.RELEASE_EVENTS:
125: executeReleaseEvents(bb, os);
126: break;
127: case JdwpConstants.CommandSet.VirtualMachine.CAPABILITIES_NEW:
128: executeCapabilitiesNew(bb, os);
129: break;
130: case JdwpConstants.CommandSet.VirtualMachine.REDEFINE_CLASSES:
131: executeRedefineClasses(bb, os);
132: break;
133: case JdwpConstants.CommandSet.VirtualMachine.SET_DEFAULT_STRATUM:
134: executeSetDefaultStratum(bb, os);
135: break;
136: case JdwpConstants.CommandSet.VirtualMachine.ALL_CLASSES_WITH_GENERIC:
137: executeAllClassesWithGeneric(bb, os);
138: break;
139: default:
140: throw new NotImplementedException("Command " + command +
141: " not found in VirtualMachine Command Set.");
142: }
143: }
144: catch (IOException ex)
145: {
146:
147:
148: throw new JdwpInternalErrorException(ex);
149: }
150:
151: return shutdown;
152: }
153:
154: private void executeVersion(ByteBuffer bb, DataOutputStream os)
155: throws JdwpException, IOException
156: {
157:
158: Properties props = System.getProperties();
159:
160: int jdwpMajor = JdwpConstants.Version.MAJOR;
161: int jdwpMinor = JdwpConstants.Version.MINOR;
162:
163: String description = "JDWP version " + jdwpMajor + "." + jdwpMinor
164: + ", JVM version " + props.getProperty("java.vm.name")
165: + " " + props.getProperty("java.vm.version") + " "
166: + props.getProperty("java.version");
167: String vmVersion = props.getProperty("java.version");
168: String vmName = props.getProperty("java.vm.name");
169: JdwpString.writeString(os, description);
170: os.writeInt(jdwpMajor);
171: os.writeInt(jdwpMinor);
172: JdwpString.writeString(os, vmName);
173: JdwpString.writeString(os, vmVersion);
174: }
175:
176: private void executeClassesBySignature(ByteBuffer bb, DataOutputStream os)
177: throws JdwpException, IOException
178: {
179: String sig = JdwpString.readString(bb);
180: ArrayList allMatchingClasses = new ArrayList();
181:
182:
183: Collection classes = VMVirtualMachine.getAllLoadedClasses();
184: Iterator iter = classes.iterator ();
185:
186: while (iter.hasNext())
187: {
188: Class clazz = (Class) iter.next();
189: String clazzSig = Signature.computeClassSignature(clazz);
190: if (clazzSig.equals(sig))
191: allMatchingClasses.add(clazz);
192: }
193:
194: os.writeInt(allMatchingClasses.size());
195: for (int i = 0; i < allMatchingClasses.size(); i++)
196: {
197: Class clazz = (Class) allMatchingClasses.get(i);
198: ReferenceTypeId id = idMan.getReferenceTypeId(clazz);
199: id.writeTagged(os);
200: int status = VMVirtualMachine.getClassStatus(clazz);
201: os.writeInt(status);
202: }
203: }
204:
205: private void executeAllClasses(ByteBuffer bb, DataOutputStream os)
206: throws JdwpException, IOException
207: {
208: Collection classes = VMVirtualMachine.getAllLoadedClasses();
209: os.writeInt(classes.size ());
210:
211: Iterator iter = classes.iterator ();
212: while (iter.hasNext())
213: {
214: Class clazz = (Class) iter.next();
215: ReferenceTypeId id = idMan.getReferenceTypeId(clazz);
216: id.writeTagged(os);
217: String sig = Signature.computeClassSignature(clazz);
218: JdwpString.writeString(os, sig);
219: int status = VMVirtualMachine.getClassStatus(clazz);
220: os.writeInt(status);
221: }
222: }
223:
224: private void executeAllThreads(ByteBuffer bb, DataOutputStream os)
225: throws JdwpException, IOException
226: {
227: ThreadGroup jdwpGroup = Thread.currentThread().getThreadGroup();
228: ThreadGroup root = getRootThreadGroup(jdwpGroup);
229:
230: int numThreads = root.activeCount();
231: Thread allThreads[] = new Thread[numThreads];
232: root.enumerate(allThreads);
233:
234:
235:
236:
237:
238: numThreads = 0;
239: for (int i = 0; i < allThreads.length; i++)
240: {
241: Thread thread = allThreads[i];
242: if (thread == null)
243: break;
244: if (!thread.getThreadGroup().equals(jdwpGroup))
245: numThreads++;
246: }
247:
248: os.writeInt(numThreads);
249:
250: for (int i = 0; i < allThreads.length; i++)
251: {
252: Thread thread = allThreads[i];
253: if (thread == null)
254: break;
255: if (!thread.getThreadGroup().equals(jdwpGroup))
256: idMan.getObjectId(thread).write(os);
257: }
258: }
259:
260: private void executeTopLevelThreadGroups(ByteBuffer bb, DataOutputStream os)
261: throws JdwpException, IOException
262: {
263: ThreadGroup jdwpGroup = Thread.currentThread().getThreadGroup ();
264: ThreadGroup root = getRootThreadGroup(jdwpGroup);
265:
266: os.writeInt(1);
267: idMan.getObjectId(root).write(os);
268: }
269:
270: private void executeDispose(ByteBuffer bb, DataOutputStream os)
271: throws JdwpException
272: {
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285: throw new NotImplementedException(
286: "Command VirtualMachine.Dispose not implemented");
287:
288: }
289:
290: private void executeIDsizes(ByteBuffer bb, DataOutputStream os)
291: throws JdwpException, IOException
292: {
293: os.writeInt(ObjectId.SIZE);
294: os.writeInt(ObjectId.SIZE);
295: os.writeInt(ObjectId.SIZE);
296: os.writeInt(ReferenceTypeId.SIZE);
297: os.writeInt(VMFrame.SIZE);
298: }
299:
300: private void executeSuspend(ByteBuffer bb, DataOutputStream os)
301: throws JdwpException
302: {
303: VMVirtualMachine.suspendAllThreads ();
304: }
305:
306: private void executeResume(ByteBuffer bb, DataOutputStream os)
307: throws JdwpException
308: {
309: VMVirtualMachine.resumeAllThreads ();
310: }
311:
312: private void executeExit(ByteBuffer bb, DataOutputStream os)
313: throws JdwpException, IOException
314: {
315: int exitCode = bb.getInt();
316: System.exit (exitCode);
317: }
318:
319: private void executeCreateString(ByteBuffer bb, DataOutputStream os)
320: throws JdwpException, IOException
321: {
322: String string = JdwpString.readString(bb);
323: ObjectId stringId = idMan.getObjectId(string);
324:
325:
326:
327: stringId.disableCollection();
328: stringId.write(os);
329: }
330:
331: private void executeCapabilities(ByteBuffer bb, DataOutputStream os)
332: throws JdwpException, IOException
333: {
334: os.writeBoolean(VMVirtualMachine.canWatchFieldModification);
335: os.writeBoolean(VMVirtualMachine.canWatchFieldAccess);
336: os.writeBoolean(VMVirtualMachine.canGetBytecodes);
337: os.writeBoolean(VMVirtualMachine.canGetSyntheticAttribute);
338: os.writeBoolean(VMVirtualMachine.canGetOwnedMonitorInfo);
339: os.writeBoolean(VMVirtualMachine.canGetCurrentContendedMonitor);
340: os.writeBoolean(VMVirtualMachine.canGetMonitorInfo);
341: }
342:
343: private void executeClassPaths(ByteBuffer bb, DataOutputStream os)
344: throws JdwpException, IOException
345: {
346: String baseDir = System.getProperty("user.dir");
347: JdwpString.writeString(os, baseDir);
348:
349:
350: String classPath = System.getProperty("java.class.path");
351: String[] paths = classPath.split(":");
352:
353: os.writeInt(paths.length);
354: for (int i = 0; i < paths.length; i++)
355: JdwpString.writeString(os, paths[i]);
356:
357:
358: String bootPath = System.getProperty("sun.boot.class.path");
359: paths = bootPath.split(":");
360: os.writeInt(paths.length);
361: for (int i = 0; i < paths.length; i++)
362: JdwpString.writeString(os, paths[i]);
363: }
364:
365: private void executeDisposeObjects(ByteBuffer bb, DataOutputStream os)
366: throws JdwpException
367: {
368:
369:
370:
371: }
372:
373: private void executeHoldEvents(ByteBuffer bb, DataOutputStream os)
374: throws JdwpException
375: {
376:
377:
378:
379: throw new NotImplementedException(
380: "Command VirtualMachine.HoldEvents not implemented");
381: }
382:
383:
384: private void executeReleaseEvents(ByteBuffer bb, DataOutputStream os)
385: throws JdwpException
386: {
387: throw new NotImplementedException(
388: "Command VirtualMachine.ReleaseEvents not implemented");
389: }
390:
391: private void executeCapabilitiesNew(ByteBuffer bb, DataOutputStream os)
392: throws JdwpException, IOException
393: {
394: final int CAPABILITIES_NEW_SIZE = 32;
395:
396: executeCapabilities(bb, os);
397: os.writeBoolean(VMVirtualMachine.canRedefineClasses);
398: os.writeBoolean(VMVirtualMachine.canAddMethod);
399: os.writeBoolean(VMVirtualMachine.canUnrestrictedlyRedefineClasses);
400: os.writeBoolean(VMVirtualMachine.canPopFrames);
401: os.writeBoolean(VMVirtualMachine.canUseInstanceFilters);
402: os.writeBoolean(VMVirtualMachine.canGetSourceDebugExtension);
403: os.writeBoolean(VMVirtualMachine.canRequestVMDeathEvent);
404: os.writeBoolean(VMVirtualMachine.canSetDefaultStratum);
405: for (int i = 15; i < CAPABILITIES_NEW_SIZE; i++)
406: {
407:
408: os.writeBoolean(false);
409: }
410: }
411:
412: private void executeRedefineClasses(ByteBuffer bb, DataOutputStream os)
413: throws JdwpException
414: {
415: if (!VMVirtualMachine.canRedefineClasses)
416: {
417: String msg = "redefinition of classes is not supported";
418: throw new NotImplementedException(msg);
419: }
420:
421: int classes = bb.getInt();
422: Class[] types = new Class[classes];
423: byte[][] bytecodes = new byte[classes][];
424: for (int i = 0; i < classes; ++i)
425: {
426: ReferenceTypeId id = idMan.readReferenceTypeId(bb);
427: int classfile = bb.getInt();
428: byte[] bytecode = new byte[classfile];
429: bb.get(bytecode);
430: types[i] = id.getType();
431: bytecodes[i] = bytecode;
432: }
433:
434: VMVirtualMachine.redefineClasses (types, bytecodes);
435: }
436:
437: private void executeSetDefaultStratum(ByteBuffer bb, DataOutputStream os)
438: throws JdwpException
439: {
440: if (!VMVirtualMachine.canSetDefaultStratum)
441: {
442: String msg = "setting the default stratum is not supported";
443: throw new NotImplementedException(msg);
444: }
445:
446: String stratum = JdwpString.readString(bb);
447: VMVirtualMachine.setDefaultStratum(stratum);
448: }
449:
450: private void executeAllClassesWithGeneric(ByteBuffer bb, DataOutputStream os)
451: throws JdwpException
452: {
453:
454: throw new NotImplementedException(
455: "Command VirtualMachine.AllClassesWithGeneric not implemented");
456: }
457:
458:
461: private ThreadGroup getRootThreadGroup(ThreadGroup group)
462: {
463: ThreadGroup parent = group.getParent();
464:
465: while (parent != null)
466: {
467: group = parent;
468: parent = group.getParent();
469: }
470: return group;
471: }
472: }