Frames | No Frames |
1: /* VMVirtualMachine.java -- A reference implementation of a JDWP virtual 2: machine 3: 4: Copyright (C) 2005, 2006 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 java.lang.reflect.Method; 49: import java.nio.ByteBuffer; 50: import java.util.ArrayList; 51: import java.util.Iterator; 52: 53: /** 54: * A virtual machine according to JDWP. 55: * 56: * @author Keith Seitz <keiths@redhat.com> 57: */ 58: public class VMVirtualMachine 59: { 60: /** 61: * Suspend a thread 62: * 63: * @param thread the thread to suspend 64: */ 65: public static native void suspendThread (Thread thread) 66: throws JdwpException; 67: 68: /** 69: * Suspend all threads 70: */ 71: public static void suspendAllThreads () 72: throws JdwpException 73: { 74: // Our JDWP thread group -- don't suspend any of those threads 75: Thread current = Thread.currentThread (); 76: ThreadGroup jdwpGroup = Jdwp.getDefault().getJdwpThreadGroup(); 77: 78: // Find the root ThreadGroup 79: ThreadGroup group = jdwpGroup; 80: ThreadGroup parent = group.getParent (); 81: while (parent != null) 82: { 83: group = parent; 84: parent = group.getParent (); 85: } 86: 87: // Get all the threads in the system 88: int num = group.activeCount (); 89: Thread[] threads = new Thread[num]; 90: group.enumerate (threads); 91: 92: for (int i = 0; i < num; ++i) 93: { 94: Thread t = threads[i]; 95: if (t != null) 96: { 97: if (t.getThreadGroup () == jdwpGroup || t == current) 98: { 99: // Don't suspend the current thread or any JDWP thread 100: continue; 101: } 102: else 103: suspendThread (t); 104: } 105: } 106: 107: // Now suspend the current thread 108: if (current.getThreadGroup() != jdwpGroup) 109: suspendThread (current); 110: } 111: 112: /** 113: * Resume a thread. A thread must be resumed as many times 114: * as it has been suspended. 115: * 116: * @param thread the thread to resume 117: */ 118: public static native void resumeThread (Thread thread) 119: throws JdwpException; 120: 121: /** 122: * Resume all threads. This simply decrements the thread's 123: * suspend count. It can not be used to force the application 124: * to run. 125: */ 126: public static void resumeAllThreads () 127: throws JdwpException 128: { 129: // Our JDWP thread group -- don't resume 130: Thread current = Thread.currentThread (); 131: ThreadGroup jdwpGroup = current.getThreadGroup (); 132: 133: // Find the root ThreadGroup 134: ThreadGroup group = jdwpGroup; 135: ThreadGroup parent = group.getParent (); 136: while (parent != null) 137: { 138: group = parent; 139: parent = group.getParent (); 140: } 141: 142: // Get all the threads in the system 143: int num = group.activeCount (); 144: Thread[] threads = new Thread[num]; 145: group.enumerate (threads); 146: 147: for (int i = 0; i < num; ++i) 148: { 149: Thread t = threads[i]; 150: if (t != null) 151: { 152: if (t.getThreadGroup () == jdwpGroup || t == current) 153: { 154: // Don't resume the current thread or any JDWP thread 155: continue; 156: } 157: else 158: resumeThread (t); 159: } 160: } 161: } 162: 163: /** 164: * Get the suspend count for a give thread 165: * 166: * @param thread the thread whose suspend count is desired 167: * @return the number of times the thread has been suspended 168: */ 169: public static native int getSuspendCount (Thread thread) 170: throws JdwpException; 171: 172: /** 173: * Returns a count of the number of loaded classes in the VM 174: */ 175: public static native int getAllLoadedClassesCount () 176: throws JdwpException; 177: 178: /** 179: * Returns an iterator over all the loaded classes in the VM 180: */ 181: public static native Iterator getAllLoadedClasses () 182: throws JdwpException; 183: 184: /** 185: * Returns the status of the given class 186: * 187: * @param clazz the class whose status is desired 188: * @return a flag containing the class's status 189: * @see JdwpConstants.ClassStatus 190: */ 191: public static native int getClassStatus (Class clazz) 192: throws JdwpException; 193: 194: /** 195: * Returns all of the methods defined in the given class. This 196: * includes all methods, constructors, and class initializers. 197: * 198: * @param klass the class whose methods are desired 199: * @return an array of virtual machine methods 200: */ 201: public static native VMMethod[] getAllClassMethods (Class klass) 202: throws JdwpException; 203: 204: /** 205: * A factory method for getting valid virtual machine methods 206: * which may be passed to/from the debugger. 207: * 208: * @param klass the class in which the method is defined 209: * @param id the ID of the desired method 210: * @return the desired internal representation of the method 211: * @throws InvalidMethodException if the method is not defined 212: * in the class 213: * @throws JdwpException for any other error 214: */ 215: public static native VMMethod getClassMethod(Class klass, long id) 216: throws JdwpException; 217: 218: /** 219: * Returns the thread's call stack 220: * 221: * @param thread thread for which to get call stack 222: * @param start index of first frame to return 223: * @param length number of frames to return (-1 for all frames) 224: * @return a list of frames 225: */ 226: public static native ArrayList getFrames (Thread thread, int start, 227: int length) 228: throws JdwpException; 229: 230: /** 231: * Returns the frame for a given thread with the frame ID in 232: * the buffer 233: * 234: * I don't like this. 235: * 236: * @param thread the frame's thread 237: * @param bb buffer containing the frame's ID 238: * @return the desired frame 239: */ 240: public static native VMFrame getFrame (Thread thread, ByteBuffer bb) 241: throws JdwpException; 242: 243: /** 244: * Returns the number of frames in the thread's stack 245: * 246: * @param thread the thread for which to get a frame count 247: * @return the number of frames in the thread's stack 248: */ 249: public static native int getFrameCount (Thread thread) 250: throws JdwpException; 251: 252: 253: /** 254: * Returns the status of a thread 255: * 256: * @param thread the thread for which to get status 257: * @return integer status of the thread 258: * @see JdwpConstants.ThreadStatus 259: */ 260: public static native int getThreadStatus (Thread thread) 261: throws JdwpException; 262: 263: /** 264: * Returns a list of all classes which this class loader has been 265: * requested to load 266: * 267: * @param cl the class loader 268: * @return a list of all visible classes 269: */ 270: public static native ArrayList getLoadRequests (ClassLoader cl) 271: throws JdwpException; 272: 273: /** 274: * Executes a method in the virtual machine 275: * 276: * @param obj instance in which to invoke method (null for static) 277: * @param thread the thread in which to invoke the method 278: * @param clazz the class in which the method is defined 279: * @param method the method to invoke 280: * @param values arguments to pass to method 281: * @param nonVirtual "otherwise, normal virtual invoke 282: * (instance methods only) " 283: * @return a result object containing the results of the invocation 284: */ 285: public static native MethodResult executeMethod (Object obj, Thread thread, 286: Class clazz, Method method, 287: Object[] values, 288: boolean nonVirtual) 289: throws JdwpException; 290: 291: /** 292: * "Returns the name of source file in which a reference type was declared" 293: * 294: * @param clazz the class for which to return a source file 295: * @return a string containing the source file name; "no path information 296: * for the file is included" 297: */ 298: public static native String getSourceFile (Class clazz) 299: throws JdwpException; 300: 301: /** 302: * Register a request from the debugger 303: * 304: * Virtual machines have two options. Either do nothing and allow 305: * the event manager to take care of the request (useful for broadcast-type 306: * events like class prepare/load/unload, thread start/end, etc.) 307: * or do some internal work to set up the event notification (useful for 308: * execution-related events like breakpoints, single-stepping, etc.). 309: */ 310: public static native void registerEvent (EventRequest request) 311: throws JdwpException; 312: 313: /** 314: * Unregisters the given request 315: * 316: * @param request the request to unregister 317: */ 318: public static native void unregisterEvent (EventRequest request) 319: throws JdwpException; 320: 321: 322: /** 323: * Clear all events of the given kind 324: * 325: * @param kind the type of events to clear 326: */ 327: public static native void clearEvents (byte kind) 328: throws JdwpException; 329: }