Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
CDT/Obsolete/MultiCoreDebugWorkingGroup/VisualizerView
Contents
Visualizer View
This article presents a proposed debugging view for the Eclipse IDE, known as the Visualizer View.
A bugzilla entry has been created to track the progress of this effort:
Bug 335027: Visualizer View feature
Overview
The existing Debug View in Eclipse consists of a simple tree structure, displaying launches, processes, threads, stack frames, etc. in creation order. The Debug View allows selection of a process or thread of interest, and allows actions to be performed on the selected entity, such as suspending or stepping. The Debug View also serves as a selection source for other views: a selection in the Debug View triggers updates in the source code view, variables view, etc.
This presentation is suitable for the very common case where the developer of a multicore application views that application merely as a "bag of processes" and does not really care how they are scheduled on the physical hardware, beyond perhaps ensuring that multiple worker processes are not competing for the same resources.
There are other possible presentations, however. These include:
- a more concrete view, where the actual layout of tasks on hardware is shown
- an application-centric view, where the layout is a graphical representation of the parent/child or functional relationships between tasks
- other possibilities, which require more than a simple flat (or hierarchical) listing of tasks
These presentations, or visualizations of debugging state, suggest the need for a Visualizer View, which can be used to present and possibly select from the available visualizations.
This Visualizer View should not be viewed as a replacement for the Debug View, but rather as a complementary perspective on the same application. To give an analogy, in writing a technical article one does not dispense with the text of the article and merely present a graph; one uses the graph to cogently present an overview of the details discussed in the article. Similarly, the Debug View might still serve as the "main view" of a debugged application, but one might also use the Visualizer View to get a different, high-level perspective on the same application.
In creating any such visual presentation of debugger state, one needs to
- present an overview of large numbers of elements in a compact, yet accessible form
- make important things (e.g. suspended/crashed processes) stand out, while giving a clear sense of the overall state (e.g. all other processes are fine)
- allow the user to select and interact with these elements in a straightforward way
Tilera's Grid View
A specific example of a concrete, hardware-centric visualization is the Grid View extension added by Tilera Corporation to its Eclipse-based IDE.
The figure below is a screenshot of the Grid View, showing an application that consists of a number of processes distributed across "tiles" (or cores) on Tilera's chip. The tiles are indicated by the squares in the grid, hence the name "Grid View", and the processes/threads by colored "dots" within the squares. Each process/thread "dot" is further annotated with its Linux task ID. (Not shown is a tooltip displayed when one hovers over a tile or process, providing further detail such as the executable name.)
In this example, the application is stopped at a breakpoint (hence the overall yellow coloring of the hardware elements) and one process has "crashed" by raising a signal. (This is the process "dot" on the red tile with the blue selection ring around it.)
Other elements to note in the Grid View display are:
- the I/O and memory elements around the edge of the grid
- the task (x,y) coordinates indicated at the top and left edges
- the overall application state, displayed as text at the top
As noted above, the Grid View does not replace the Debug View. Rather it complements it, by presenting a hardware-oriented view of the layout of the application. In the Tilera case, it might happen that the arrangement of processes on tiles, or their proximity to various I/O devices is of interest. At the very least, the Grid View provides a quick visual confirmation that there is at most one "worker" process scheduled to a tile. (On the red tile, the parent process and a worker it has forked are momentarily sharing the same tile.)
The Grid View also allows selection of processes/threads. In the figure above, in the top-right corner two processes are being drag-selected using the marquee-style selection box. The view's toolbar buttons for pausing, stepping, etc., mimic the corresponding buttons on the Debug View, and apply to the currently selected process(es). (More precisely, they correspond to processes that have an associated debugger, indicated by a small "D" mark next to the process.)
Finally, the Grid View also serves as a selection source for other views. The selected process(es) or threads in the Grid View are automatically selected in the Debug View, and views that are dependent on the Debug View selection are implicitly updated as well. Similarly, the Grid View is "selection aware", so a selection in the Debug View causes the Grid View to update its selection accordingly.
This is an example of a useful synergy between the two views: in the Debug View it is not immediately obvious which process is assigned to which tile, but by selecting a process in the Debug View, one can immediately see from the selection in the Grid View which tile it is currently associated with.
Use Cases
Hardware Types
The potential hardware/application types that would want to be supported by this framework are:
- A highly symmetric, many-core platform with a specific 2-D hardware layout, such as Tilera's chip.
- A symmetric, many-core platform with a large number of cores, where the layout is not essential -- in other words, a generic parallel display.
- An asymmetric, SoC hardware platform.
- Possibly multiple hardware components ganged together.
TBD: Suggestions are welcomed, as well as more detail on the latter cases, as the author's background is heavily biased towards symmetric and massively parallel hardware platforms!
Debugging Tasks
The guiding debugging tasks for this proposal are:
- Default Visualizer View state:
- The Visualizer View can exist when there is nothing to be displayed.
In such cases, it should have some initial "default" display,
for example, a blank view or perhaps a guiding message. ("Please invoke
a launch", etc.) This can be left to each of the selectable presentation(s),
but this case should be taken into consideration in the design of any
such presentation.
- Debugging a multi-process/thread application in a symmetric environment:
- When the user launches an application, the Visualizer View should
update to reflect that launch. Note that the launch does not have to
be invoked in Debug mode -- the Visualizer should work just as well
for non-debugged applications.
- During execution, with some periodicity, the Visualizer View should
update to reflect the current state (or at least a snapshot) of the
application as known to Eclipse/GDB at the time. There will necessarily
be some skew, but this is permitted, since the goal is to allow a rough
sense of where the application is.
- The Visualizer (or rather each presentation) indicates somehow
which of the visible elements can be operated on by debugging actions.
This might be a marker of some kind that shows where debuggers are attached.
- When execution is suspended "normally" (e.g. at a breakpoint)
the Visualizer should update to reflect the current state. At this point
we want the presentation to be as current and accurate as possible.
If we're debugging in an environment where some processes are allowed
to continue execution, it is permissible for only the suspended processes
to be up to date, and the rest are displayed based on their last
reported state.
- When execution is suspended due to a crash,
the Visualizer should update to reflect the current state.
The crashed process(es)/thread(s) should be indicated.
- Switching between launches
- When the user changes the launch context (i.e. by selecting a different
simultaneous launch in the Debug View) the Visualizer View should update
to reflect the selected launch's state.
- When a launch is removed from the Debug View, if it happens to be the
one displayed in the Visualizer View, then the state of some other
launch should be displayed. (Which one to display is somewhat arbitrary,
but it is suggested that it should be the next most recently viewed
launch. We might also use the current Debug View selection to determine
which launch to display, though this provides less determinism about which
launch happens to be selected next) If no other launch is available for display,
the Visualizer View should return to the "default" state of the currently
selected presentation.
- Selection in the Visualizer View
- The user selects a set of debuggable elements (e.g. processes/threads)
in the Visualizer view. The Debug View selection updates as a result,
causing its dependent views to likewise update.
Where more than one such item is selected, the item(s) selected
depend on how the Debug View and its subsidiary views handle
multiple selection of the selected elements.
- If selected items in the Visualizer View do not directly correspond to
Debug View elements (for example, if the user selects a tile), then
related Debug View elements are selected (for example, the process if
any that is currently on that tile).
- Selection in other views
- The user selects a process, thread, etc. in the Debug View.
If this corresponds to one or more elements in the current Visualizer View,
then the view updates its own selection accordingly. If no such elements
exist in the visualization, the selection there is cleared.
- Actions on selections
- The user selects one or more processes, and clicks, for example,
"Suspend" in the Visualizer's toolbar. This should be the same as
invoking the Suspend action in the Debug View for any process(es)
that have debuggers associated with them. Processes that do not have
debuggers are unaffected by the command. (A possible alternative
is attaching debuggers to any such processes, but this may involve
too much overhead to be practical.)
- Context Menu support
- If the user right-clicks on the Visualizer View, the click location
is used to determine the contextual item, if any. For example, the user
may right-click a tile or a process/thread icon. (Alternatively, the
current selection, if any, is treated as context.) A context menu with
appropriate commands for the context, plus any "global" actions,
is displayed.
- Switching between presentations
- The user runs an application, and selects items in the current
Visualizer presentation. The user then switches (via tab or other control)
to a different presentation. The new presentation should update
(or already be updated) to reflect the current launch and the
current selection if any.
Requirements
The Visualizer View, as here proposed, should not be thought of as a specific visualization, such as the Grid View, but rather as a framework. The Visualizer View should support multiple graphic representations of the current state of an executing application, and allow selection of items and invocation of actions on that application. It should also allow the user to easily switch between the available presentations.
We should also consider allowing multiple views, each of which could present a selected presentation, and supporting pin-and-clone so the user can "lock" a given view to a specific launch and/or presentation.
As noted above, a given visualization can be highly concrete, e.g. an exact representation of the processing hardware showing the layout of the application on it, as in Tilera's Grid View. It could also be highly abstract, e.g. a graph representation of the processes/threads of the application, showing their parent/child relationships.
One important motivating instance of this is displaying and allowing control of an application with one or more debuggers attached to its processes. So for example in the Grid View, a marker (a small "D") is used to indicate processes with associated debuggers, and the toolbar operations of the view are oriented towards control of these debuggers (stepping, suspend/resume, etc.)
Something else to note is that we distinguish visualization views (such as the Debug View or the Grid View) from detail views (such as the Variables View, the Memory and Disassembly Views, etc.) which provide detail or related context based on the current selection. The intent of a visualization is to provide the "big picture", while detail views like those indicated above provide a narrower, focused view of the selected element. (This is a broad classification, and it's not impossible that the selected element could itself be complex enough that such "detail views" might themselves require some kind of visual representation, but for now we exclude this possibility.)
The Visualizer view should consist of:
- The Visualizer view itself. This should support periodic and on-demand
updating of the display, in response to:
- user actions, like resizing the view or requesting an update</li>
- event(s) from the model ("push" model)</li>
- periodic updating of the view ("polling" model)</li>
- A provider-based "presentation" mechanism for display of the model,
its elements, and their current state.
- An application-specific "model" object hierarchy.
Ideally, this is just the application model itself, i.e. objects representing
processes, threads, tiles, etc. The model classes themselves should be
entirely presentation-agnostic. The presentation model is responsible for
the mapping from model to view elements.
- A description of the target, in a presentation-neutral format, which
captures any important layout information that would be useful.
(The internal structure of the hardware, connections between elements, etc.)
- An update framework for reflecting changes to the model state.
Examples:
- rescheduling of threads to new tiles
- changes to thread state (running, paused, stopped at breakpoint)
- generated model state (e.g. current processor cycle,
aggregate amount of memory in use, other on-the-fly performance data;
in general stuff that isn't associated with a specific event, but wants to be
periodically updated)
- Some kind of "backend" interface, by which the model can receive
information about the target and its current state.
(This may also serve as a source for the target description and
update events described above.)
- An action framework for performing operations on the model and its elements.
(Ideally this would be the existing Eclipse action framework.)
Examples:
- stopping/starting debugged processes</li>
- attaching a debugger to a process on demand</li>
- opening a console pane associated with a specific process</li>
The action framework should support not only toolbar items for the view,
but context menu items displayed on the Visualizer View's context menu.
- A context menu mechanism, by which context menu items can be registered
"globally" (e.g. for the view as a whole) and presentation-specific items
added on the fly, based on the right-click context and/or the current selection.
- Other requirements:
- Support for multiple different user-selectable presentations
(e.g. a hardware view vs. a more abstract "application" view).
- The ability to select element(s) of the model and have that selection
be made available to the workbench as a whole, and via the Debug View
selection mechanism in particular. (Note: this probably requires defining
some mechanism for mapping visualization elements to objects that are
"known" to other views, such as debug targets, processes, etc.)
- Acceptance of selection state provided by the workbench, and auto-selection
of corresponding elements (if any) in the visualizer view.
- The Visualizer View should support pin-and-clone, so a user can have multiple
views open, each pinned to a given launch and presentation.
- The Visualizer view should support Grouping and Hiding, like the Debug View.
Such a feature might redefine the current layout based on hidden items
and on grouped items. (Note: we might specify that visibility/grouping
are model properties, and a presentation is free to present these properties
in whatever way makes sense.)
- Support for a concept of zoom-level, i.e. being able to enlarge/shrink the
view to see more context or more detail. To some extent this may just be a
presentation thing -- one presentation might scale itself based on how much
screen real-estate it's given, another might treat that real-estate as a
scrollable view over a "zoomable" visualization.
- Support for new display properties/behaviors. For example, we might extend
selection to support the notion of 'locked' or 'protected' elements.
The user could select elements in the Visualizer and mark them protected.
The protected elements would be excluded from operations (e.g., suspend,
resume) even if they are selected. (This simplifies selection, and can help
a user avoid making time-wasting mistakes by resuming the wrong entity, etc.)
This may be nothing more than the requirement that the set of model properties
a presentation has access to be extensible, and the presentations themselves
able to be modified to make use of newly defined properties.
Proposed Implementation
Visualization Framework
The visualization framework will want to include the following classes:
. VisualizerView
- This is a standard Eclipse view, which contains a viewer and
actions, and interacts with the workbench as usual
- We might provide a base "VisualizerView" class, which handles most
of the boilerplate view stuff.
- Alternatively, we might just present some examples of how one can
implement a view that makes use of the other classes below.
(In the case of Tilera's Grid View, the outermost view class is a thin
wrapper that holds the equivalent of the Viewer class and mainly
handles toolbar actions and the context menu.)
. VisualizerViewer
- A "canvas" style control that displays the view contents of the
currently selected presentation
- Should be arbitrarily scalable in width/height.
- Should decide when to update itself based on user resizing, etc.
- Should provide a method for requesting an update, and "batching" requests
(e.g. by using a timer to periodically check whether an update is needed)
- Should also support tool-tip display
- Events:
- move move/drag (to allow rubber-banding/marquee display)
- point/region selection
- element selection (using providers to decide what got selected)
- context menu action
- Question: who creates the viewer elements? Does the presentation decide
what represents what, or does the view "walk" the presentation view of the
model and assign one element to each walked child?
. VisualizerViewerElement
- Graphic display element, base class for view elements of various presentations
- This is not a UI component, it is simply a class/interface that knows how
to draw itself given an appropriate graphic context from the VisualizerViewer.
In fact, it might be better to implement this as an interface, so that we
don't tie the user to a fixed base class. (We might still provide a sample
implementation base class that does something simple, of course.)
- Viewer (or rather current presentation) sets the bounds of this element
based on its own size, then the element decides how to draw itself
within the space it's given.
- One could also abstract out scaling of elements to the canvas, but in general
the result looks uglier than if an element draws itself based on its size and
can decide when to simply stop displaying labels, details, etc. because
it is being drawn too small.
- should provide methods for
- determining whether a click point is contained in the element
- determining whether a selection region contains/overlaps the element
. VisualizerPresentationManager
- Manages set of presentations for VisualizerViewer
- Question: how is a presentation selected? Should the selection UI (if any)
be part of the presentation itself, so it can be defined by the user?
Or should we provide a tab panel, etc. mechanism, like in the Memory view?
. VisualizerPresentation
- Represents one possible display of the current visualizer model
- Includes methods for obtaining the model object and navigating its structure.
- Provider based, consults list of VisualizerPresentationProviders to
find one that knows how to present the current object.
- Provides context menu actions for the presentation as a whole
. VisualizerPresentationProvider
- Presentation for an element (the whole platform or one of its hardware elements, etc.)
- Knows how to present the element itself, given its size.
- Provides methods for accessing the element's parent/children.
- Provides any element-specific context menu items
- This allows the model object to be an arbitrary tree-structure, perhaps
even the existing object model, with no need for an extra "model" hierarchy.
- It also makes changes to the model easy -- just add a provider for any
new object type.
. VisualizerContextMenuManager
- Manages construction of context menu for Visualizer View
- allows registration of "global" context menu actions, always displayed
- polls the current presentation dynamically for any additional,
context-specific actions to present
. "Visualizer Model" Object
- Root class of tree structure representing platform, etc. to display
- This can be any object, the VisualizerPresentation encapsulates how
it is navigated and presented.
. A "model descriptor" data structure that captures important aspects
of the target platform's layout (core "grid", IO devices, etc.)
This should be in a presentation-agnostic format, and serves as a guide
for presentations that want to provide a realistic hardware layout.
A presentation is permitted to summarize, paraphrase, or ignore this
information as needed, based on what it intends to show.
. A "backend framework" by which the model and/or presentation can receive
updates on the target's state. (This might include the model description
noted above.) Note that this framework should not be directly tied
to the visualizer view -- ideally, the backend informs the model, and the
model (though appropriate update events) triggers an update in the view.
We do need some standard framework by which a given target can tie its
backend into the visualization mechanism.
"Hardware Visualization" Instance
It is suggested (though not required) that the Grid View, or a similar hardware-oriented view, should serve as a specific, motivating example of a visualization style to be supported by the above framework.
Since there is no one "right" visualization for all possible hardware types, what might be required is either:
- a prototypical example that could be modified or extended to suit the hardware layout(s) in used by a particular implementer.
- or a generic "hardware view" that supports some kind of description language that specifies the layout of elements and identifies them for the purpose of assigning update events to them
(TBD: Need more detail here -- use cases welcomed!)
Implementation Considerations / Design Choices
For the Visualizer view and element classes, we might consider specifying/using a plugin that provides graphic elements and view support, for example GEF (http://www.eclipse.org/gef/) to reduce the coding needed to construct a presentation.
However, this has the consequence of making that plugin a requirement for CDT and/or base Eclipse, so we'd need to be sure it was the "right" one. There is a precedent for this: the remote launch plugin requires RSE.
Perhaps the Visualizer framework may not specify or require such a plugin, but a specific visualization instance, such as the Grid View, might do so.
Alternatively, we might have the framework leave the choice of implementation entirely open, and provide some useful examples in various frameworks like GEF to show what's possible.
TBD: Does the Parallel Tools Platform (PTP, http://www.eclipse.org/ptp/) have a similar view, and/or is there any possible synergy here?
Comments To Be Factored In
If you have comments and/or suggested requirements, please either add them to the bugzilla Bug 335027: Visualizer View feature or below, and we'll factor them in as this document is updated.
