From 9504323dd53d6e502fe73ab2ba687101e947915a Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 13 Mar 2008 06:41:35 +0000 Subject: [PATCH] [220446] Updated the "PDA Debugger Introduction" document. --- .../docs/pda/pda_tutorial_outline.html | 881 +++++++++++++++--- .../docs/pda/source_display_1.dia | Bin 0 -> 2451 bytes .../docs/pda/source_display_1.png | Bin 0 -> 25113 bytes .../docs/pda/stack_1.dia | Bin 0 -> 2012 bytes 4 files changed, 744 insertions(+), 137 deletions(-) create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/pda/source_display_1.dia create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/pda/source_display_1.png create mode 100644 plugins/org.eclipse.dd.doc.dsf/docs/pda/stack_1.dia diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/pda/pda_tutorial_outline.html b/plugins/org.eclipse.dd.doc.dsf/docs/pda/pda_tutorial_outline.html index f87e58b80c8..18f154334d6 100644 --- a/plugins/org.eclipse.dd.doc.dsf/docs/pda/pda_tutorial_outline.html +++ b/plugins/org.eclipse.dd.doc.dsf/docs/pda/pda_tutorial_outline.html @@ -7,17 +7,95 @@

How to write a DSF-based debugger

Summary

-

DSF

- -

Debug Services

-

TODO: remove this sesion?

-Use of services is intended to allow for maximum level of extendability -and customization.  To achieve this, service interfaces should -encapsulate functionality that logically belongs together and at the -same time allow for a managable number of services which have a clear -hierarchy.  DSF defines a set of standard debug interfaces (in the -org.eclipse.dd.dsf.debug plugin), and supplies a set of classes that -populate the standard debug views using those interfaces (in the -org.eclipse.dd.dsf.debug.ui plugin).  However there are very few -dependencies in these service interfaces and a given debugger -implementation may leave out or replace any of them as its custom -functionality dictates. 
-

The standard debug service interfaces include:

- -

Step 1 - Launching
+

Step 1 - Launching

The first task in integrating a debugger in Eclipse is creating and managing the debugger process.  The Eclipse Platform provides an @@ -270,7 +296,7 @@ extensive API for this purpose, which is nicely presented in the article.  This section (as this tutorial) concentrates on the DSF-specific tasks of launching the PDA debugger.
-

Launch Delegate

+

Launch Delegate

At first glance, there's nothing unusual about the PDA debugger launch delegate.  Just like the Debug Platform version it:
    @@ -299,7 +325,7 @@ extension interface, in order to create a custom launch object:

    -
     51:  51:  public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {

    52: // Need to configure the source locator before creating the launch
    name="line55"> 55: // the source lookup adapter.
    56: ISourceLocator locator = getSourceLocator(configuration);

    58: return new PDALaunch(configuration, mode, locator);
    59: }
    + name="line59"> 59: }
    @@ -316,7 +342,7 @@ extension interface, in order to create a custom launch object:
    -

    PDALaunch

    +

    PDALaunch

    The PDALaunch object plays two main roles:
    1. Serve as the root element of the PDA View Model hierarchy
    2. @@ -513,7 +539,8 @@ these race conditions.
      -

      Launch/Shutdown Sequence

      +

      Launch/Shutdown +Sequence

      The actual task of calling the asynchronous IDsfService's initialize() and -

      Step 2 - Connecting 

      +

      Step 2 - +Connecting 

      With the launch framework in place, the debugger back end is running and the DSF session and executor are started.  The next step is to create the first service and to connect to the debugger.  DSF @@ -604,7 +632,7 @@ target state change events.
      -

      Synchronization

      +

      Synchronization

      Since there are several threads being used by the PDA Command Control protecting state data becomes very important.

      @@ -677,7 +705,7 @@ used only as a means of synchronization with the send job. flag.  It needs to be thread safe to allow the command and event processing jobs to access it.
      -
    3. Lines 86-95 declare the commuication sockets.  They are +
    4. Lines 86-95 declare the communication sockets.  They are marked as thread-safe though only used by dedicated threads after being created.
    5. @@ -745,10 +773,11 @@ thread. -

      Command/Event Listeners

      +

      Command/Event +Listeners

      As mentioned before there are two types of listeners that can be -registered with the comands control: event -listners and command listeners.  The most important +registered with the commands control: event +listeners and command listeners.  The most important feature of these listeners, is that they are called by the command control synchronously.  As a result of this, the command listeners can expect to see the state @@ -809,7 +838,7 @@ new command. send commands to the debugger.  The separate runnable is used to allow the command listeners to modify the queue as well. -

      PDAProgramDMContext

      +

      PDAProgramDMContext

      Finally the command control also declares a Data Model context, which is a parent to all other contexts for a given PDA debugger session.  Each command used with the command control has to @@ -820,7 +849,7 @@ instance returned by PDACommandControl.getProg However in other debuggers this context can have two other functions:
      1. To identify the command -control instnace - In debugger sessions that connect to multiple +control instance - In debugger sessions that connect to multiple back ends, the context can be used to identify which command control should process a given command.
      2. To help control @@ -828,13 +857,13 @@ debugger command protocol state - The PDA debug protocol is stateless, which means that any command acts independently of any commands that came before it.  For debuggers which do have protocol state, e.g. GDB/MI, the command control needs to check the -context of each command and set the protocol by preceeding the command +context of each command and set the protocol by preceding the command being processed with other commands.
      -

      PDA Commands

      -To increase type safetly and make the code more readable the plain text +

      PDA Commands

      +To increase type safely and make the code more readable the plain text PDA commands are abstracted using specific command objects.  Below is an example of a command class:

      @@ -933,9 +962,12 @@ immutable helps guard the integrity of these caches. -

      -

      Step 3 - View Model

      -

      Adapter Glue
      +

      +

      Step +3 - View Model

      +

      Adapter Glue

      • Line 91 creates the View Model Adapter.  This adapter is used to populate the content of all the Flexible Hierarchy debugger -views for the given PDA debugger instgance.
      • -
      • Line 94-95 register the source display adapter (the "MI" prefix +views for the given PDA debugger instance.
      • +
      • Line 94-95 +register the source display adapter (the "MI" prefix is a historical left over).
      • Lines 98-109 register handlers for common debug commands.
      • -
      • Lines 112 -116 Regiter an adapter to provide debug model -ID.  It is used by Debug Platform to enable custom keybord +
      • Lines 112 -116 Register an adapter to provide debug model +ID.  It is used by Debug Platform to enable custom keyboard shortcuts for the debugger.
      • Line 122 associates the launch object with the PDA debugger elements.  This enables some actions in debug view which access @@ -1159,7 +1192,7 @@ PDA launch is removed:
      -

      PDA View Model

      +

      PDA View Model

      The PDAVMAdapter creates the VM Providers on demand for each debugger view it supports:

      @@ -1203,7 +1236,7 @@ respectively.  These providers are implemented in the -

      Launch VM Provider

      +

      Launch VM Provider

      "Launch" actually refers to the internal name of the Debug view.  The PDA debugger has a somewhat simpler presentation in Debug view than most debuggers because it does not support multiple threads so it has @@ -1288,7 +1321,7 @@ events.  These events are used by the LaunchVMRootNode to update the state and content of the launch if it has been changed or terminated. -

      PDA Program VM Node

      +

      PDA Program VM Node

      Elements

      @@ -1371,7 +1404,7 @@ already terminated.  The super-class implementation only changes the execution thread to the DSF session and calls updateElementsInSessionThread(), which is not needed nor possible after the PDA program is terminated. -
    6. Line 126 cretes the dummy View Model context which represents a +
    7. Line 126 creates the dummy View Model context which represents a terminated PDA program.
    8. Line 135 implements the elements update method which is called in the DSF session thread. 
      @@ -1432,9 +1465,9 @@ implementation:
        -
      • Line 153 iterates through the udptes. The +
      • Line 153 iterates through the updates. The IElementLabelProvider.update() method takes an array of updates as an -argument to allow the implementation to process the udpates in bunches, +argument to allow the implementation to process the updates in bunches, improving performance. 
      • Line 157 calls a subroutine to handle the terminated program @@ -1538,13 +1571,13 @@ method to retrieve additional information about the state of the PDA program.  The label update is completed only after request monitor of this method is called.
      • Lines 207-210 perform error handling.
      • -
      • Lines 213-229 finally calcuate the label string for the +
      • Lines 213-229 finally calculate the label string for the program. 
      • On line 227, The result of the getExecutionData() call, accessed using DataRequestMonitor.getData(), is used to fill in the reason for the current state of the program.
      • -
      • Line 230 writes the label to the upate.  This call assumes +
      • Line 230 writes the label to the update.  This call assumes that there is no columns in Debug view, so it uses 0 as the column index.
      • @@ -1552,7 +1585,7 @@ that there is no columns in Debug view, so it uses Delta Translating the Data Model events into IModelDelta objects that can be -processed by the Flehible Hierarchy views, is the most complicated task +processed by the Flexible Hierarchy views, is the most complicated task performed by the View Model infrastructure.  The model deltas require that a path be formed by the IModelDelta objects which matches the hierarchy elements found in the view, including such details as @@ -1687,19 +1720,19 @@ context to be selected.
        Note: In theory, each VM Node should only generate delta flags that only affect its own elements.  In this way, the layout of the VM Nodes in a view could -be costomized as needed.  In practice, testing and fine-tuning of +be customized as needed.  In practice, testing and fine-tuning of the view requires adjustments in the flags returned by the various VM Nodes in a given view. -

        Step 4 - Run Control

        +

        Step 4 - Run Control

        Up to this point most of the work in creating the new PDA debugger has gone into infrastructure.  Now it is time to start adding functionality to do some actual debugging.  The work needed to get run control functionality implemented is all encapsulated in the PDARunControl service.
        -

        State Tracking
        +

        State Tracking

        The primary function of the run control system is to track the current execution state of the program and to issue the corresponding events to @@ -1814,7 +1847,7 @@ logic an improve the efficiency of the IDE commands.
        -

        Commands

        +

        Commands

        The command control commands all follow the same patter shown below by example of the resume() command:

        @@ -1862,7 +1895,7 @@ state flag.
      • Lines 244-253 send the resume command to the PDA debugger.
      • Lines 247-252 adds error handling in case the result command -fails.  It resotres the service state.
      • +fails.  It restores the service state.
      • Line 251 calls the super class's handleErrorOrCancel() method.  The super class relays the error status to the parent request monitor and completes it.
        @@ -1873,8 +1906,9 @@ request monitor and completes it.
      • Tracking program running state
      -

      IExecutionDMData

      -There is very little data that the run control servie interface returns +

      IExecutionDMData

      +There is very little data that the run control service interface +returns for a given execution context.  The intention behind this is to allow the service to remain very generic and thus applicable to any debugger.  In specific debuggers, additional data about processes, @@ -1883,14 +1917,14 @@ extensions.  IExpressionDMData is the only object which is retrieved asynchronously from the run control service, and it only contains the state change reason for the last debugger state change. 
      -

      Step 5 - Breakpoints

      +

      Step 5 - Breakpoints

      Managing breakpoints is one of the complicated tasks that need to be implemented by Eclipse debuggers.  The source of this complexity is the fact that Eclipse breakpoints (IDE breakpoints) are managed independently of breakpoints that are installed in the debugger (target-side breakpoints).  The Eclipse debugger integration has to keep these two sets of breakpoints synchronized. 
      -

      IDE Breakpoints

      +

      IDE Breakpoints

      Eclipse breakpoints are based on markers, which are special tags in the Eclispe resource system and are associated with files and folders.  By using markers, breakpoints gain the benefit of the @@ -1924,8 +1958,10 @@ is described in fine detail the How to write an Eclipse debugger article.

      -

      Target-Side Breakpoints

      -DSF defines the IBreakpoints interface for a service which the fuctions +

      Target-Side +Breakpoints

      +DSF defines the IBreakpoints interface for a service which the +functions of managing breakpoints installed on the target.  These functions include:
        @@ -2054,7 +2090,7 @@ subroutine:
      • Lines 183-186 determine if the breakpoint is enabled.  If it is not, the insert command fails with an expected error. 
      • -
      • Line 188 retrieves the breakpoint type attribute, shich is used +
      • Line 188 retrieves the breakpoint type attribute, which is used to determine which breakpoint insert subroutine to call.
      • Line 196 retrieves the PDAProgramDMContext from the breakpoint target context.  This context is the only @@ -2134,7 +2170,7 @@ The PDABreakpoints.removeBreakpoint() command takes the IBreakpointDMContext as an argument, but otherwise follows the same general logic as the insertBreakpoint() implementation.

        Updating a Breakpoint

        -Updating a breakpoint involves motifying some of the attributes of an +Updating a breakpoint involves modifying some of the attributes of an existing breakpoint.  Not all debuggers may support this functionality and for debuggers that do, not all types of breakpoints and not all attributes may be updated.  The IBreakpoints interface @@ -2216,11 +2252,12 @@ this field.
        The simple PDA debugger does not track detailed breakpoint data, such has hit counts, addresses etc.  So this function simply returns an error.
        -

        Breakpoints Mediator

        +

        Breakpoints Mediator

        With the APIs for managing IDE and Target-Side breakpoints clearly defined, there is a need for a component which will keep the two sets -of breakpoint objects synchronized.  DSF provides a standard -BreakpointsMediator service to accomplish this task. 
        +of breakpoint objects synchronized.  DSF provides a standard BreakpointsMediator service to +accomplish this task.   @@ -2239,49 +2276,619 @@ breakpoints
        +The BreakpointsMediator +service is not meant to be sub-classed by specific debugger +integrations, however the specific IDE Breakpoint objects as well as +Target-Side Breakpoint attributes differ from debugger to +debugger.  +Therefore, the Breakpoints Mediator requires a helper object, which +implements IBreakpointAttributeTranslator which encapsulates the +debugger-specific functionality.  The most important function of +the attribute translator is to translate IDE Breakpoint attributes into +Target-Side breakpoint attributes.  The following listing shows +how the PDA debugger implements this function:

        -
        -
          -
        • Target Side Breakpoints
        • -
        • Mediator
        • -
        • Diagram showing Mediator's role
          -
        • -
        -

        Step 6 - Stack

        -
          -
        • Command Cache at work
          -
        • -
        -

        Step 7 - Source Display

        -
          -
        • Source lookup director
          -
        • -
        -

        Step 8 - Variables

        -
          -
        • Reading and writing variables
          -
        • -
        • Formatted values
        • -
        • Expressions view
          -
        • -
        + style="font-family: monospace; font-weight: bold;">org.eclipse.dd.examples.pda.service.PDABreakpointAttributeTranslator +- getBreakpointAttributes() -
        org.eclipse.dd.examples.dsf.timers.TimersVMNode -


        +
        +
         65:     public List<Map<String, Object>> getBreakpointAttributes(IBreakpoint bp, boolean bpManagerEnabled) 
        66: throws CoreException
        67: {
        68: Map<String, Object> attrs = new HashMap<String, Object>();

        70: // Check that the marker exists and retrieve its attributes.
        71: // Due to accepted race conditions, the breakpiont marker may become null
        72: // while this method is being invoked. In this case throw an exception
        73: // and let the caller handle it.
        74: IMarker marker = bp.getMarker();
        75: if (marker == null || !marker.exists()) {
        76: throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Breakpoint marker does not exist", null));
        77: }
        78: // Suppress cast warning: platform is still on Java 1.3
        79: @SuppressWarnings("unchecked")
        80: Map<String, Object> platformBpAttrs = marker.getAttributes();

        82: // Copy breakpoint attributes.
        83: if (bp instanceof PDAWatchpoint) {
        84: attrs.put(PDABreakpoints.ATTR_BREAKPOINT_TYPE, PDABreakpoints.PDA_WATCHPOINT);

        86: copyAttributes(platformBpAttrs, attrs, fgPDAWatchpointAttributes);
        87: } else if (bp instanceof PDALineBreakpoint) {
        88: attrs.put(PDABreakpoints.ATTR_BREAKPOINT_TYPE, PDABreakpoints.PDA_LINE_BREAKPOINT);
        89: attrs.put(PDABreakpoints.ATTR_PROGRAM_PATH, marker.getResource().getFullPath().toString());

        91: copyAttributes(platformBpAttrs, attrs, fgPDALineBreakpointAttributes);
        92: }

        94: // If the breakpoint manager is disabled, override the enabled attribute.
        95: if (!bpManagerEnabled) {
        96: attrs.put(IBreakpoint.ENABLED, false);
        97: }

        99: // The breakpoint mediator allows for multiple target-side breakpoints
        100: // to be created for each IDE breakpoint. Although in case of PDA this
        101: // feature is never used, we still have to return a list of attributes.
        102: List<Map<String, Object>> retVal = new ArrayList<Map<String, Object>>(1);
        103: retVal.add(attrs);
        104: return retVal;
        105: }

        107: private void copyAttributes(Map<String, Object> srcMap, Map<String, Object> destMap, String[] attrs) {
        108: for (String attr : attrs) {
        109: if (srcMap.containsKey(attr)) {
        110: destMap.put(attr, srcMap.get(attr));
        111: }
        112: }
        113: }
        +

        Step 6 - Stack

        +

        Command Cache

        +A new feature introduced in this service is the command cache.  +The command cache is a surprisingly simple mechanism for caching +service data which otherwise would need to be retrieved repeatedly from +the debugger back end.  The command cache performs two functions:
        +
          +
        1. Map Command objects to corresponding Command Result objects.
        2. +
        3. While waiting for a Command to be processed, queue incoming +Commands for the same data and complete them when the first Command is +completed.
        4. +
        +Using the command cache greatly simplifies the logic in implementing +data retrieval commands.  As an example, the following is the +listing of the PDAStack.getFrames() method:
        +
        +
        + + + + + + + + + + +
        org.eclipse.dd.examples.pda.service.PDAStack +- getFrames()

        +
        +
        244:     public void getFrames(IDMContext context, final DataRequestMonitor<IFrameDMContext[]> rm) {
        245: // Can only create stack frames for an execution context as a parent,
        246: // however the argument context is a generic context type, so it could
        247: // be an execution context, a frame, a variable, etc. Search the
        248: // hierarchy of the argument context to find the execution one.
        249: final IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class);
        250: if (execCtx == null) {
        251: PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid context " + context);
        252: return;
        253: }

        255: // Execute the stack command and create the corresponding frame contexts.
        256: fCommandCache.execute(
        257: new PDAStackCommand(fCommandControl.getProgramDMContext()),
        258: new DataRequestMonitor<PDAStackCommandResult>(getExecutor(), rm) {
        259: @Override
        260: protected void handleOK() {
        261: IFrameDMContext[] frameCtxs = new IFrameDMContext[getData().fFrames.length];
        262: for (int i = 0; i < getData().fFrames.length; i++) {
        263: frameCtxs[i] = new FrameDMContext(getSession().getId(), execCtx, i);
        264: }
        265: rm.setData(frameCtxs);
        266: rm.done();
        267: }
        268: });
        269: }
        +
        +
        +
          +
        • Lines 256-268 create a new PDAStackCommand, and execute it using +the command cache. 
          +
        • +
            +
          • If the PDAStackCommand +was previously executed, the PDAStackCommandResult +object will be returned from the cached data. 
            +
          • +
          • If the PDAStackCommand +was just sent to the debugger, and the cache is waiting for the result, +this request monitor will be put in a queue to wait for the +result. 
            +
          • +
          • If the cache does not contain an entry for the PDAStackCommand, it will create one +and send it to the debugger.
            +
          • +
          +
        • Lines 261-266 implement the handler which processes the PDAStackCommandResult.  It +creates an array of FrameDMContext objects and returns it to the client.
          +
        • +
        +

        Frame Context

        +The primary object type managed by the stack service a stack +frame.  It is implemented by the FrameDMContext object listed +below:
        +
        +
        + + + + + + + + + + +
        org.eclipse.dd.examples.pda.service.PDAStack +- FrameDMContext

        +
        +
         54:     private static class FrameDMContext extends AbstractDMContext implements IFrameDMContext {

        56: final private int fLevel;

        58: FrameDMContext(String sessionId, IExecutionDMContext execDmc, int level) {
        59: super(sessionId, new IDMContext[] { execDmc });
        60: fLevel = level;
        61: }

        63: public int getLevel() { return fLevel; }

        65: @Override
        66: public boolean equals(Object other) {
        67: return super.baseEquals(other) && ((FrameDMContext)other).fLevel == fLevel;
        68: }

        70: @Override
        71: public int hashCode() {
        72: return super.baseHashCode() ^ fLevel;
        73: }

        75: @Override
        76: public String toString() {
        77: return baseToString() + ".frame[" + fLevel + "]"; //$NON-NLS-1$ //$NON-NLS-2$
        78: }
        79: }
        +
        +
        +
          +
        • Line 56 declares the only field in the frame object, which is the +frame level. 
          +
        • +
        +The frame context, which in itself does not provide access to much +frame information, can be used to retrieve more complete frame data +implemented using the FrameDMData object.  The frame data object +is based on information parsed from the result of the PDA debugger +"stack" command, which is written into the PDAFrame object by the PDAStackCommandResult
        +
        +
        + + + + + + + + + + +
        org.eclipse.dd.examples.pda.service.PDAStack +- FrameDMData

        +
        +
         85:     private static class FrameDMData implements IFrameDMData {

        87: final private PDAFrame fFrame;

        89: FrameDMData(PDAFrame frame) {
        90: fFrame = frame;
        91: }

        93: public String getFile() {
        94: return fFrame.fFilePath.lastSegment();
        95: }

        97: public String getFunction() {
        98: return fFrame.fFunction;
        99: }

        101: public int getLine() {
        102: return fFrame.fLine + 1;
        103: }

        105: public int getColumn() {
        106: return 0;
        107: }

        109: public IAddress getAddress() {
        110: return null;
        111: }
        112: }
        +
        +
        +

        Step 7 - Source +Display

        +Integrating source display is relatively simple task, even though the +Eclipse APIs for looking up and displaying source are rather +convoluted.  Fortunately Eclipse Platform and DSF provide most of +the components needed to implement this functionality.
        + + + + + + + + + +

        +
        Image 3: Components involved in Source +Display
        +
        +The first step in integrating source lookup, is to create a source +lookup director and the source container.  This is explained in +detail in the How +to write an Eclipse debugger article referenced earlier.  +There is one difference in this process for a DSF-based debugger.  +The source lookup director does not need to initialize a source lookup +participant list.
        +

        The second step is to register a DSF source display adapter.  +This has actually already +been accomplished in Step 3 - View +Model, when registering the View Model adapters.
        +

        +

        Step 8 - Variables

        +At this point we almost have a fully functional PDA debugger.  The +only thing that is left is to populate the Variables and Expressions +views. 
        +Displaying variable data in DSF requires use of two services:
        +
          +
        1. IStack service - +This service is used to get the list of local variables' names in a +given stack frame.
          +
        2. +
        3. IExpressions service +- This service is used to evaluate the variable names as expressions in +order to retrieve full type and value information for the given +variables.
          +
        4. +
        +

        Variable Contexts

        +The stack service allows clients to retrieve two types of variables +through two methods
        +
          +
        • getLocals() - local variables
        • +
        • getArguments() - function arguments (not implemented by the PDA +debugger)
          +
        • +
        +Both of these methods return a context that implements the IStack.IVariableDMContext +interface.  The implementation of this context is very simple in +PDA
        +
        +
        + + + + + + + + + + +
        org.eclipse.dd.examples.pda.service.PDAStack +- VariableDMContext

        +
        +
        117:     @Immutable
        118: private static class VariableDMContext extends AbstractDMContext implements IVariableDMContext {

        120: final private String fVariable;

        122: VariableDMContext(String sessionId, IFrameDMContext frameCtx, String variable) {
        123: super(sessionId, new IDMContext[] { frameCtx });
        124: fVariable = variable;
        125: }

        127: String getVariable() { return fVariable; }

        129: @Override
        130: public boolean equals(Object other) {
        131: return super.baseEquals(other) && ((VariableDMContext)other).fVariable.equals(fVariable);
        132: }

        134: @Override
        135: public int hashCode() {
        136: return super.baseHashCode() + fVariable.hashCode();
        137: }

        139: @Override
        140: public String toString() {
        141: return baseToString() + ".variable(" + fVariable + ")"; //$NON-NLS-1$ //$NON-NLS-2$
        142: }
        143: }
        +
        +
        +
          +
        • Line 127 declares the fVariable +(name) field which along with the parent context uniquely identifies a +PDA variable.
          +
        • +
        +The getLocals() implementation is also very simple as it only uses the +familiar stack PDA debugger +command:
        +
        +
        + + + + + + + + + + +
        org.eclipse.dd.examples.pda.service.PDAStack +- getLocals()

        +
        +
        271:     public void getLocals(final IFrameDMContext frameCtx, final DataRequestMonitor<IVariableDMContext[]> rm) {
        272: // Execute the stack command again.
        273: fCommandCache.execute(
        274: new PDAStackCommand(fCommandControl.getProgramDMContext()),
        275: new DataRequestMonitor<PDAStackCommandResult>(getExecutor(), rm) {
        276: @Override
        277: protected void handleOK() {
        278: // Find the correct PDAFrame
        279: int frameId = getData().fFrames.length - frameCtx.getLevel() - 1;
        280: if (frameId < 0) {
        281: PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid frame level " + frameCtx);
        282: return;
        283: }
        284: PDAFrame pdaFrame = getData().fFrames[frameId];

        286: // Create variable contexts for all variables in frame.
        287: IVariableDMContext[] variableCtxs = new IVariableDMContext[pdaFrame.fVariables.length];
        288: for (int i = 0; i < pdaFrame.fVariables.length; i++) {
        289: variableCtxs[i] = new VariableDMContext(getSession().getId(), frameCtx, pdaFrame.fVariables[i]);
        290: }
        291: rm.setData(variableCtxs);
        292: rm.done();
        293: }
        294: });

        296: }
        +
        +
        +
          +
        • Lines 273-294 send the stack +command to the PDA debugger through the command cache.
        • +
        • Lines 279-284 verify the stack frame number and retrieve the +corresponding PDAFrame object +from the stack result.
        • +
        • Lines 287-290 create the variable Data Model contexts and return +then to the caller.
        • +
        +The IStack interface also defines an IVariableDMData interface which +returns information about the variable.  However, the only method +from this interface used by the Variables view is the getName() method +and it is the only method implemented by the PDA debugger integration:
        +

        Expression Contexts

        +The IExpressions interface +uses a somewhat unusual way of managing contexts.  A client can +create an IExpressionDMContext +context instance for any expression and +parent context by calling the IExpressions.createExpressions() +method.  However, when the returned expression context is +evaluated, if its expression is not valid or if it uses an invalid +parent context, it is guaranteed to fail.  The +PDAExpressions.createExpression() implementation reflects this:
        +
        +
        + + + + + + + + + + +
        org.eclipse.dd.examples.pda.service.PDAExpressions +- createExpression()

        +
        +
        213:     public IExpressionDMContext createExpression(IDMContext ctx, String expression) {
        214: // Create an expression based on the given context and string expression.
        215: // The PDA debugger can only evaluate variables as expressions and only
        216: // in context of a frame.
        217: IFrameDMContext frameCtx = DMContexts.getAncestorOfType(ctx, IFrameDMContext.class);
        218: if (frameCtx != null) {
        219: return new ExpressionDMContext(getSession().getId(), frameCtx, expression);
        220: } else {
        221: // If a frame cannot be found in context, return an "invalid"
        222: // expression context, because a null return value is not allowed.
        223: // Evaluating an invalid expression context will always yield an
        224: // error.
        225: return new InvalidExpressionDMContext(getSession().getId(), ctx, expression);
        226: }
        227: }
        +
        +
        +
        +

        Expression Data
        +

        +The IExpressions interface allows for retrieving data in two stages:
        +
          +
        1. Variable type and other data.
        2. +
        3. Variable value.
        4. +
        +The implementation of the IExpressions.IExpressionDMData interface is +required by the Variables views, however for the PDA debugger the +IExpressionDMData does not carry any additional information beyond the +expression string.
        +

        Formatted Value +Context
        +

        +The IExpressions service allows expression values to be retrieved in +different, client-selectable formats.  For the PDA debugger, only +one formatting is available, which is reflected in the implementation +of +IFormattedValues.getAvailableFormats() +method.   Also, the implementation of the IFormattedValues.getFormattedValueContext() +method is just a formality.
        +
        +
        + + + + + + + + + + +
        org.eclipse.dd.examples.pda.service.PDAExpressions +- getAvailableFormats()

        +
        +
        262:     public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor<String[]> rm) {
        263: // PDA debugger doesn't support formatting the expression. Natural
        264: // formatting is the only available option.
        265: rm.setData(new String[] { NATURAL_FORMAT });
        266: rm.done();
        267: }

        269: public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext exprCtx, String formatId) {
        270: // Creates a context that can be used to retrieve a formatted value.
        271: return new FormattedValueDMContext(this, exprCtx, formatId);
        272: }
        +
        +
        +
        +Only when the formatted vlaue context is evaluated, the var command is sent to the PDA +debugger:
        +
        +
        + + + + + + + + + + +
        org.eclipse.dd.examples.pda.service.PDAExpressions +- getFormattedExpressionValue()

        +
        +
        274:     public void getFormattedExpressionValue(FormattedValueDMContext formattedCtx, 
        275: final DataRequestMonitor<FormattedValueDMData> rm)
        276: {
        277: final ExpressionDMContext exprCtx = DMContexts.getAncestorOfType(formattedCtx, ExpressionDMContext.class);
        278: if (exprCtx != null) {
        279: final IFrameDMContext frameCtx = DMContexts.getAncestorOfType(exprCtx, IFrameDMContext.class);
        280:
        281: // First retrieve the stack depth, needed to properly calculate
        282: // the frame index that is used by the PDAVarCommand.
        283: fStack.getStackDepth(
        284: frameCtx, 0,
        285: new DataRequestMonitor<Integer>(getExecutor(), rm) {
        286: @Override
        287: protected void handleOK() {
        288: // Calculate the frame index.
        289: int frameId = getData() - frameCtx.getLevel() - 1;
        290:
        291: // Send the command to evaluate the variable.
        292: fCommandCache.execute(
        293: new PDAVarCommand(fCommandControl.getProgramDMContext(), frameId, exprCtx.getExpression()),
        294: new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
        295: @Override
        296: protected void handleOK() {
        297: rm.setData(new FormattedValueDMData(getData().fResponseText));
        298: rm.done();
        299: }
        300: });
        301: }
        302: });
        303: } else {
        304: PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid expression context " + formattedCtx);
        305: rm.done();
        306: }
        307: }
        +
        +
        +
          +
        • Line 277 extracts the expression context out of the formattedCtx argument.  If the +expression context is not found, the evaluation is failed.
        • +
        • Line 283 calls the stack service to retrieve the stack +depth.  This step is reqiured because the DPA debugger var command requires a stack frame +number which is counted from the bottom.  Where as the stack frame +level returned in the IFrameDMCotnext.getLevel() +is counted at the top of the stack.
        • +
        • Line 289 calculates the frame number that can be used with the var command.
        • +
        • Lines 292-300 call the var command to evaluate the given +expression and return the result to the client.
          +
        • +
        +

        Additional Resources
        +

        +

        Debug Platform

        +The platform team has evolved and improved the debug APIs over many +releases.  Before starting a debugger integration using DSF, it +would be very helpful to familiarize yourself with materials in these +documents:
        + +

        GDB

        +The DSDP Device Debugging +project is developing a DSF-based debugger integration with GDB as +the main reference implementation of the DSF APIs.  In comparison +with PDA, GDB is a much more complex and feature rich debugger +integration.  The GDB debugger integration is also being +continually developed and improve features and performance.
        +

        TCF

        +The Target Communication Framework which is being developed as part of +the DSDP Target Management +project includes a reference debugger agent implementation. This +reference debugger agent is integrated with Eclipse using DSF.  +The +TCF debugger is more limited in features than the GDB debugger, however +the TCF debugger API is considerably different than the GDB/MI protocol +and is an interesting example integration.
        +
        diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/pda/source_display_1.dia b/plugins/org.eclipse.dd.doc.dsf/docs/pda/source_display_1.dia new file mode 100644 index 0000000000000000000000000000000000000000..7c60f7d3219c6d86ad881e7e7f5031af0e286d6f GIT binary patch literal 2451 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 literal 0 HcmV?d00001 diff --git a/plugins/org.eclipse.dd.doc.dsf/docs/pda/stack_1.dia b/plugins/org.eclipse.dd.doc.dsf/docs/pda/stack_1.dia new file mode 100644 index 0000000000000000000000000000000000000000..e07bbeef391a45bdc2419101a8f8fa12956dfe53 GIT binary patch literal 2012 zcmV<22P60&iwFP!000001MQtlZ{s!)fbaelg7@mse2Jnqn=E$G7A??451XD1+F~4a zWyz4}JbLJFFDc3KLy}*z;s`4PNnm+AL((&&k3*XI^!a%fSdTJJ{3yKXBLMrB3@4H2 zhtr$>-*>-V@&4!A-Y3r&AN9{P7Bfq~BTUS*oBo4R^N+*f)6)|OUJ{|A7zF+TBy#wl z2m&$GLc{)T&$8APctQztEx#(1iv96INh=gHdD9<@$&YCqEkduKN#$~rD2QU~Q3N;r z5BKS#Kg`t(H}ve#Jr`3sj-~ifts3fw>z<-|F5_*rvw4*GT136f3nCSI%;y7y2P|1@37EWgusx zNfd`gFgQ<-QUht~DE4ZZHtZUzAEZBhP}RB-0^Ejc4|JL_Kh#4s+6>E*z%*egPwY?f z5Iv1b=yU(A^%yJJhdqjg=P!~S;|7ppQ3g3ZRC zy9z%<0dG9|YV_xj=%c{t0`TVyz&rV@)*=w)5r}I?AO^(IF~Wh1?FJ(eY2bupfE>UH z=O!9$>I^Uh5SWb!@*iF78P zD4lVVLYysMu^x1e%KcGADHK?%S8w{fIG@;3dY(*3YR?69N@_k2Vhk`s{526`1{}_D zdotl#^0Rv1q<%?7ahC?qn+BJ@*d@W1CPCP65-gvO(YiU1=ow3*8dg4kRmi4ID{p+*u6 z9M%RT`LcXR(z}Z_8w4GaoF7S6-iTQTC9Q-KdJ!mLb@L!428Np~6Ke}}Stq70Acjbo z-6WFK>eE3BHI0{w8SF~MZQ>E9b{w*0ZH_k?ixfc4(gF!agkMt*7$a$cgmBgZ8u{aw zUpGp`R_~h##Z-1ga%Lh~`lAE5i#j4{BayJCiA4VE%lJ<}lqF!o+mR44GYQZgAd?u8 zb8XN8V=_PtaO|8|2N=tLM_GD0wtppJ*s#ndaFmoZ9pD@yR<{bD--wMXB-Kt03vDQU z?I>;vy^)CH=xIkN;hL&Pfefd+un(SG<9ao*2P_Y^aOQ+i{a*4$HP;HRa%d;TsI{MXfu9Ibo%0i z81Qgy-XI8-_O7(pgVWZb-Ew+f>KuSeXW+|@gxX9(um%ay3z1Om4ao$ii(rkW5e_IZ zbs?75g%Gg0sSCL+sS7RUp3vgGaRGxm_Gz4b3jW!FPkX_KwqrGn7%PMt7I19Lv(>O{ zv!d%j_6}CV4&fO`Q6yX-CXLsAI58=Myw-jYXYK&oz-a~a zXb1GH-d6ReEBm}5`V_siL!b7d4{OW%m-(_NX6ar?OzgDmgKdfoN)SZwyI24-8=F%& z+gTst=`tAt-Cm%Mf0|hSy3k%ARC|*(P8SsP&86wO55zc49Lu^7b*V-mX7(7i27xM0 z<>*-GEm^44V>=vbFAni`EPFLUF%#1&A}QvwLyyB!5SDg<A1)L^zIH<~?cfH*hb!2~YV1f=I89GmAln~*jTkRK*8 zR{0L-;c^{porpRhx(pDNxNnC;t;Hb>TXV!B1rD)Ux_D0^H$a3axASv7oCb-gqK74d z%(Q0DrXW)mGM(VvH^n+KI^meXcUv98=qzNkSvEa?8essXC$nZ;q;H_qL1up64lb%X uskN7XN6hNJBld