How Breakpoints Work
Class Diagram
For an overview of the classes involved, see the
breakpoints.dia
file. This is a diagram created with
GNU Dia, a GNOME Linux application.
Breakpoint Groups
Breakpoint groups are collections of breakpoints. They can be
modified as a whole, which is convenient for users setting lots of
breakpoints.
- Disabling a breakpoint group will mean that the breakpoints
in the group can not truly be enabled. Their state may be enabled
but they will remain effectively disabled so long as the parent
group is disabled.
- There will be a "Default" breakpoint group into
which all new breakpoints are placed. This group will always be
enabled when a new session starts.
- The breakpoint manager will hold the list of breakpoint
groups, inside which all of the breakpoints will reside.
- Breakpoint groups can be inside other breakpoint groups.
Breakpoints
Breakpoints are those objects that cause execution to halt in
the debuggee process. They can be set in any class at any line of
executable code.
- Breakpoints have several states: unresolved, disabled,
expired, skipping
- The 'stop' command will still work, but creates only
a simple breakpoint. More complex options must be configured
through breakpoint dialog.
- Breakpoints will support more than one conditional. For the
breakpoint to halt execution, all of the conditionals must be
satisfied.
- Breakpoints will keep track of how many times they were
hit.
- Breakpoints should probably have colors associated with their
states, so various UI components are consistent overall. Make a
method for getting the breakpoint's "color", so
other classes are easier to write.
- Breakpoints will support more than one monitor. A monitor is
an action that will be performed whenever the breakpoint should
stop.
- Breakpoints define a shouldResume() method that tells whether
or not the execution of the debuggee VM should remain halted.
This is called when a BreakpointEvent has occurred in the
debuggee VM. This method will first check if the breakpoint has
expired or not. Then it will check the set of conditionals to see
if the conditions are satisfied.
- The breakpoint has a shouldResume() method that returns true
if the conditions are not satisfactory for the breakpoint to
cause the debuggee VM to stop executing.
- The breakpoint defines a performStop() method should be
called when the breakpoint has been "hit" so that
monitors are executed.
- Breakpoints need a reset() method to reset all the counts to
zero and return it to unresolved state. This will not affect the
enabled state.
- When the session deactivates, the breakpoints are all
reset.
- When the same session begins again, the breakpoints need to
prepare to resolve themselves.
- Breakpoint manager needs to re-enable itself when the session
activates.
How to set a breakpoint
- UI layer gets a breakpoint setting request, such as an
invocation of the 'set' command or the SetBreakAction.
This calls on the BreakpointManager to create the appropriate
breakpoint.
- The breakpoint is created and inserted into the list of
breakpoints in the breakpoint manager's "default"
breakpoint group.
- Breakpoint manager will attempt to resolve the breakpoint
immediately.
- The breakpoint classes are responsible for dealing with the
mechanics of resolving themselves.
How breakpoints are resolved
- BreakpointManager listens for class prepare events whenever
necessary. If there are no breakpoints, it will not listen. When
a new breakpoint is created during an active session, the manager
must start listening.
-
Types of breakpoints and what they need to resolve.
- watchpoint: Field, ReferenceType, optional class/thread
filters
- breakpoint: Location, ReferenceType, optional thread
filter
- exception: ReferenceType, optional class/thread
filters
- class prepare/unload: none, optional class filter
- method entry/exit: none, optional class/thread
filters
- thread start/death: none, optional thread filter
- ResolvableBreakpoint is an abstract subclass of
DefaultBreakpoint, which resolves itself against a
ReferenceType.
- When a new breakpoint is created, it will be asked to try to
resolve immediately. If it is unsuccessful, an appropriate event
request is created. The event request will contain a property
called "breakpoint" that refers to the breakpoint that
created it. This is used by the breakpoint manager to look up the
breakpoint that created the request.
- The breakpoint manager listens for class prepare events. When
one occurs it will look up the "breakpoint" that
requested the event. If one exists, it will be asked to
resolve.
What happens when an event occurs
- VMEventManager gets the event and sends it off to the event
listeners.
- Each breakpoint class must listen for the events it is
interested in. This is easier than having a single class listen
for all types of events.
- Breakpoint receives the event notification and compares the
value of the "breakpoint" property of the EventRequest
that generated this event. If it matches, the shouldResume()
method is called to determine whether to continue the debuggee VM
or not.
- If the breakpoint should stop, the performStop() method
should be called so it will increment the stopped counter and run
any registered monitors.
How breakpoints are customized
- Breakpoint dialog iterates breakpoint groups and shows a tree
of breakpoints in the dialog. For each breakpoint group, a group
node is created. For each breakpoint, a breakpoint (leaf) node is
created.
-
Buttons on the side of the breakpoints dialog allow the user to
modify the breakpoints. The buttons will include:
- "Properties..."
- "Show Source"
- "Disable"
- "Enable"
- "Remove"
- "New Breakpoint..."
- "New Group..."
- The create button will bring up the SetBreak action, for
now.
- Someday the create button will need to have clones that
create other types of breakpoints (i.e. "create watch",
"create catch").
- The tree uses custom node objects to keep a reference from
the tree node to the breakpoint group or breakpoint.
- The tree nodes must have custom renderers to show the
breakpoint or group status (resolved, disabled, etc.).
- Each breakpoint subclass must provide an accessor method,
getUIAdapter(), that returns an appropriate user interface
adapter (which implements the UIAdapter interface).
- The UI adapter will have a JComponent widget that contains
the user interface widget(s). The UI adapter will have a commit()
method to save the widget values to the breakpoint, condition, or
monitor.
- The breakpoint manager dialog builds a breakpoint editor
dialog and stuffs the breakpoint's UI into this editor
dialog, including any monitors and conditions for the
breakpoint.
- After changes are accepted, the editor dialog calls the UI
adapters and tells them to save their values to their respective
objects (breakpoints, conditions, and monitors).
How Conditions work
- Must be given Session instance to retrieve information in
order to evaluate the condition.
- Returns true if the condition is satisfied.
- EditorDialog shows a list of defined Conditions.
- ConditionUI provides a String descriptor for the
condition.
- EditorDialog provides "add condition" and
"remove condition" buttons.
How breakpoints are persisted
- The breakpoint groups, breakpoints, conditions, and monitors
are all stored in nodes of type
java.util.prefs.Preferences
, the class provided in
JDK 1.4 and later.
- Serialization begins with the default breakpoint and
traverses down the tree until everything has been saved.
- Breakpoint manager handles [de]serialization of the
breakpoints.
How breakpoints link up with source code
- Have a "LocatableBreakpoint" interface that certain
breakpoint classes will implement.
- A resolved locatable breakpoint will have a Location for the
breakpoint.
- A resolved locatable breakpoint can determine if it belongs
to a certain source file or not (uses the locatable event
request's location).
- An unresolved locatable breakpoint can make a guess as to
whether it belongs to a certain source file or not (uses the
class name pattern to match the filename).
- How will unresolved method breakpoints know which line they
are set at?
- If classname of locatable breakpoint is not wild-carded, can
use it to map to the source file.