Source for gnu.classpath.jdwp.VMVirtualMachine

   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: }