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.util.ArrayList; 52 import java.util.Collection; 53 54 /** 55 * A virtual machine according to JDWP. 56 * 57 * @author Keith Seitz <keiths@redhat.com> 58 */ 59 public class VMVirtualMachine 60 { 61 // VM Capabilities 62 public static final boolean canWatchFieldModification = false; 63 public static final boolean canWatchFieldAccess = false; 64 public static final boolean canGetBytecodes = false; 65 public static final boolean canGetSyntheticAttribute = false; 66 public static final boolean canGetOwnedMonitorInfo = false; 67 public static final boolean canGetCurrentContendedMonitor = false; 68 public static final boolean canGetMonitorInfo = false; 69 public static final boolean canRedefineClasses = false; 70 public static final boolean canAddMethod = false; 71 public static final boolean canUnrestrictedlyRedefineClasses = false; 72 public static final boolean canPopFrames = false; 73 public static final boolean canUseInstanceFilters = false; 74 public static final boolean canGetSourceDebugExtension = false; 75 public static final boolean canRequestVMDeathEvent = false; 76 public static final boolean canSetDefaultStratum = false; 77 78 /** 79 * Suspend a thread 80 * 81 * @param thread the thread to suspend 82 */ suspendThread(Thread thread)83 public static native void suspendThread(Thread thread) 84 throws JdwpException; 85 86 /** 87 * Suspend all threads 88 */ suspendAllThreads()89 public static void suspendAllThreads() 90 throws JdwpException 91 { 92 // Our JDWP thread group -- don't suspend any of those threads 93 Thread current = Thread.currentThread (); 94 ThreadGroup jdwpGroup = Jdwp.getDefault().getJdwpThreadGroup(); 95 96 // Find the root ThreadGroup 97 ThreadGroup group = jdwpGroup; 98 ThreadGroup parent = group.getParent (); 99 while (parent != null) 100 { 101 group = parent; 102 parent = group.getParent (); 103 } 104 105 // Get all the threads in the system 106 int num = group.activeCount (); 107 Thread[] threads = new Thread[num]; 108 group.enumerate (threads); 109 110 for (int i = 0; i < num; ++i) 111 { 112 Thread t = threads[i]; 113 if (t != null) 114 { 115 if (t.getThreadGroup () == jdwpGroup || t == current) 116 { 117 // Don't suspend the current thread or any JDWP thread 118 continue; 119 } 120 else 121 suspendThread (t); 122 } 123 } 124 125 // Now suspend the current thread 126 if (current.getThreadGroup() != jdwpGroup) 127 suspendThread (current); 128 } 129 130 /** 131 * Resume a thread. A thread must be resumed as many times 132 * as it has been suspended. 133 * 134 * @param thread the thread to resume 135 */ resumeThread(Thread thread)136 public static native void resumeThread(Thread thread) 137 throws JdwpException; 138 139 /** 140 * Resume all threads. This simply decrements the thread's 141 * suspend count. It can not be used to force the application 142 * to run. 143 */ resumeAllThreads()144 public static void resumeAllThreads() 145 throws JdwpException 146 { 147 // Our JDWP thread group -- don't resume 148 Thread current = Thread.currentThread (); 149 ThreadGroup jdwpGroup = current.getThreadGroup (); 150 151 // Find the root ThreadGroup 152 ThreadGroup group = jdwpGroup; 153 ThreadGroup parent = group.getParent (); 154 while (parent != null) 155 { 156 group = parent; 157 parent = group.getParent (); 158 } 159 160 // Get all the threads in the system 161 int num = group.activeCount (); 162 Thread[] threads = new Thread[num]; 163 group.enumerate (threads); 164 165 for (int i = 0; i < num; ++i) 166 { 167 Thread t = threads[i]; 168 if (t != null) 169 { 170 if (t.getThreadGroup () == jdwpGroup || t == current) 171 { 172 // Don't resume the current thread or any JDWP thread 173 continue; 174 } 175 else 176 resumeThread (t); 177 } 178 } 179 } 180 181 /** 182 * Get the suspend count for a give thread 183 * 184 * @param thread the thread whose suspend count is desired 185 * @return the number of times the thread has been suspended 186 */ getSuspendCount(Thread thread)187 public static native int getSuspendCount(Thread thread) 188 throws JdwpException; 189 190 /** 191 * Returns a Collection of all classes loaded in the VM 192 */ getAllLoadedClasses()193 public static native Collection getAllLoadedClasses() 194 throws JdwpException; 195 196 /** 197 * Returns the status of the given class 198 * 199 * @param clazz the class whose status is desired 200 * @return a flag containing the class's status 201 * @see JdwpConstants.ClassStatus 202 */ getClassStatus(Class clazz)203 public static native int getClassStatus(Class clazz) 204 throws JdwpException; 205 206 /** 207 * Returns all of the methods defined in the given class. This 208 * includes all methods, constructors, and class initializers. 209 * 210 * @param klass the class whose methods are desired 211 * @return an array of virtual machine methods 212 */ getAllClassMethods(Class klass)213 public static native VMMethod[] getAllClassMethods(Class klass) 214 { return null; } 215 216 /** 217 * A factory method for getting valid virtual machine methods 218 * which may be passed to/from the debugger. 219 * 220 * @param klass the class in which the method is defined 221 * @param id the ID of the desired method 222 * @return the desired internal representation of the method 223 * @throws InvalidMethodException if the method is not defined 224 * in the class 225 * @throws JdwpException for any other error 226 */ getClassMethod(Class klass, long id)227 public static native VMMethod getClassMethod(Class klass, long id) 228 { return null; } 229 230 /** 231 * Returns the thread's call stack 232 * 233 * @param thread thread for which to get call stack 234 * @param start index of first frame to return 235 * @param length number of frames to return (-1 for all frames) 236 * @return a list of frames 237 */ getFrames(Thread thread, int start, int length)238 public static native ArrayList getFrames(Thread thread, int start, 239 int length) 240 throws JdwpException; 241 242 /** 243 * Returns the frame for a given thread with the frame ID in 244 * the buffer 245 * 246 * I don't like this. 247 * 248 * @param thread the frame's thread 249 * @param bb buffer containing the frame's ID 250 * @return the desired frame 251 */ getFrame(Thread thread, long frameID)252 public static native VMFrame getFrame(Thread thread, long frameID) 253 throws JdwpException; 254 255 /** 256 * Returns the number of frames in the thread's stack 257 * 258 * @param thread the thread for which to get a frame count 259 * @return the number of frames in the thread's stack 260 */ getFrameCount(Thread thread)261 public static native int getFrameCount(Thread thread) 262 throws JdwpException; 263 264 265 /** 266 * Returns the status of a thread 267 * 268 * @param thread the thread for which to get status 269 * @return integer status of the thread 270 * @see JdwpConstants.ThreadStatus 271 */ getThreadStatus(Thread thread)272 public static native int getThreadStatus(Thread thread) 273 throws JdwpException; 274 275 /** 276 * Returns a list of all classes which this class loader has been 277 * requested to load 278 * 279 * @param cl the class loader 280 * @return a list of all visible classes 281 */ getLoadRequests(ClassLoader cl)282 public static native ArrayList getLoadRequests(ClassLoader cl) 283 throws JdwpException; 284 285 /** 286 * Executes a method in the virtual machine. The thread must already 287 * be suspended by a previous event. When the method invocation is 288 * complete, the thread (or all threads if INVOKE_SINGLE_THREADED is 289 * not set in options) must be suspended before this method returns. 290 * 291 * @param obj instance in which to invoke method (null for static) 292 * @param thread the thread in which to invoke the method 293 * @param clazz the class in which the method is defined 294 * @param method the method to invoke 295 * @param values arguments to pass to method 296 * @param options invocation options 297 * @return a result object containing the results of the invocation 298 */ executeMethod(Object obj, Thread thread, Class clazz, VMMethod method, Value[] values, int options)299 public static native MethodResult executeMethod (Object obj, Thread thread, 300 Class clazz, VMMethod method, 301 Value[] values, 302 int options) 303 throws JdwpException; 304 305 /** 306 * "Returns the name of source file in which a reference type was declared" 307 * 308 * @param clazz the class for which to return a source file 309 * @return a string containing the source file name; "no path information 310 * for the file is included" 311 */ getSourceFile(Class clazz)312 public static native String getSourceFile(Class clazz) 313 throws JdwpException; 314 315 /** 316 * Register a request from the debugger 317 * 318 * Virtual machines have two options. Either do nothing and allow 319 * the event manager to take care of the request (useful for broadcast-type 320 * events like class prepare/load/unload, thread start/end, etc.) 321 * or do some internal work to set up the event notification (useful for 322 * execution-related events like breakpoints, single-stepping, etc.). 323 */ registerEvent(EventRequest request)324 public static native void registerEvent(EventRequest request) 325 throws JdwpException; 326 327 /** 328 * Unregisters the given request 329 * 330 * @param request the request to unregister 331 */ unregisterEvent(EventRequest request)332 public static native void unregisterEvent(EventRequest request) 333 throws JdwpException; 334 335 336 /** 337 * Clear all events of the given kind 338 * 339 * @param kind the type of events to clear 340 */ clearEvents(byte kind)341 public static native void clearEvents(byte kind) 342 throws JdwpException; 343 344 /** 345 * Redefines the given types. VM must support canRedefineClasses 346 * capability (may also require canAddMethod and/or 347 * canUnrestrictedlyRedefineClasses capabilities) 348 * 349 * @param types the classes to redefine 350 * @param bytecodes the new bytecode definitions for the classes 351 */ redefineClasses(Class[] types, byte[][] bytecodes)352 public static native void redefineClasses(Class[] types, byte[][] bytecodes) 353 throws JdwpException; 354 355 /** 356 * Sets the default stratum. VM must support the 357 * canSetDefaultStratum capability. 358 * 359 * @param stratum the new default stratum or empty string to 360 * use the reference default 361 */ setDefaultStratum(String stratum)362 public static native void setDefaultStratum(String stratum) 363 throws JdwpException; 364 365 /** 366 * Returns the source debug extension. VM must support the 367 * canGetSourceDebugExtension capability. 368 * 369 * @param klass the class for which to return information 370 * @returns the source debug extension 371 */ getSourceDebugExtension(Class klass)372 public static native String getSourceDebugExtension(Class klass) 373 throws JdwpException; 374 375 /** 376 * Returns the bytecode for the given method. VM must support the 377 * canGetBytecodes capability. 378 * 379 * @param method the method for which to get bytecodes 380 * @returns the bytecodes 381 */ getBytecodes(VMMethod method)382 public static native byte[] getBytecodes(VMMethod method) 383 throws JdwpException; 384 385 /** 386 * Returns monitor information about an object. VM must support 387 * the canGetMonitorInformation capability. 388 * 389 * @param obj the object 390 * @returns monitor information (owner, entry count, waiters) 391 */ getMonitorInfo(Object obj)392 public static native MonitorInfo getMonitorInfo(Object obj) 393 throws JdwpException; 394 395 /** 396 * Returns a list of owned monitors. VM must support the 397 * canGetOwnedMonitorInfo capability. 398 * 399 * @param thread a thread 400 * @returns the list of monitors owned by this thread 401 */ getOwnedMonitors(Thread thread)402 public static native Object[] getOwnedMonitors(Thread thread) 403 throws JdwpException; 404 405 /** 406 * Returns the current contended monitor for a thread. VM must 407 * support canGetCurrentContendedMonitor capability. 408 * 409 * @param thread the thread 410 * @returns the contended monitor 411 */ getCurrentContendedMonitor(Thread thread)412 public static native Object getCurrentContendedMonitor(Thread thread) 413 throws JdwpException; 414 415 /** 416 * Pop all frames up to and including the given frame. VM must 417 * support canPopFrames capability. It is the responsibility 418 * of the VM to check if the thread is suspended. If it is not, 419 * the VM should throw ThreadNotSuspendedException. 420 * 421 * @param thread the thread 422 * @param frame the frame ID 423 */ popFrames(Thread thread, long frameId)424 public static native void popFrames(Thread thread, long frameId); 425 } 426