Frames | No Frames |
1: /* VMVirtualMachine.java -- A reference implementation of a JDWP virtual 2: machine 3: 4: Copyright (C) 2005, 2006, 2007 Free Software Foundation 5: 6: This file is part of GNU Classpath. 7: 8: GNU Classpath is free software; you can redistribute it and/or modify 9: it under the terms of the GNU General Public License as published by 10: the Free Software Foundation; either version 2, or (at your option) 11: any later version. 12: 13: GNU Classpath is distributed in the hope that it will be useful, but 14: WITHOUT ANY WARRANTY; without even the implied warranty of 15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16: General Public License for more details. 17: 18: You should have received a copy of the GNU General Public License 19: along with GNU Classpath; see the file COPYING. If not, write to the 20: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 21: 02110-1301 USA. 22: 23: Linking this library statically or dynamically with other modules is 24: making a combined work based on this library. Thus, the terms and 25: conditions of the GNU General Public License cover the whole 26: combination. 27: 28: As a special exception, the copyright holders of this library give you 29: permission to link this library with independent modules to produce an 30: executable, regardless of the license terms of these independent 31: modules, and to copy and distribute the resulting executable under 32: terms of your choice, provided that you also meet, for each linked 33: terms of your choice, provided that you also meet, for each linked 34: independent module, the terms and conditions of the license of that 35: module. An independent module is a module which is not derived from 36: or based on this library. If you modify this library, you may extend 37: this exception to your version of the library, but you are not 38: obligated to do so. If you do not wish to do so, delete this 39: exception statement from your version. */ 40: 41: 42: package gnu.classpath.jdwp; 43: 44: import gnu.classpath.jdwp.event.EventRequest; 45: import gnu.classpath.jdwp.exception.InvalidMethodException; 46: import gnu.classpath.jdwp.exception.JdwpException; 47: import gnu.classpath.jdwp.util.MethodResult; 48: import gnu.classpath.jdwp.util.MonitorInfo; 49: import gnu.classpath.jdwp.value.Value; 50: 51: import java.nio.ByteBuffer; 52: import java.util.ArrayList; 53: import java.util.Collection; 54: import java.util.Hashtable; 55: 56: /** 57: * A virtual machine according to JDWP. 58: * 59: * @author Keith Seitz <keiths@redhat.com> 60: */ 61: public class VMVirtualMachine 62: { 63: // VM Capabilities 64: public static final boolean canWatchFieldModification = false; 65: public static final boolean canWatchFieldAccess = false; 66: public static final boolean canGetBytecodes = false; 67: public static final boolean canGetSyntheticAttribute = false; 68: public static final boolean canGetOwnedMonitorInfo = false; 69: public static final boolean canGetCurrentContendedMonitor = false; 70: public static final boolean canGetMonitorInfo = false; 71: public static final boolean canRedefineClasses = false; 72: public static final boolean canAddMethod = false; 73: public static final boolean canUnrestrictedlyRedefineClasses = false; 74: public static final boolean canPopFrames = false; 75: public static final boolean canUseInstanceFilters = false; 76: public static final boolean canGetSourceDebugExtension = false; 77: public static final boolean canRequestVMDeathEvent = false; 78: public static final boolean canSetDefaultStratum = false; 79: 80: // Thread suspension table. Maps Thread to suspend count (Integer) 81: private static Hashtable _jdwp_suspend_counts; 82: 83: // List of stepping threads: maps Thread -> stepping info 84: static Hashtable _stepping_threads; 85: 86: // List of co-located JVMTI events 87: static ArrayList _event_list; 88: 89: public static native void initialize (); 90: 91: /** 92: * Suspend a thread 93: * 94: * @param thread the thread to suspend 95: */ 96: public static native void suspendThread (Thread thread) 97: throws JdwpException; 98: 99: /** 100: * Suspend all threads 101: */ 102: public static void suspendAllThreads () 103: throws JdwpException 104: { 105: // Our JDWP thread group -- don't suspend any of those threads 106: Thread current = Thread.currentThread (); 107: ThreadGroup jdwpGroup = Jdwp.getDefault().getJdwpThreadGroup(); 108: 109: // Find the root ThreadGroup 110: ThreadGroup group = jdwpGroup; 111: ThreadGroup parent = group.getParent (); 112: while (parent != null) 113: { 114: group = parent; 115: parent = group.getParent (); 116: } 117: 118: // Get all the threads in the system 119: int num = group.activeCount (); 120: Thread[] threads = new Thread[num]; 121: group.enumerate (threads); 122: 123: for (int i = 0; i < num; ++i) 124: { 125: Thread t = threads[i]; 126: if (t != null) 127: { 128: if (t.getThreadGroup () == jdwpGroup || t == current) 129: { 130: // Don't suspend the current thread or any JDWP thread 131: continue; 132: } 133: else 134: suspendThread (t); 135: } 136: } 137: 138: // Now suspend the current thread 139: if (current.getThreadGroup() != jdwpGroup) 140: suspendThread (current); 141: } 142: 143: /** 144: * Resume a thread. A thread must be resumed as many times 145: * as it has been suspended. 146: * 147: * @param thread the thread to resume 148: */ 149: public static native void resumeThread (Thread thread) 150: throws JdwpException; 151: 152: /** 153: * Resume all threads. This simply decrements the thread's 154: * suspend count. It can not be used to force the application 155: * to run. 156: */ 157: public static void resumeAllThreads () 158: throws JdwpException 159: { 160: // Our JDWP thread group -- don't resume 161: Thread current = Thread.currentThread (); 162: ThreadGroup jdwpGroup = current.getThreadGroup (); 163: 164: // Find the root ThreadGroup 165: ThreadGroup group = jdwpGroup; 166: ThreadGroup parent = group.getParent (); 167: while (parent != null) 168: { 169: group = parent; 170: parent = group.getParent (); 171: } 172: 173: // Get all the threads in the system 174: int num = group.activeCount (); 175: Thread[] threads = new Thread[num]; 176: group.enumerate (threads); 177: 178: for (int i = 0; i < num; ++i) 179: { 180: Thread t = threads[i]; 181: if (t != null) 182: { 183: if (t.getThreadGroup () == jdwpGroup || t == current) 184: { 185: // Don't resume the current thread or any JDWP thread 186: continue; 187: } 188: else 189: resumeThread (t); 190: } 191: } 192: } 193: 194: /** 195: * Get the suspend count for a give thread 196: * 197: * @param thread the thread whose suspend count is desired 198: * @return the number of times the thread has been suspended 199: */ 200: public static native int getSuspendCount (Thread thread) 201: throws JdwpException; 202: 203: /** 204: * Returns a Collection of all classes loaded in the VM 205: */ 206: public static native Collection getAllLoadedClasses () 207: throws JdwpException; 208: 209: /** 210: * Returns the status of the given class 211: * 212: * @param clazz the class whose status is desired 213: * @return a flag containing the class's status 214: * @see JdwpConstants.ClassStatus 215: */ 216: public static native int getClassStatus (Class clazz) 217: throws JdwpException; 218: 219: /** 220: * Returns all of the methods defined in the given class. This 221: * includes all methods, constructors, and class initializers. 222: * 223: * @param klass the class whose methods are desired 224: * @return an array of virtual machine methods 225: */ 226: public static native VMMethod[] getAllClassMethods (Class klass) 227: throws JdwpException; 228: 229: /** 230: * A factory method for getting valid virtual machine methods 231: * which may be passed to/from the debugger. 232: * 233: * @param klass the class in which the method is defined 234: * @param id the ID of the desired method 235: * @return the desired internal representation of the method 236: * @throws InvalidMethodException if the method is not defined 237: * in the class 238: * @throws JdwpException for any other error 239: */ 240: public static native VMMethod getClassMethod(Class klass, long id) 241: throws JdwpException; 242: 243: /** 244: * Returns the thread's call stack 245: * 246: * @param thread thread for which to get call stack 247: * @param start index of first frame to return 248: * @param length number of frames to return (-1 for all frames) 249: * @return a list of frames 250: */ 251: public static native ArrayList getFrames (Thread thread, int start, 252: int length) 253: throws JdwpException; 254: 255: /** 256: * Returns the frame for a given thread with the frame ID in 257: * the buffer 258: * 259: * I don't like this. 260: * 261: * @param thread the frame's thread 262: * @param bb buffer containing the frame's ID 263: * @return the desired frame 264: */ 265: public static native VMFrame getFrame (Thread thread, long frameID) 266: throws JdwpException; 267: 268: /** 269: * Returns the number of frames in the thread's stack 270: * 271: * @param thread the thread for which to get a frame count 272: * @return the number of frames in the thread's stack 273: */ 274: public static native int getFrameCount (Thread thread) 275: throws JdwpException; 276: 277: 278: /** 279: * Returns the status of a thread 280: * 281: * @param thread the thread for which to get status 282: * @return integer status of the thread 283: * @see JdwpConstants.ThreadStatus 284: */ 285: public static native int getThreadStatus (Thread thread) 286: throws JdwpException; 287: 288: /** 289: * Returns a list of all classes which this class loader has been 290: * requested to load 291: * 292: * @param cl the class loader 293: * @return a list of all visible classes 294: */ 295: public static native ArrayList getLoadRequests (ClassLoader cl) 296: throws JdwpException; 297: 298: /** 299: * Executes a method in the virtual machine. The thread must already 300: * be suspended by a previous event. When the method invocation is 301: * complete, the thread (or all threads if INVOKE_SINGLE_THREADED is 302: * not set in options) must be suspended before this method returns. 303: * 304: * @param obj instance in which to invoke method (null for static) 305: * @param thread the thread in which to invoke the method 306: * @param clazz the class in which the method is defined 307: * @param method the method to invoke 308: * @param values arguments to pass to method 309: * @param options invocation options 310: * @return a result object containing the results of the invocation 311: */ 312: public static native MethodResult executeMethod (Object obj, Thread thread, 313: Class clazz, VMMethod method, 314: Value[] values, 315: int options) 316: throws JdwpException; 317: 318: /** 319: * "Returns the name of source file in which a reference type was declared" 320: * 321: * @param clazz the class for which to return a source file 322: * @return a string containing the source file name; "no path information 323: * for the file is included" 324: */ 325: public static native String getSourceFile (Class clazz) 326: throws JdwpException; 327: 328: /** 329: * Register a request from the debugger 330: * 331: * Virtual machines have two options. Either do nothing and allow 332: * the event manager to take care of the request (useful for broadcast-type 333: * events like class prepare/load/unload, thread start/end, etc.) 334: * or do some internal work to set up the event notification (useful for 335: * execution-related events like breakpoints, single-stepping, etc.). 336: */ 337: public static native void registerEvent (EventRequest request) 338: throws JdwpException; 339: 340: /** 341: * Unregisters the given request 342: * 343: * @param request the request to unregister 344: */ 345: public static native void unregisterEvent (EventRequest request) 346: throws JdwpException; 347: 348: 349: /** 350: * Clear all events of the given kind 351: * 352: * @param kind the type of events to clear 353: */ 354: public static native void clearEvents (byte kind) 355: throws JdwpException; 356: 357: /** 358: * Redefines the given types. VM must support canRedefineClasses 359: * capability (may also require canAddMethod and/or 360: * canUnrestrictedlyRedefineClasses capabilities) 361: * 362: * @param types the classes to redefine 363: * @param bytecodes the new bytecode definitions for the classes 364: */ 365: public static native void redefineClasses(Class[] types, byte[][] bytecodes) 366: throws JdwpException; 367: 368: /** 369: * Sets the default stratum. VM must support the 370: * canSetDefaultStratum capability. 371: * 372: * @param stratum the new default stratum or empty string to 373: * use the reference default 374: */ 375: public static native void setDefaultStratum(String stratum) 376: throws JdwpException; 377: 378: /** 379: * Returns the source debug extension. VM must support the 380: * canGetSourceDebugExtension capability. 381: * 382: * @param klass the class for which to return information 383: * @returns the source debug extension 384: */ 385: public static native String getSourceDebugExtension(Class klass) 386: throws JdwpException; 387: 388: /** 389: * Returns the bytecode for the given method. VM must support the 390: * canGetBytecodes capability. 391: * 392: * @param method the method for which to get bytecodes 393: * @returns the bytecodes 394: */ 395: public static native byte[] getBytecodes(VMMethod method) 396: throws JdwpException; 397: 398: /** 399: * Returns monitor information about an object. VM must support 400: * the canGetMonitorInformation capability. 401: * 402: * @param obj the object 403: * @returns monitor information (owner, entry count, waiters) 404: */ 405: public static native MonitorInfo getMonitorInfo(Object obj) 406: throws JdwpException; 407: 408: /** 409: * Returns a list of owned monitors. VM must support the 410: * canGetOwnedMonitorInfo capability. 411: * 412: * @param thread a thread 413: * @returns the list of monitors owned by this thread 414: */ 415: public static native Object[] getOwnedMonitors(Thread thread) 416: throws JdwpException; 417: 418: /** 419: * Returns the current contended monitor for a thread. VM must 420: * support canGetCurrentContendedMonitor capability. 421: * 422: * @param thread the thread 423: * @returns the contended monitor 424: */ 425: public static native Object getCurrentContendedMonitor(Thread thread) 426: throws JdwpException; 427: 428: /** 429: * Pop all frames up to and including the given frame. VM must 430: * support canPopFrames capability. It is the responsibility 431: * of the VM to check if the thread is suspended. If it is not, 432: * the VM should throw ThreadNotSuspendedException. 433: * 434: * @param thread the thread 435: * @param frame the frame ID 436: */ 437: public static native void popFrames(Thread thread, long frameId); 438: }