edu.rice.cs.drjava.model.debug.jpda
Class JPDADebugger

java.lang.Object
  extended by edu.rice.cs.drjava.model.debug.jpda.JPDADebugger
All Implemented Interfaces:
Debugger

public class JPDADebugger
extends Object
implements Debugger

An integrated debugger which attaches to the Interactions JVM using Sun's Java Platform Debugger Architecture (JPDA/JDI) interface. Every public method in this class throws an llegalStateException if it is called while the debugger is not active, except for isAvailable, isReady, and startUp. Public methods also throw a DebugException if the EventHandlerThread has caught an exception.

Version:
$Id: JPDADebugger.java 5611 2012-07-25 15:03:33Z rcartwright $

Nested Class Summary
protected static class JPDADebugger.DelegatingLocation
          A Location that delegates to another location in all cases except for line number, source path and source name.
private static class JPDADebugger.RandomAccessStack
          A thread-safe stack from which you can remove any element, not just the top of the stack.
 
Nested classes/interfaces inherited from interface edu.rice.cs.drjava.model.debug.Debugger
Debugger.StepType
 
Field Summary
private  Throwable _eventHandlerError
          If not null, this field holds an error caught by the EventHandlerThread.
private  com.sun.jdi.request.EventRequestManager _eventManager
          Manages all event requests in JDI.
private  com.sun.jdi.ObjectReference _interpreterJVM
          A handle to the interpreterJVM that we need so we can populate the environment.
private  boolean _isAutomaticTraceEnabled
           
private static Log _log
          A log for recording messages in a file.
private  GlobalModel _model
          Reference to DrJava's model.
(package private)  DebugEventNotifier _notifier
          Provides a way for the JPDADebugger to communicate with the view.
private  PendingRequestManager _pendingRequestManager
          Keeps track of any DebugActions whose classes have not yet been loaded, so that EventRequests can be created when the correct ClassPrepareEvent occurs.
private  com.sun.jdi.ThreadReference _runningThread
          The running ThreadReference that we are debugging.
private  JPDADebugger.RandomAccessStack _suspendedThreads
          Storage for all the threads suspended by this debugger.
private  com.sun.jdi.VirtualMachine _vm
          VirtualMachine of the interactions JVM.
private  ArrayList<DebugWatchData> _watches
          Vector of all current Watches.
private  InteractionsListener _watchListener
           
private static String ADD_INTERPRETER_SIG
          Signature of the InterpreterJVM.addInterpreter method.
private static String GET_VARIABLE_VALUE_SIG
          Signature of the InterpreterJVM.getVariableValue method.
private static String NEW_INSTANCE_SIG
           
private static int OBJECT_COLLECTED_TRIES
           
 
Constructor Summary
JPDADebugger(GlobalModel model)
          Builds a new JPDADebugger to debug code in the Interactions JVM, using the JPDA/JDI interfaces.
 
Method Summary
private  void _attachToVM()
          Handles the details of attaching to the interpreterJVM.
private  com.sun.jdi.ObjectReference _box(com.sun.jdi.PrimitiveValue val, com.sun.jdi.ThreadReference thread, List<com.sun.jdi.ObjectReference> toRelease)
          Create a boxed object corresponding to the given primitive.
private  void _copyVariablesFromInterpreter()
          Assumes lock is already held.
private  void _currThreadResumed()
          Notifies all listeners that the current thread has been resumed.
private  void _dumpVariablesIntoInterpreterAndSwitch()
          Copy the current selected thread's visible variables (those in scope) into an interpreter's environment and then switch the Interactions window's interpreter to that interpreter.
private  void _ensureReady()
          Ensures that debugger is active.
private  com.sun.jdi.connect.AttachingConnector _getAttachingConnector()
          Returns an attaching connector to use for connecting to the interpreter JVM.
private  com.sun.jdi.ReferenceType _getClass(String name)
          Get a reference type corresponding to the class with the given name.
private  String _getPromptString(com.sun.jdi.ThreadReference threadRef)
           
private static com.sun.jdi.Value _getStaticField(com.sun.jdi.ReferenceType location, String name)
          Get the value of the given static field, and handle any errors that may arise.
private  com.sun.jdi.ThreadReference _getThreadFromDebugThreadData(DebugThreadData d)
          Assumes lock is already held.
private  String _getUniqueThreadName(com.sun.jdi.ThreadReference thread)
          Returns a unique name for the given thread.
private  void _hideWatches()
          Hides all of the values of the watches and their types.
private static com.sun.jdi.Value _invokeConstructor(com.sun.jdi.ThreadReference thread, com.sun.jdi.ClassType location, String signature, com.sun.jdi.Value... args)
          Invoke a constructor of the given class, and handle any errors that may arise.
private static com.sun.jdi.Value _invokeMethod(com.sun.jdi.ThreadReference thread, com.sun.jdi.ObjectReference receiver, String name, String signature, com.sun.jdi.Value... args)
          Invoke the given method, and handle any errors that may arise.
private static com.sun.jdi.Value _invokeStaticMethod(com.sun.jdi.ThreadReference thread, com.sun.jdi.ClassType location, String name, String signature, com.sun.jdi.Value... args)
          Invoke the given static method, and handle any errors that may arise.
private  void _log(String message)
          Logs any unexpected behavior that occurs (but which should not cause DrJava to abort).
private  void _log(String message, Throwable t)
          Logs any unexpected behavior that occurs (but which should not cause DrJava to abort).
private  com.sun.jdi.ArrayReference _mirrorArray(String elementClass, List<? extends com.sun.jdi.ObjectReference> elts, com.sun.jdi.ThreadReference thread, List<com.sun.jdi.ObjectReference> toRelease)
          Create an array of the given elements in the VM and prevent it from being garbage collected.
private  com.sun.jdi.StringReference _mirrorString(String s, List<com.sun.jdi.ObjectReference> toRelease)
          Create a String in the VM and prevent it from being garbage collected.
private  void _removeAllDebugInterpreters()
          Removes all of the debug interpreters as part of shutting down.
private  void _removeCurrentDebugInterpreter(boolean fromStep)
          Removes the current debug interpreter upon resuming the current thread.
private  void _resumeFromStep()
          Resumes the thread currently being debugged without removing the debug interpreter or switching to the next suspended thread.
private  void _resumeHelper(boolean fromStep)
          Resumes execution of the currently suspended thread.
private  void _resumeThread(com.sun.jdi.ThreadReference thread, boolean fromStep)
          Resumes the given thread, only copying variables from its debug interpreter if shouldCopyBack is true.
private  void _stepHelper(Debugger.StepType type, boolean shouldNotify)
          Performs a step in the currently suspended thread, only generating a step event if shouldNotify if true.
private  void _switchToInterpreterForThreadReference(com.sun.jdi.ThreadReference threadRef)
          Switches the current interpreter to the one corresponding to threadRef.
private  void _switchToSuspendedThread()
          Calls the real switchToSuspendedThread, telling it to updateWatches.
private  void _switchToSuspendedThread(com.sun.jdi.request.BreakpointRequest request)
          Calls the real switchToSuspendedThread, telling it to updateWatches.
private  void _switchToSuspendedThread(com.sun.jdi.request.BreakpointRequest request, boolean updateWatches)
          Performs the bookkeeping to switch to the suspened thread on the top of the _suspendedThreads stack.
private  com.sun.jdi.PrimitiveValue _unbox(com.sun.jdi.ObjectReference val, com.sun.jdi.ThreadReference thread)
          Create an unboxed primitive corresponding to the given object.
private  void _updateWatches()
          Updates the stored value of each watched field and variable.
 void addListener(DebugListener listener)
          Adds a listener to this JPDADebugger.
 void addWatch(String field)
          Adds a watch on the given field or variable.
 DebugModelCallback callback()
           
(package private)  void currThreadDied()
          Notifies all listeners that the current thread has died.
(package private)  void currThreadSuspended()
          Notifies all listeners that the current thread has been suspended.
(package private)  void currThreadSuspended(com.sun.jdi.request.BreakpointRequest request)
          Notifies all listeners that the current thread has been suspended.
(package private)  void eventHandlerError(Throwable t)
          Records that an error occurred in the EventHandlerThread.
 Breakpoint getBreakpoint(int line, String className)
          Gets the Breakpoint object at the specified line in the given class.
(package private)  com.sun.jdi.ThreadReference getCurrentRunningThread()
          Returns the running thread currently tracked by the debugger.
 ArrayList<DebugStackData> getCurrentStackFrameData()
          Returns a Vector of DebugStackData for the current suspended thread.
(package private)  com.sun.jdi.ThreadReference getCurrentThread()
          Returns the currently selected thread for the debugger.
 ArrayList<DebugThreadData> getCurrentThreadData()
          Returns a list of all threads being tracked by the debugger.
(package private)  com.sun.jdi.request.EventRequestManager getEventRequestManager()
          Returns the current EventRequestManager from JDI, or null if startUp() has not been called.
 com.sun.jdi.Location getLLLocation(com.sun.jdi.Location l, List<File> files)
          Return a JDI location that matches the given location, but Java line numbers have been mapped to LL line numbers.
 StackTraceElement getLLStackTraceElement(com.sun.jdi.Location l, List<File> files)
          Return a stack trace element that matches the given location, but Java line numbers have been mapped to LL line numbers.
 LanguageLevelStackTraceMapper getLLSTM()
          Gets the LanguageLevelStackTraceMapper
(package private)  PendingRequestManager getPendingRequestManager()
          Returns the pending request manager used by the debugger.
(package private)  Vector<com.sun.jdi.ReferenceType> getReferenceTypes(String className, int lineNumber)
          Returns a Vector with the loaded ReferenceTypes for the given class name (empty if the class could not be found).
(package private)  com.sun.jdi.ThreadReference getThreadAt(int i)
          Returns the suspended thread at the current index of the stack.
(package private)  com.sun.jdi.VirtualMachine getVM()
          Accessor for the _vm field.
 ArrayList<DebugWatchData> getWatches()
          Returns all currently watched fields and variables.
 boolean hasRunningThread()
          Returns whether the thread the debugger is tracking is now running.
 boolean hasSuspendedThreads()
          Returns whether the debugger currently has any suspended threads.
 boolean isAutomaticTraceEnabled()
          Returns whether automatic trace has been enabled within the debugger
 boolean isAvailable()
          Returns whether the debugger is available in this copy of DrJava.
 boolean isCurrentThreadSuspended()
          Returns whether the debugger's current thread is suspended.
static boolean isJavaIdentifier(String s)
           
 boolean isReady()
          Returns whether the debugger is currently enabled.
static boolean isSimpleVariableOrFieldAccess(String var)
          Checks whether the argument is a valid variable or field access.
 int LLBreakpointLineNum(Breakpoint breakpoint)
          Returns the line number of the breakpoint, possibly mapped from LL to Java if the breakpoint is set in a language level file.
(package private)  void nonCurrThreadDied()
           
 void notifyBreakpointChange(Breakpoint breakpoint)
          Enable or disable the specified breakpoint.
(package private)  void notifyDebuggerShutdown()
          Notifies all listeners that the debugger has shut down.
(package private)  void notifyDebuggerStarted()
          Notifies all listeners that the debugger has started.
(package private)  void notifyStepRequested()
          Notifies all listeners that a step has been requested.
private  void openAndScroll(OpenDefinitionsDocument doc, int line, String className, boolean shouldHighlight)
          Opens a document and scrolls to the appropriate location.
private  void openAndScroll(OpenDefinitionsDocument doc, com.sun.jdi.Location location, boolean shouldHighlight)
          Opens a document and scrolls to the appropriate location.
 Pair<com.sun.jdi.Location,OpenDefinitionsDocument> preloadDocument(com.sun.jdi.Location location)
          Return the adjusted location (identical to input unless the matching document is a LL file) and document associated with this location generated by the JVM and hence associated with a conventional Java (not an LL) file.
(package private)  void printMessage(String message)
          Prints a message in the Interactions Pane.
(package private)  void reachedBreakpoint(com.sun.jdi.request.BreakpointRequest request)
          Called when a breakpoint is reached.
 void removeAllWatches()
          Removes all watches on existing fields and variables.
 void removeBreakpoint(Breakpoint bp)
          Removes a breakpoint.
 void removeListener(DebugListener listener)
          Removes a listener to this JPDADebugger.
 void removeWatch(int index)
          Removes the watch at the given index.
 void removeWatch(String field)
          Removes any watches on the given field or variable.
 void resume()
          Resumes the thread currently being debugged, copying back all variables from the current debug interpreter.
 void resume(DebugThreadData threadData)
          Resumes the given thread, copying back any variables from its associated debug interpreter.
 void scrollToSource(Breakpoint bp)
          Scrolls to the source of the given breakpoint.
 void scrollToSource(Breakpoint bp, boolean shouldHighlight)
          Scrolls to the source of the given breakpoint.
 void scrollToSource(DebugStackData stackData)
          Scrolls to the source location specified by the the debug stack data.
private  void scrollToSource(com.sun.jdi.Location location)
          Scroll to the location specified by location Assumes lock on this is already held
private  void scrollToSource(com.sun.jdi.Location location, boolean shouldHighlight)
          Scroll to the location specified by location.
 void setAutomaticTraceEnabled(boolean e)
          Enables or disables automatic trace.
 void setBreakpoint(Breakpoint breakpoint)
          Sets a breakpoint.
 void setCurrentThread(DebugThreadData threadData)
          Sets the notion of current thread to the one contained in threadData.
(package private)  boolean setCurrentThread(com.sun.jdi.ThreadReference thread)
          Sets the debugger's currently active thread.
 void shutdown()
          Disconnects the debugger from the Interactions JVM and cleans up any state.
 void startUp()
          Attaches the debugger to the Interactions JVM to prepare for debugging.
 void step(Debugger.StepType type)
          Steps the execution of the currently loaded document.
(package private)  void threadStarted()
           
 boolean toggleBreakpoint(OpenDefinitionsDocument doc, int offset, boolean isEnabled)
          Toggles whether a breakpoint is set at the given line in the given document.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

_log

private static final Log _log
A log for recording messages in a file.


OBJECT_COLLECTED_TRIES

private static final int OBJECT_COLLECTED_TRIES
See Also:
Constant Field Values

ADD_INTERPRETER_SIG

private static final String ADD_INTERPRETER_SIG
Signature of the InterpreterJVM.addInterpreter method.

See Also:
InterpreterJVM.addInterpreter(java.lang.String), _dumpVariablesIntoInterpreterAndSwitch(), Constant Field Values

GET_VARIABLE_VALUE_SIG

private static final String GET_VARIABLE_VALUE_SIG
Signature of the InterpreterJVM.getVariableValue method.

See Also:
InterpreterJVM.getVariableValue(java.lang.String), _copyVariablesFromInterpreter(), Constant Field Values

NEW_INSTANCE_SIG

private static final String NEW_INSTANCE_SIG
See Also:
Constant Field Values

_model

private volatile GlobalModel _model
Reference to DrJava's model.


_vm

private volatile com.sun.jdi.VirtualMachine _vm
VirtualMachine of the interactions JVM.


_eventManager

private volatile com.sun.jdi.request.EventRequestManager _eventManager
Manages all event requests in JDI.


_watches

private final ArrayList<DebugWatchData> _watches
Vector of all current Watches.


_pendingRequestManager

private final PendingRequestManager _pendingRequestManager
Keeps track of any DebugActions whose classes have not yet been loaded, so that EventRequests can be created when the correct ClassPrepareEvent occurs.


_notifier

final DebugEventNotifier _notifier
Provides a way for the JPDADebugger to communicate with the view.


_runningThread

private volatile com.sun.jdi.ThreadReference _runningThread
The running ThreadReference that we are debugging.


_suspendedThreads

private volatile JPDADebugger.RandomAccessStack _suspendedThreads
Storage for all the threads suspended by this debugger. The "current" thread is the top one on the stack.


_interpreterJVM

private volatile com.sun.jdi.ObjectReference _interpreterJVM
A handle to the interpreterJVM that we need so we can populate the environment.


_watchListener

private volatile InteractionsListener _watchListener

_eventHandlerError

private volatile Throwable _eventHandlerError
If not null, this field holds an error caught by the EventHandlerThread.


_isAutomaticTraceEnabled

private volatile boolean _isAutomaticTraceEnabled
Constructor Detail

JPDADebugger

public JPDADebugger(GlobalModel model)
Builds a new JPDADebugger to debug code in the Interactions JVM, using the JPDA/JDI interfaces. Does not actually connect to the interpreterJVM until startUp().

Method Detail

_log

private void _log(String message)
Logs any unexpected behavior that occurs (but which should not cause DrJava to abort).

Parameters:
message - message to print to the log

_log

private void _log(String message,
                  Throwable t)
Logs any unexpected behavior that occurs (but which should not cause DrJava to abort).

Parameters:
message - message to print to the log
t - Exception or Error being logged

addListener

public void addListener(DebugListener listener)
Adds a listener to this JPDADebugger.

Specified by:
addListener in interface Debugger
Parameters:
listener - a listener that reacts on events generated by the JPDADebugger

removeListener

public void removeListener(DebugListener listener)
Removes a listener to this JPDADebugger.

Specified by:
removeListener in interface Debugger
Parameters:
listener - listener to remove

isAvailable

public boolean isAvailable()
Returns whether the debugger is available in this copy of DrJava. This method does not indicate whether the debugger is ready to be used, which is indicated by isReady().

Specified by:
isAvailable in interface Debugger

callback

public DebugModelCallback callback()
Specified by:
callback in interface Debugger

isReady

public boolean isReady()
Returns whether the debugger is currently enabled.

Specified by:
isReady in interface Debugger

startUp

public void startUp()
             throws DebugException
Attaches the debugger to the Interactions JVM to prepare for debugging. Only runs in event thread.

Specified by:
startUp in interface Debugger
Throws:
DebugException

shutdown

public void shutdown()
Disconnects the debugger from the Interactions JVM and cleans up any state.

Specified by:
shutdown in interface Debugger
Throws:
IllegalStateException - if debugger is not ready

setCurrentThread

public void setCurrentThread(DebugThreadData threadData)
                      throws DebugException
Sets the notion of current thread to the one contained in threadData. The thread must be suspended. (Note: the intention is for this method to suspend the thread if necessary, but this is not yet implemented. The catch is that any manually suspended threads won't cooperate with the debug interpreters; the thread must be suspended by a breakpoint or step.)

Specified by:
setCurrentThread in interface Debugger
Parameters:
threadData - The Thread to set as current.
Throws:
IllegalStateException - if debugger is not ready
IllegalArgumentException - if threadData is null or not suspended
DebugException

getCurrentThread

com.sun.jdi.ThreadReference getCurrentThread()
Returns the currently selected thread for the debugger.


hasSuspendedThreads

public boolean hasSuspendedThreads()
                            throws DebugException
Returns whether the debugger currently has any suspended threads.

Specified by:
hasSuspendedThreads in interface Debugger
Returns:
true if there are any threads in the program currently being debugged which have been suspended (by the user or by hitting a breakpoint).
Throws:
DebugException

isCurrentThreadSuspended

public boolean isCurrentThreadSuspended()
                                 throws DebugException
Returns whether the debugger's current thread is suspended.

Specified by:
isCurrentThreadSuspended in interface Debugger
Throws:
DebugException

hasRunningThread

public boolean hasRunningThread()
                         throws DebugException
Returns whether the thread the debugger is tracking is now running.

Specified by:
hasRunningThread in interface Debugger
Throws:
DebugException

resume

public void resume()
            throws DebugException
Resumes the thread currently being debugged, copying back all variables from the current debug interpreter.

Specified by:
resume in interface Debugger
Throws:
DebugException

setAutomaticTraceEnabled

public void setAutomaticTraceEnabled(boolean e)
Enables or disables automatic trace.

Specified by:
setAutomaticTraceEnabled in interface Debugger

isAutomaticTraceEnabled

public boolean isAutomaticTraceEnabled()
Description copied from interface: Debugger
Returns whether automatic trace has been enabled within the debugger

Specified by:
isAutomaticTraceEnabled in interface Debugger

resume

public void resume(DebugThreadData threadData)
            throws DebugException
Resumes the given thread, copying back any variables from its associated debug interpreter.

Specified by:
resume in interface Debugger
Parameters:
threadData - Thread to resume
Throws:
DebugException

step

public void step(Debugger.StepType type)
          throws DebugException
Steps the execution of the currently loaded document.

Specified by:
step in interface Debugger
Throws:
DebugException

isSimpleVariableOrFieldAccess

public static boolean isSimpleVariableOrFieldAccess(String var)
Checks whether the argument is a valid variable or field access.

Parameters:
var - the name of the field
Returns:
true if the argument is a valid variable or field access

isJavaIdentifier

public static boolean isJavaIdentifier(String s)
Returns:
true if s is a valid Java identifier.

addWatch

public void addWatch(String field)
              throws DebugException
Adds a watch on the given field or variable.

Specified by:
addWatch in interface Debugger
Parameters:
field - the name of the field we will watch
Throws:
DebugException

removeWatch

public void removeWatch(String field)
                 throws DebugException
Removes any watches on the given field or variable. Has no effect if the given field is not being watched.

Specified by:
removeWatch in interface Debugger
Parameters:
field - the name of the field we will watch
Throws:
DebugException

removeWatch

public void removeWatch(int index)
                 throws DebugException
Removes the watch at the given index.

Specified by:
removeWatch in interface Debugger
Parameters:
index - Index of the watch to remove
Throws:
DebugException

removeAllWatches

public void removeAllWatches()
                      throws DebugException
Removes all watches on existing fields and variables.

Specified by:
removeAllWatches in interface Debugger
Throws:
DebugException

notifyBreakpointChange

public void notifyBreakpointChange(Breakpoint breakpoint)
Enable or disable the specified breakpoint.

Parameters:
breakpoint - breakpoint to change

toggleBreakpoint

public boolean toggleBreakpoint(OpenDefinitionsDocument doc,
                                int offset,
                                boolean isEnabled)
                         throws DebugException
Toggles whether a breakpoint is set at the given line in the given document.

Specified by:
toggleBreakpoint in interface Debugger
Parameters:
doc - Document in which to set or remove the breakpoint
offset - Start offset on the line to set the breakpoint
isEnabled - true if this breakpoint should be enabled
Returns:
true if breakpoint is set
Throws:
DebugException

setBreakpoint

public void setBreakpoint(Breakpoint breakpoint)
                   throws DebugException
Sets a breakpoint.

Specified by:
setBreakpoint in interface Debugger
Parameters:
breakpoint - The new breakpoint to set
Throws:
DebugException

LLBreakpointLineNum

public int LLBreakpointLineNum(Breakpoint breakpoint)
Returns the line number of the breakpoint, possibly mapped from LL to Java if the breakpoint is set in a language level file.


getLLStackTraceElement

public StackTraceElement getLLStackTraceElement(com.sun.jdi.Location l,
                                                List<File> files)
Return a stack trace element that matches the given location, but Java line numbers have been mapped to LL line numbers.

Parameters:
l - location with Java line numbers
files - open LL files
Returns:
stack trace element with LL line numbers

getLLLocation

public com.sun.jdi.Location getLLLocation(com.sun.jdi.Location l,
                                          List<File> files)
Return a JDI location that matches the given location, but Java line numbers have been mapped to LL line numbers.

Parameters:
l - location with Java line numbers
files - open LL files
Returns:
JDI location with LL line numbers

removeBreakpoint

public void removeBreakpoint(Breakpoint bp)
                      throws DebugException
Removes a breakpoint. Called from toggleBreakpoint -- even with BPs that are not active.

Specified by:
removeBreakpoint in interface Debugger
Parameters:
bp - The breakpoint to remove.
Throws:
DebugException

getWatches

public ArrayList<DebugWatchData> getWatches()
                                     throws DebugException
Returns all currently watched fields and variables. No synchronization required because _watches is final.

Specified by:
getWatches in interface Debugger
Throws:
DebugException

getCurrentThreadData

public ArrayList<DebugThreadData> getCurrentThreadData()
                                                throws DebugException
Returns a list of all threads being tracked by the debugger. Does not return any threads known to be dead.

Specified by:
getCurrentThreadData in interface Debugger
Throws:
DebugException

getCurrentStackFrameData

public ArrayList<DebugStackData> getCurrentStackFrameData()
                                                   throws DebugException
Returns a Vector of DebugStackData for the current suspended thread.

Specified by:
getCurrentStackFrameData in interface Debugger
Throws:
DebugException - if the current thread is running or there are no suspended threads TO DO: Config option for hiding DrJava subset of stack trace

preloadDocument

public Pair<com.sun.jdi.Location,OpenDefinitionsDocument> preloadDocument(com.sun.jdi.Location location)
Return the adjusted location (identical to input unless the matching document is a LL file) and document associated with this location generated by the JVM and hence associated with a conventional Java (not an LL) file. A document is preloaded when a debugger step occurs. This method was originally intended to avoid the deadlock described in [ 1696060 ] Debugger Infinite Loop. but all debugger actions now occur in the Event thread and synchronization has been elided.


scrollToSource

public void scrollToSource(DebugStackData stackData)
                    throws DebugException
Scrolls to the source location specified by the the debug stack data.

Specified by:
scrollToSource in interface Debugger
Parameters:
stackData - Stack data containing location to display
Throws:
DebugException - if current thread is not suspended

scrollToSource

public void scrollToSource(Breakpoint bp)
Scrolls to the source of the given breakpoint.

Specified by:
scrollToSource in interface Debugger
Parameters:
bp - the breakpoint

scrollToSource

public void scrollToSource(Breakpoint bp,
                           boolean shouldHighlight)
Scrolls to the source of the given breakpoint.

Parameters:
bp - the breakpoint

getBreakpoint

public Breakpoint getBreakpoint(int line,
                                String className)
Gets the Breakpoint object at the specified line in the given class. If the given data do not correspond to an actual breakpoint, null is returned.

Specified by:
getBreakpoint in interface Debugger
Parameters:
line - The line number of the breakpoint
className - The name of the class the breakpoint's in
Returns:
the Breakpoint corresponding to the line and className, or null if there is no such breakpoint.

getVM

com.sun.jdi.VirtualMachine getVM()
Accessor for the _vm field. Called from DocumentDebugAction and this.


getEventRequestManager

com.sun.jdi.request.EventRequestManager getEventRequestManager()
Returns the current EventRequestManager from JDI, or null if startUp() has not been called.


getPendingRequestManager

PendingRequestManager getPendingRequestManager()
Returns the pending request manager used by the debugger.


getThreadAt

com.sun.jdi.ThreadReference getThreadAt(int i)
Returns the suspended thread at the current index of the stack.

Parameters:
i - index into the stack of suspended threads

getCurrentRunningThread

com.sun.jdi.ThreadReference getCurrentRunningThread()
Returns the running thread currently tracked by the debugger.


_ensureReady

private void _ensureReady()
                   throws DebugException
Ensures that debugger is active. Should be called by every public method in the debugger except for startUp(). Assumes lock is already held.

Throws:
IllegalStateException - if debugger is not active
DebugException - if an exception was detected in the EventHandlerThread

eventHandlerError

void eventHandlerError(Throwable t)
Records that an error occurred in the EventHandlerThread. The next call to _ensureReady() will fail, indicating that the error occurred. Not private because EventHandlerThread accesses it.

Parameters:
t - Error occurring in the EventHandlerThread

_attachToVM

private void _attachToVM()
                  throws DebugException
Handles the details of attaching to the interpreterJVM. Only runs in the event thread.

Throws:
DebugException

_getAttachingConnector

private com.sun.jdi.connect.AttachingConnector _getAttachingConnector()
                                                               throws DebugException
Returns an attaching connector to use for connecting to the interpreter JVM.

Throws:
DebugException

setCurrentThread

boolean setCurrentThread(com.sun.jdi.ThreadReference thread)
Sets the debugger's currently active thread. This method assumes that the given thread is already suspended. Returns true if this actually changed the suspended thread by pushing it onto the stack of suspended threads. Returns false if this thread was already selected. The return value fixes a bug that occurs if the user steps into a breakpoint.

Throws:
IllegalArgumentException - if thread is not suspended.

getReferenceTypes

Vector<com.sun.jdi.ReferenceType> getReferenceTypes(String className,
                                                    int lineNumber)
Returns a Vector with the loaded ReferenceTypes for the given class name (empty if the class could not be found). Makes no attempt to load the class if it is not already loaded. If the lineNumber is not DebugAction.ANY_LINE, this method ensures that the returned ReferenceTypes contain the given lineNumber, searching through inner classes if necessary. If no inner classes contain the line number, an empty Vector is returned.

If custom class loaders are in use, multiple copies of the class may be loaded, so all are returned.


_getThreadFromDebugThreadData

private com.sun.jdi.ThreadReference _getThreadFromDebugThreadData(DebugThreadData d)
                                                           throws NoSuchElementException
Assumes lock is already held.

Returns:
The thread in the virtual machine with name d.uniqueID()
Throws:
NoSuchElementException - if the thread could not be found

_resumeFromStep

private void _resumeFromStep()
                      throws DebugException
Resumes the thread currently being debugged without removing the debug interpreter or switching to the next suspended thread. Assumes lock is already held.

Throws:
DebugException

_resumeHelper

private void _resumeHelper(boolean fromStep)
                    throws DebugException
Resumes execution of the currently suspended thread. Assumes lock is already held.

Parameters:
fromStep - Whether to copy back the variables from the current debug interpreter and switch to the next suspended thread.
Throws:
DebugException

_resumeThread

private void _resumeThread(com.sun.jdi.ThreadReference thread,
                           boolean fromStep)
                    throws DebugException
Resumes the given thread, only copying variables from its debug interpreter if shouldCopyBack is true. Assumes lock on this is already held.

Parameters:
thread - Thread to resume
fromStep - Whether to copy back the variables from the current debug interpreter and switch to the next suspended thread.
Throws:
IllegalArgumentException - if thread is null
DebugException

_stepHelper

private void _stepHelper(Debugger.StepType type,
                         boolean shouldNotify)
                  throws DebugException
Performs a step in the currently suspended thread, only generating a step event if shouldNotify if true. Assumes that lock is already held.

Parameters:
type - The type of step to perform
shouldNotify - Whether to generate a step event
Throws:
DebugException

reachedBreakpoint

void reachedBreakpoint(com.sun.jdi.request.BreakpointRequest request)
Called when a breakpoint is reached. The Breakpoint object itself should be stored in the "debugAction" property on the request.

Parameters:
request - The BreakPointRequest reached by the debugger

scrollToSource

private void scrollToSource(com.sun.jdi.Location location)
Scroll to the location specified by location Assumes lock on this is already held


scrollToSource

private void scrollToSource(com.sun.jdi.Location location,
                            boolean shouldHighlight)
Scroll to the location specified by location.


openAndScroll

private void openAndScroll(OpenDefinitionsDocument doc,
                           com.sun.jdi.Location location,
                           boolean shouldHighlight)
Opens a document and scrolls to the appropriate location. If doc is null, a message is printed indicating the source file could not be found. Assumes lock on this is already held.

Parameters:
doc - Document to open
location - Location to display

openAndScroll

private void openAndScroll(OpenDefinitionsDocument doc,
                           int line,
                           String className,
                           boolean shouldHighlight)
Opens a document and scrolls to the appropriate location. If doc is null, a message is printed indicating the source file could not be found. Assumes lock on this is already held.

Parameters:
doc - Document to open
line - the line number to display
className - the name of the appropriate class

printMessage

void printMessage(String message)
Prints a message in the Interactions Pane. Not synchronized on this on this because no local state is accessed.

Parameters:
message - Message to display

_hideWatches

private void _hideWatches()
Hides all of the values of the watches and their types. Called when there is no debug information. Assumes lock is already held.


_updateWatches

private void _updateWatches()
Updates the stored value of each watched field and variable. Synchronization is necessary because this method is called from unsynchronized listeners.


_dumpVariablesIntoInterpreterAndSwitch

private void _dumpVariablesIntoInterpreterAndSwitch()
                                             throws DebugException
Copy the current selected thread's visible variables (those in scope) into an interpreter's environment and then switch the Interactions window's interpreter to that interpreter.

Throws:
DebugException

_getPromptString

private String _getPromptString(com.sun.jdi.ThreadReference threadRef)
Returns:
the prompt to display in the itneractions console based upon the ThreadReference threadRef, which is being debugged.

_mirrorString

private com.sun.jdi.StringReference _mirrorString(String s,
                                                  List<com.sun.jdi.ObjectReference> toRelease)
                                           throws DebugException
Create a String in the VM and prevent it from being garbage collected.

Throws:
DebugException

_mirrorArray

private com.sun.jdi.ArrayReference _mirrorArray(String elementClass,
                                                List<? extends com.sun.jdi.ObjectReference> elts,
                                                com.sun.jdi.ThreadReference thread,
                                                List<com.sun.jdi.ObjectReference> toRelease)
                                         throws DebugException
Create an array of the given elements in the VM and prevent it from being garbage collected.

Throws:
DebugException

_box

private com.sun.jdi.ObjectReference _box(com.sun.jdi.PrimitiveValue val,
                                         com.sun.jdi.ThreadReference thread,
                                         List<com.sun.jdi.ObjectReference> toRelease)
                                  throws DebugException
Create a boxed object corresponding to the given primitive.

Throws:
DebugException

_unbox

private com.sun.jdi.PrimitiveValue _unbox(com.sun.jdi.ObjectReference val,
                                          com.sun.jdi.ThreadReference thread)
                                   throws DebugException
Create an unboxed primitive corresponding to the given object.

Throws:
DebugException - If the value is not of a type that can be unboxed, or if an error occurs in the unboxing method invocation.

_getClass

private com.sun.jdi.ReferenceType _getClass(String name)
                                     throws DebugException
Get a reference type corresponding to the class with the given name. Note there is not necessarily a one-to-one correspondence between classes and names -- every class loader can define a class with a certain name -- so we just pick one. Classes defined by the bootstrap class loader have priority over other classes.

Throws:
DebugException - If no loaded class has the given name.

currThreadSuspended

void currThreadSuspended()
Notifies all listeners that the current thread has been suspended. Synchronization is necessary because it is called from unsynchronized listeners and other classes (in same package).


currThreadSuspended

void currThreadSuspended(com.sun.jdi.request.BreakpointRequest request)
Notifies all listeners that the current thread has been suspended. Synchronization is unnecessary because it only runs in the Event thread.

Parameters:
request - The BreakPointRequest reached by the debugger

_switchToSuspendedThread

private void _switchToSuspendedThread()
                               throws DebugException
Calls the real switchToSuspendedThread, telling it to updateWatches. This is what is usually called.

Throws:
DebugException

_switchToSuspendedThread

private void _switchToSuspendedThread(com.sun.jdi.request.BreakpointRequest request)
                               throws DebugException
Calls the real switchToSuspendedThread, telling it to updateWatches. This is what is usually called.

Throws:
DebugException

_switchToSuspendedThread

private void _switchToSuspendedThread(com.sun.jdi.request.BreakpointRequest request,
                                      boolean updateWatches)
                               throws DebugException
Performs the bookkeeping to switch to the suspened thread on the top of the _suspendedThreads stack.

Parameters:
request - The BreakPointRequest reached by the debugger, or null if not a breakpoint
updateWatches - A flag that is false if the current file does not have debug information. This prevents the default interpreter's watch values from being shown.
Throws:
DebugException

_getUniqueThreadName

private String _getUniqueThreadName(com.sun.jdi.ThreadReference thread)
Returns a unique name for the given thread.


_copyVariablesFromInterpreter

private void _copyVariablesFromInterpreter()
                                    throws DebugException
Assumes lock is already held.

Throws:
DebugException
See Also:
InterpreterJVM.getVariableValue(java.lang.String), GET_VARIABLE_VALUE_SIG

_removeAllDebugInterpreters

private void _removeAllDebugInterpreters()
Removes all of the debug interpreters as part of shutting down. Assumes lock is already held.


_removeCurrentDebugInterpreter

private void _removeCurrentDebugInterpreter(boolean fromStep)
Removes the current debug interpreter upon resuming the current thread. Assumes lock on this is already held.

Parameters:
fromStep - A flat switch specifying a switch to the default interpreter since we don't want to switch to the next debug interpreter and display its watch data. We would like to just not have an active interpreter and put up an hourglass over the interactions pane, but the interpreterJVM must have an active interpreter.

_currThreadResumed

private void _currThreadResumed()
                         throws DebugException
Notifies all listeners that the current thread has been resumed. Unsynchronized because invokeLater runs asynchronously. Precondition: assumes that the current thread hasn't yet been resumed

Throws:
DebugException

_switchToInterpreterForThreadReference

private void _switchToInterpreterForThreadReference(com.sun.jdi.ThreadReference threadRef)
Switches the current interpreter to the one corresponding to threadRef. Assumes lock on this is already held.

Parameters:
threadRef - The ThreadRefernce corresponding to the interpreter to switch to

threadStarted

void threadStarted()

currThreadDied

void currThreadDied()
              throws DebugException
Notifies all listeners that the current thread has died. updateThreads is set to true if the threads and stack tables need to be updated, false if there are no suspended threads

Throws:
DebugException

nonCurrThreadDied

void nonCurrThreadDied()

notifyDebuggerShutdown

void notifyDebuggerShutdown()
Notifies all listeners that the debugger has shut down. updateThreads is set to true if the threads and stack tables need to be updated, false if there are no suspended threads


notifyDebuggerStarted

void notifyDebuggerStarted()
Notifies all listeners that the debugger has started.


notifyStepRequested

void notifyStepRequested()
Notifies all listeners that a step has been requested.


_invokeMethod

private static com.sun.jdi.Value _invokeMethod(com.sun.jdi.ThreadReference thread,
                                               com.sun.jdi.ObjectReference receiver,
                                               String name,
                                               String signature,
                                               com.sun.jdi.Value... args)
                                        throws DebugException
Invoke the given method, and handle any errors that may arise. Note that the result does not have garbage collection disabled; if the result is a reference that will be needed later and that is not referenced elsewhere in the VM, garbage collection for it should be immediately disabled (and there's still the possibility that it was collected in the mean time...)

Throws:
DebugException

_invokeStaticMethod

private static com.sun.jdi.Value _invokeStaticMethod(com.sun.jdi.ThreadReference thread,
                                                     com.sun.jdi.ClassType location,
                                                     String name,
                                                     String signature,
                                                     com.sun.jdi.Value... args)
                                              throws DebugException
Invoke the given static method, and handle any errors that may arise. Note that the result does not have garbage collection disabled; if the result is a reference that will be needed later and that is not referenced elsewhere in the VM, garbage collection for it should be immediately disabled (and there's still the possibility that it was collected in the mean time...)

Parameters:
signature - A method signature descriptor to match. For example: "(Ljava/lang/String;)Ljava/lang/Object;".
Throws:
DebugException

_invokeConstructor

private static com.sun.jdi.Value _invokeConstructor(com.sun.jdi.ThreadReference thread,
                                                    com.sun.jdi.ClassType location,
                                                    String signature,
                                                    com.sun.jdi.Value... args)
                                             throws DebugException
Invoke a constructor of the given class, and handle any errors that may arise. Note that the result does not have garbage collection disabled; if the result will be needed later and is not referenced elsewhere in the VM (a likely event, since it was just constructed), garbage collection for it should be immediately disabled (and there's still the possibility that it was collected in the mean time...)

Parameters:
signature - A method signature descriptor matching the corresponding <init> method. For example: "(Ljava/lang/String;)V". The return type will always be void.
Throws:
DebugException

_getStaticField

private static com.sun.jdi.Value _getStaticField(com.sun.jdi.ReferenceType location,
                                                 String name)
                                          throws DebugException
Get the value of the given static field, and handle any errors that may arise. Note the result does not have garbage collection enabled; if the result is a reference that will be needed later and that is not referenced elsewhere in the VM (this would require that the value of the field subsequently changes), garbage collection for it should be immediately disabled (and there's still the possibility that it was collected in the mean time...)

Throws:
DebugException

getLLSTM

public LanguageLevelStackTraceMapper getLLSTM()
Gets the LanguageLevelStackTraceMapper

Returns:
the LanguageLevelStackTraceMapper used by JPDADebugger in the compiler model