Debugger Core API/SPI Requirements
Autor: Jan Jancura
$Revision: 1.2 $
History:
1.6: First version
1.7: Some very useful comments from Ivan has been incorporated (I hope
that properly), Debugger Engine definition has been added, DAR8, DAR2.1
has been added. Do not study relationship between Session <>
Engine <> Language <> PlugIn in this version much, please.
I
will prepare some pictures ;) and description.
1.8: DAR9 and 10 added; DAR8, 6.2 and 6.1 changed
Why new Debugger Core APIs?
- Compatibility &
maintainability: Debugger is one of the most important modules
in the IDE, and many other modules are based on it - JSP debugger, J2EE
Debugger, Native Debugger, applet, RMI, Corba and some external
moduels. Current
NetBeans Debugger does not have public APIs. All
dependencies are hardcoded. Such dependencies are not
maintainable in a longer period. Some communication standards,
interfaces are needed.
- Separation of UI and
implementation: NetBeans debugger is bundled to differrent IDEs.
And differrent IDEs have differrent user requirements, differrent UIs.
That is why the Debugger UI should not be mixed with implementation,
and should be easily replaceable. Debugger UI should be separated to
special module, and Debugger Core API should define contract for it.
- Testability: Current
codebase is not stabe enough for unit testing. The debugger model must
be changed.
- Threading model: NB3.5
debugger does not have strictly separated UI & implementation.
Definition of threading model is nearly impossible in such architecture.
- Filterring of debugger stuff:
One of the most important requirements from Enterprise Debugger group
is to hide generated code (EJB stuff). So Debugger API should define
some interface for filterring of Threads View, CallStack View and Smart
Stepping functionality.
- Multi-language debugging:
Current Debugger Core does not support multi-language debugging.
Implementation of JSP debugger is hacky, and it causes a large number
of bugs in it.
- JSR45 support: Support
for JSR45 is required to the next releases. Its not possible to do it
in the current model correctly.
Basic terms:
- Debugger Plug-in is
Netbeans module (or part of some module) which contains implementation
of debugger for some special programming language / environment (like
JPDA Debugger Plug-in, jdb debugger Plug-in, JSP debugger-plug-in...)
- Debugger Session is
visual
representation of some process running in debug mode. Debugger API does
not define if session represents one application, one process or
something else. This should be defined by Debugger Plug-ins, or in some
debugger UI guidelines. One of debugger sessions is always Current Session. This session
defines behavoiur of Step actions, value of watches and other features.
- Debugger Engine is Java
class (or more classes) representing some engine capable of debugging =
providing implementation of debugger actions like Start Debugging,
Finish Debugging, Step into / Over / Out... Debugger Engine should be
able to manage watches and breakpoints. DebuggerEngine is
provided
by Debugger Plug-in.
DAR1 - Allow to install and use more Debugger Plug-ins (for
different programming languages) to NetBeans IDE. <Web team, S1SEE,
Native>
NetBeans Debugger consists of
Debugger Core (Debugger API + implementation of debugger engine +
some shared debugger UI components) and Java Debugger. And its
architecture should allow to install debugger plug-ins for other
languages - JSP, C++, XSLT, ...
DAR2 - Debug more sessions at a one time - multisession debugging.
<S1SEE, Native>
Architecture of NB debugger should
support debugging of client-server, RMI, J2EE applications. It means
that debugger can:
- start a new session even if some other is already running
- start more than one session at one time
- display state of all running sessions - it means watch threads /
locals / callstack / watches / variables of all sessions.
There are two solutions for "3." - debugger can display state of one
(current) session, or it can display all sessions simultaneously.
I think that both of them should be supported in APIs.
DAR2.1 - Debugger API should support visualisation of all running
sessions simultaneously <Native>
DAR3 - Debugger Core API should be language neutral. <Native>
Debugger API should not contain special
support for some specific language. While allowing language-specific
features as extensions.
DAR4 - State management should be defined by Debugger Plug-In, and
should be asynchronous. <Native>
Debugger APIs and its implementation
(Debugger Core + shared debugger UI) should not drive changes of state
of Debugger Plug-in. Debugger Plug-In (and all of its classes) can be
in
different states. Some of these states are visible to other modules
through DebuggerAPIs or to a user through shared part of Debugger UI.
The change of state can be initiated by some UI component, or some call
of some Debugger API method, but it should always be validated /
confirmed by debugger plug-in. Debugger Core should not change the
state
itself. Both of synchronous and asynchronous confirmations should
be supported.
Example: Debugger API defines "enabled" property for breakpoints.
JPDALineBreakpoint is implemented in JPDA Debugger Plug-In.
- Breakpoint node calls Breakpoint.enable ()
- JPDALineBreakpoint.enable () method is called
- ---asynchronous call (different thread) ----
- JPDALineBreakpoint validates state change and calls protected
method Breakpoint.setEnabled (true)
- Breakpoint.setEnabled method fires the change of state
DAR5 - Debugger API should support sharing of UI
components for different
Debugger Plug-Ins.
DAR5.1 - Share Debugger Actions <S1SEE, Native, Web team>
List of Actions: Run in
Debugger, Attach, Finish, Pause, Continue, Step Over / Into /
Out,
Run to Cursor, Fix, New Watch, New Breakpoint, Make Callee Current,
Make
Caller Current, Pop Topmost Call, Debugger Window
Current Debugger Session (provided by some Debugger Plug-In) defines
behaviour of all shared actions. It can:
- manage enabled / disabled state of action
- define action performer
DAR5.2 - Share Debugger Views <S1SEE, Native, Web team>
DAR5.2.1 - Default set of Debugger Views
defined in Debugger Core can be shared by different Debugger Plug Ins:
- Sesions View: show list (or tree) of all sessions, one session is
current
- Threads View: show list (or tree) of all threads from the current
session, one threads is current
- Call Stack View: show call stack of the current thread from the
current session
- Locals View: show list of current local variables, local variable
can present set of its fields in tree structure
- Breakpoints View: shows list (or tree) of all breakpoints
- Watches View: show list of all watches
DAR5.2.2 - Debugger Plug-In can define
list (tree) of nodes visible in Threads / Call Stack / Locals Views.
Content of this views is defined by
current session. But other sessions can filter it - see requirement
DAR7.1.
DAR5.2.3 - Debugger Plug-In can add its
own visual representation of session / breakpoint / watch (Node) to
Sessions / Breakpoints / Watches View.
DAR5.2.4 - Debugger Views are
implemented using TreeTableViews / Nodes.
DAR5.2.5 - Debugger PlugIn can add a new
column to Debugger View or hide / redefine some existing one.
DAR5.2.6 - Debugger PlugIn can install
new Debugger View(s), remove some existing or replace them.
Author of Debugger Plug-In should be
careful in the case of removing / modifying default views. Conflicts
may
occur if two plug-ins would like to redefine the same view and so on.
DAR5.3 - Share New Breakpoint Dialog <S1SEE, Native, Web team>
Debugger API should allow sharing one
New Breakpoint Dialog among different breakpoint types installed by
different Debugger Plug-ins.
DAR5.4 - Share Attach Dialog <S1SEE, Native, Web team>
Debugger API should allow sharing one
Attach Dialog among different Debugger Plug-ins.
DAR5.5 - Share New Watch Dialog <S1SEE, Native, Web team>
Debugger API should allow sharing one
New Watch Dialog among different Debugger Plug-ins.
Support for multilanguage debugging.
Debugger API should support debugging
in multilanguage environments. There are two usecases:
- Current context of debugger can be represented by more than one
programming language (for example user can see one position in code as
JSP / Java / Bytecode).
- When the current context is changed (step action, stop on
breakpoint) a current language can be changed too (for example call
from
Java code to some native code).
DAR6.1 - Each Session has set of programming languages supported in
the current context. <web team>
DAR6.2 - Session has Current Language property. <web team>
Current language defines:
- context for threads / call stack / locals views / watches view (if
there is one View shared by all sessions)
- context for editor window or some other "source viewer" (UML...)
- context for Step actions (= context for debugger engine)
Breakpoint and other components can have some specific notion of
language. For example "class load breakpoint" will be always Java
specific. Line breakpoint should be attached to some source, and this
source will define the language.
DAR6.3 - One Debugger Engine can support debugging in more than one
language. <Native>
Each language is represented by some
Debugger Engine
DAR6.4 - User can change current language for each session
separately. <web team>
DAR6.5 - One debugger Plug-in can install support for more than one
language. <Native>
It means that one Debugger Plug-In can
install more than one Debugger Engines and one Debugger Engine can
support more than one language.
DAR6.6 - Set of languages supported by some session can be changed
when the context is changed. <web team>
Some new language can be detected
during debugging (during debugging of some Java code a JSP can be
detected) and the support for the new language can be added
automatically.
DAR6.7 - One Debugger Plug-In can add support for some new
programming language to the Session produced by different Debugger
Plug-In. <web team>
For example, JSP debugger can be
implemented as a "plug-in" to some already existing implementation of
Java Debugger. In this case JSP Debugger will register
JSPDebuggerEngine
to already existing JavaSession produced by JPDADebuggerPlugIn.
JSPDebuggerEngine than only delegates some functionality to already
existing JPDADebuggerEngine.
Support for Debug Accross Tiers.
Enterprise applications consists of
different tiers. Each tier can run in different process and / or can be
written in different programming language. Some tiers are automatically
generated and should be hidden to user. Debugger should present
application as one unit - through all different tiers. So, for example,
call stack view can contain call stack lines from different languages,
some part of call stack can be hidden (generated RMI stub), and call
stack can be combined from two threads from two processes (RMI call).
DAR7.1 - Each Debugger Plug-In can
install some filters for Threads / Call Stack / Locals View. This
filter
can add / remove / replace default Nodes in list (tree) of Nodes in
view. <S1SEE>
DAR8 - Debugger Engine can be "reused" for a new Debugger Session.
<native>
DAR9 - Debugger Plug-in can create a new Session / Engine anytime
during debugging. <native>
DAR10 - Debugger API should allow to split
debugger UI and
implementation to differrent modules. <Rave>