diff options
Diffstat (limited to 'dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service')
49 files changed, 4451 insertions, 4244 deletions
diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/AbstractDsfDebugServicesFactory.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/AbstractDsfDebugServicesFactory.java index 10fb783818a..37a7b2e27e5 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/AbstractDsfDebugServicesFactory.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/AbstractDsfDebugServicesFactory.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Ericsson - initial API and implementation * Dobrin Alexiev (Texas Instruments) - user groups support (bug 240208) @@ -25,59 +25,99 @@ import org.eclipse.cdt.dsf.service.DsfSession; */ public abstract class AbstractDsfDebugServicesFactory implements IDsfDebugServicesFactory { - @SuppressWarnings("unchecked") - @Override - public <V> V createService(Class<V> clazz, DsfSession session, Object ... optionalArguments) { - if (IBreakpoints.class.isAssignableFrom(clazz)) { - return (V)createBreakpointService(session); - } else if (ICommandControl.class.isAssignableFrom(clazz)) { - return (V)createCommandControl(session); - } else if (IDisassembly.class.isAssignableFrom(clazz)) { - return (V)createDisassemblyService(session); + @SuppressWarnings("unchecked") + @Override + public <V> V createService(Class<V> clazz, DsfSession session, Object... optionalArguments) { + if (IBreakpoints.class.isAssignableFrom(clazz)) { + return (V) createBreakpointService(session); + } else if (ICommandControl.class.isAssignableFrom(clazz)) { + return (V) createCommandControl(session); + } else if (IDisassembly.class.isAssignableFrom(clazz)) { + return (V) createDisassemblyService(session); } else if (IExpressions.class.isAssignableFrom(clazz)) { - return (V)createExpressionService(session); + return (V) createExpressionService(session); } else if (IMemory.class.isAssignableFrom(clazz)) { - return (V)createMemoryService(session); + return (V) createMemoryService(session); } else if (IModules.class.isAssignableFrom(clazz)) { - return (V)createModulesService(session); + return (V) createModulesService(session); } else if (IProcesses.class.isAssignableFrom(clazz)) { - return (V)createProcessesService(session); + return (V) createProcessesService(session); } else if (IRegisters.class.isAssignableFrom(clazz)) { - return (V)createRegistersService(session); + return (V) createRegistersService(session); } else if (IRunControl.class.isAssignableFrom(clazz)) { - return (V)createRunControlService(session); + return (V) createRunControlService(session); } else if (ISourceLookup.class.isAssignableFrom(clazz)) { - return (V)createSourceLookupService(session); + return (V) createSourceLookupService(session); } else if (ISignals.class.isAssignableFrom(clazz)) { - return (V)createSignalsService(session); + return (V) createSignalsService(session); } else if (IStack.class.isAssignableFrom(clazz)) { - return (V)createStackService(session); + return (V) createStackService(session); } else if (ISymbols.class.isAssignableFrom(clazz)) { - return (V)createSymbolsService(session); + return (V) createSymbolsService(session); } else if (IExecutionContextTranslator.class.isAssignableFrom(clazz)) { - return (V)createExecutionContextTranslator(session); - } - + return (V) createExecutionContextTranslator(session); + } + + return null; + } + + protected IBreakpoints createBreakpointService(DsfSession session) { + return null; + } + + protected ICommandControl createCommandControl(DsfSession session) { + return null; + } + + protected IDisassembly createDisassemblyService(DsfSession session) { + return null; + } + + protected IExpressions createExpressionService(DsfSession session) { + return null; + } + + protected IMemory createMemoryService(DsfSession session) { + return null; + } + + protected IModules createModulesService(DsfSession session) { + return null; + } + + protected IProcesses createProcessesService(DsfSession session) { + return null; + } + + protected IRegisters createRegistersService(DsfSession session) { + return null; + } + + protected IRunControl createRunControlService(DsfSession session) { + return null; + } + + protected ISourceLookup createSourceLookupService(DsfSession session) { + return null; + } + + protected ISignals createSignalsService(DsfSession session) { + return null; + } + + protected IStack createStackService(DsfSession session) { + return null; + } + + protected ISymbols createSymbolsService(DsfSession session) { return null; } - protected IBreakpoints createBreakpointService(DsfSession session) { return null; } - protected ICommandControl createCommandControl(DsfSession session) { return null; } - protected IDisassembly createDisassemblyService(DsfSession session) { return null; } - protected IExpressions createExpressionService(DsfSession session) { return null; } - protected IMemory createMemoryService(DsfSession session) { return null; } - protected IModules createModulesService(DsfSession session) { return null; } - protected IProcesses createProcessesService(DsfSession session) { return null; } - protected IRegisters createRegistersService(DsfSession session) { return null; } - protected IRunControl createRunControlService(DsfSession session) { return null; } - protected ISourceLookup createSourceLookupService(DsfSession session) { return null; } - protected ISignals createSignalsService(DsfSession session) { return null; } - protected IStack createStackService(DsfSession session) { return null; } - protected ISymbols createSymbolsService(DsfSession session) { return null; } - /** * @since 2.2 */ - protected IExecutionContextTranslator createExecutionContextTranslator( DsfSession session) { return null; } + protected IExecutionContextTranslator createExecutionContextTranslator(DsfSession session) { + return null; + } } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/AbstractInstruction.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/AbstractInstruction.java index a705634690a..2c9ddf604a6 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/AbstractInstruction.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/AbstractInstruction.java @@ -23,15 +23,15 @@ import java.math.BigInteger; * @since 2.2 */ public abstract class AbstractInstruction implements IInstructionWithSize, IInstructionWithRawOpcodes { - /* - * @see org.eclipse.cdt.dsf.debug.service.IInstructionWithSize#getSize() - */ - @Override - public Integer getSize() { - // unknown size - return null; - } - + /* + * @see org.eclipse.cdt.dsf.debug.service.IInstructionWithSize#getSize() + */ + @Override + public Integer getSize() { + // unknown size + return null; + } + /** * @since 2.5 */ diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/BreakpointsMediator.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/BreakpointsMediator.java index 359780a716d..b687727e93b 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/BreakpointsMediator.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/BreakpointsMediator.java @@ -10,7 +10,7 @@ * * Contributors: * Wind River - Initial API and implementation - * Ericsson - Low-level breakpoints integration + * Ericsson - Low-level breakpoints integration *******************************************************************************/ package org.eclipse.cdt.dsf.debug.service; @@ -51,9 +51,9 @@ import org.eclipse.debug.core.model.IBreakpoint; import org.osgi.framework.BundleContext; /** - * Breakpoints mediator is a DSF service which synchronizes breakpoints in the - * IDE and breakpoints in the debugger. The IDE breakpoints are managed by the - * {@link IBreakpointManager} while the debugger breakpoints are accessed + * Breakpoints mediator is a DSF service which synchronizes breakpoints in the + * IDE and breakpoints in the debugger. The IDE breakpoints are managed by the + * {@link IBreakpointManager} while the debugger breakpoints are accessed * through the {@link IBreakpoints} service. * <p> * This class is not intended to be extended by clients. Instead clients should @@ -61,473 +61,477 @@ import org.osgi.framework.BundleContext; * to translate breakpoint attributes between the IDE and debugger breakpoints. * <p> * Note: This breakpoint mediator implementation has been superseded by a more - * powerful {@link BreakpointsMediator2} implementation. - * + * powerful {@link BreakpointsMediator2} implementation. + * * @since 1.0 * @see IBreakpointAttributeTranslator * @see BreakpointsMediator2 */ -public class BreakpointsMediator extends AbstractDsfService implements IBreakpointManagerListener, IBreakpointListener -{ - - /** - * The attribute translator that this service will use to map the platform - * breakpoint attributes to the corresponding target attributes, and vice - * versa. - */ - private IBreakpointAttributeTranslator fAttributeTranslator; - - /** - * DSF Debug service for creating breakpoints. - */ - IBreakpoints fBreakpoints; - - /** - * Platform breakpoint manager - */ - IBreakpointManager fBreakpointManager; - - - /////////////////////////////////////////////////////////////////////////// - // Breakpoints tracking - /////////////////////////////////////////////////////////////////////////// - - /** - * Holds the set of platform breakpoints with their corresponding back-end - * breakpoint attributes, per context (i.e. each platform breakpoint is - * replicated for each execution context). - * - Context entry added/removed on start/stopTrackingBreakpoints() - * - Augmented on breakpointAdded() - * - Modified on breakpointChanged() - * - Diminished on breakpointRemoved() - */ - private Map<IBreakpointsTargetDMContext, Map<IBreakpoint, List<Map<String, Object>>>> fPlatformBPs = - new HashMap<IBreakpointsTargetDMContext, Map<IBreakpoint, List<Map<String, Object>>>>(); - - /** - * Holds the mapping from platform breakpoint to the corresponding target - * breakpoint(s), per context. There can be multiple back-end BPs for a - * single platform BP in the case of [1] multiple target contexts, and/or - * [2] thread filtering. - * Updated when: - * - We start/stop tracking an execution context - * - A platform breakpoint is added/removed - * - A thread filter is applied/removed - */ - private Map<IBreakpointsTargetDMContext, Map<IBreakpoint, List<IBreakpointDMContext>>> fBreakpointDMContexts = - new HashMap<IBreakpointsTargetDMContext, Map<IBreakpoint, List<IBreakpointDMContext>>>(); - - /** - * Due to the very asynchronous nature of DSF, a new breakpoint request can - * pop up at any time before an ongoing one is completed. The following set - * is used to store requests until the ongoing operation completes. - */ - private Set<IBreakpoint> fPendingRequests = new HashSet<IBreakpoint>(); - +public class BreakpointsMediator extends AbstractDsfService implements IBreakpointManagerListener, IBreakpointListener { + + /** + * The attribute translator that this service will use to map the platform + * breakpoint attributes to the corresponding target attributes, and vice + * versa. + */ + private IBreakpointAttributeTranslator fAttributeTranslator; + + /** + * DSF Debug service for creating breakpoints. + */ + IBreakpoints fBreakpoints; + + /** + * Platform breakpoint manager + */ + IBreakpointManager fBreakpointManager; + + /////////////////////////////////////////////////////////////////////////// + // Breakpoints tracking + /////////////////////////////////////////////////////////////////////////// + + /** + * Holds the set of platform breakpoints with their corresponding back-end + * breakpoint attributes, per context (i.e. each platform breakpoint is + * replicated for each execution context). + * - Context entry added/removed on start/stopTrackingBreakpoints() + * - Augmented on breakpointAdded() + * - Modified on breakpointChanged() + * - Diminished on breakpointRemoved() + */ + private Map<IBreakpointsTargetDMContext, Map<IBreakpoint, List<Map<String, Object>>>> fPlatformBPs = new HashMap<IBreakpointsTargetDMContext, Map<IBreakpoint, List<Map<String, Object>>>>(); + + /** + * Holds the mapping from platform breakpoint to the corresponding target + * breakpoint(s), per context. There can be multiple back-end BPs for a + * single platform BP in the case of [1] multiple target contexts, and/or + * [2] thread filtering. + * Updated when: + * - We start/stop tracking an execution context + * - A platform breakpoint is added/removed + * - A thread filter is applied/removed + */ + private Map<IBreakpointsTargetDMContext, Map<IBreakpoint, List<IBreakpointDMContext>>> fBreakpointDMContexts = new HashMap<IBreakpointsTargetDMContext, Map<IBreakpoint, List<IBreakpointDMContext>>>(); + + /** + * Due to the very asynchronous nature of DSF, a new breakpoint request can + * pop up at any time before an ongoing one is completed. The following set + * is used to store requests until the ongoing operation completes. + */ + private Set<IBreakpoint> fPendingRequests = new HashSet<IBreakpoint>(); + /** * @see fPendingRequests */ private Set<IBreakpoint> fPendingBreakpoints = new HashSet<IBreakpoint>(); - - /////////////////////////////////////////////////////////////////////////// - // AbstractDsfService - /////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////// + // AbstractDsfService + /////////////////////////////////////////////////////////////////////////// /** * The service constructor - * + * * @param session * @param debugModelId */ public BreakpointsMediator(DsfSession session, IBreakpointAttributeTranslator attributeTranslator) { - super(session); - fAttributeTranslator = attributeTranslator; + super(session); + fAttributeTranslator = attributeTranslator; + } + + @Override + public void initialize(final RequestMonitor rm) { + // - Collect references for the services we interact with + // - Register to interesting events + // - Obtain the list of platform breakpoints + // - Register the service for interested parties + super.initialize(new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + doInitialize(rm); + } + }); + } + + /** + * Asynchronous service initialization + * + * @param requestMonitor + */ + private void doInitialize(RequestMonitor rm) { + + // Get the services references + fBreakpoints = getServicesTracker().getService(IBreakpoints.class); + fBreakpointManager = DebugPlugin.getDefault().getBreakpointManager(); + fAttributeTranslator.initialize(this); + + // Register to the useful events + fBreakpointManager.addBreakpointListener(this); + fBreakpointManager.addBreakpointManagerListener(this); + + // Register this service + register(new String[] { BreakpointsMediator.class.getName() }, new Hashtable<String, String>()); + + rm.done(); } - @Override - public void initialize(final RequestMonitor rm) { - // - Collect references for the services we interact with - // - Register to interesting events - // - Obtain the list of platform breakpoints - // - Register the service for interested parties - super.initialize( - new RequestMonitor(getExecutor(), rm) { - @Override - protected void handleSuccess() { - doInitialize(rm); - }}); - } - - /** - * Asynchronous service initialization - * - * @param requestMonitor - */ - private void doInitialize(RequestMonitor rm) { - - // Get the services references - fBreakpoints = getServicesTracker().getService(IBreakpoints.class); - fBreakpointManager = DebugPlugin.getDefault().getBreakpointManager(); - fAttributeTranslator.initialize(this); - - // Register to the useful events - fBreakpointManager.addBreakpointListener(this); - fBreakpointManager.addBreakpointManagerListener( this ); - - // Register this service - register(new String[] { BreakpointsMediator.class.getName() }, - new Hashtable<String, String>()); - - rm.done(); - } - - @Override - public void shutdown(final RequestMonitor rm) { - // - Un-register the service - // - Stop listening to events - // - Remove the breakpoints installed by this service - // - // Since we are shutting down, there is no overwhelming need - // to keep the maps coherent... - - // Stop accepting requests and events - unregister(); - fBreakpointManager.removeBreakpointListener(this); - fBreakpointManager.removeBreakpointManagerListener( this ); - fAttributeTranslator.dispose(); - - // Cleanup the breakpoints that are still installed by the service. - // Use a counting monitor which will call mom to complete the shutdown - // after the breakpoints are un-installed (successfully or not). - CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) { - @Override - protected void handleCompleted() { - BreakpointsMediator.super.shutdown(rm); - } - }; - - // We have to make a copy of the fPlatformBPs keys because uninstallBreakpoints() - // modifies the map as it walks through it. - List<IBreakpointsTargetDMContext> platformBPKeysCopy = new ArrayList<IBreakpointsTargetDMContext>(fPlatformBPs.size()); - platformBPKeysCopy.addAll(0, fPlatformBPs.keySet()); - for (IBreakpointsTargetDMContext dmc : platformBPKeysCopy) { - stopTrackingBreakpoints(dmc, countingRm); - } - countingRm.setDoneCount(platformBPKeysCopy.size()); - } - @Override - protected BundleContext getBundleContext() { - return DsfPlugin.getBundleContext(); - } + public void shutdown(final RequestMonitor rm) { + // - Un-register the service + // - Stop listening to events + // - Remove the breakpoints installed by this service + // + // Since we are shutting down, there is no overwhelming need + // to keep the maps coherent... + + // Stop accepting requests and events + unregister(); + fBreakpointManager.removeBreakpointListener(this); + fBreakpointManager.removeBreakpointManagerListener(this); + fAttributeTranslator.dispose(); + + // Cleanup the breakpoints that are still installed by the service. + // Use a counting monitor which will call mom to complete the shutdown + // after the breakpoints are un-installed (successfully or not). + CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + BreakpointsMediator.super.shutdown(rm); + } + }; + + // We have to make a copy of the fPlatformBPs keys because uninstallBreakpoints() + // modifies the map as it walks through it. + List<IBreakpointsTargetDMContext> platformBPKeysCopy = new ArrayList<IBreakpointsTargetDMContext>( + fPlatformBPs.size()); + platformBPKeysCopy.addAll(0, fPlatformBPs.keySet()); + for (IBreakpointsTargetDMContext dmc : platformBPKeysCopy) { + stopTrackingBreakpoints(dmc, countingRm); + } + countingRm.setDoneCount(platformBPKeysCopy.size()); + } - /////////////////////////////////////////////////////////////////////////// - // IBreakpointsManager - /////////////////////////////////////////////////////////////////////////// + @Override + protected BundleContext getBundleContext() { + return DsfPlugin.getBundleContext(); + } + /////////////////////////////////////////////////////////////////////////// + // IBreakpointsManager + /////////////////////////////////////////////////////////////////////////// /** - * Install and begin tracking breakpoints for given context. The service - * will keep installing new breakpoints that appear in the IDE for this - * context until {@link #uninstallBreakpoints(IDMContext)} is called for that - * context. - * @param dmc Context to start tracking breakpoints for. - * @param rm Completion callback. - */ - public void startTrackingBreakpoints(IBreakpointsTargetDMContext dmc, final RequestMonitor rm) { - // - Augment the maps with the new execution context - // - Install the platform breakpoints on the selected target - - // Validate the context - final IBreakpointsTargetDMContext breakpointsDmc = DMContexts.getAncestorOfType(dmc, IBreakpointsTargetDMContext.class); - if (breakpointsDmc == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid context type", null)); //$NON-NLS-1$ - rm.done(); - return; - } - - // Make sure a mapping for this execution context does not already exist + * Install and begin tracking breakpoints for given context. The service + * will keep installing new breakpoints that appear in the IDE for this + * context until {@link #uninstallBreakpoints(IDMContext)} is called for that + * context. + * @param dmc Context to start tracking breakpoints for. + * @param rm Completion callback. + */ + public void startTrackingBreakpoints(IBreakpointsTargetDMContext dmc, final RequestMonitor rm) { + // - Augment the maps with the new execution context + // - Install the platform breakpoints on the selected target + + // Validate the context + final IBreakpointsTargetDMContext breakpointsDmc = DMContexts.getAncestorOfType(dmc, + IBreakpointsTargetDMContext.class); + if (breakpointsDmc == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid context type", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Make sure a mapping for this execution context does not already exist Map<IBreakpoint, List<Map<String, Object>>> platformBPs = fPlatformBPs.get(dmc); if (platformBPs != null) { - rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INTERNAL_ERROR, "Context already initialized", null)); //$NON-NLS-1$ - rm.done(); - return; + rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INTERNAL_ERROR, "Context already initialized", //$NON-NLS-1$ + null)); + rm.done(); + return; } - // Create entries in the breakpoint tables for the new context. These entries should only - // be removed when this service stops tracking breakpoints for the given context. - fPlatformBPs.put(breakpointsDmc, new HashMap<IBreakpoint, List<Map<String, Object>>>()); + // Create entries in the breakpoint tables for the new context. These entries should only + // be removed when this service stops tracking breakpoints for the given context. + fPlatformBPs.put(breakpointsDmc, new HashMap<IBreakpoint, List<Map<String, Object>>>()); fBreakpointDMContexts.put(breakpointsDmc, new HashMap<IBreakpoint, List<IBreakpointDMContext>>()); - // Install the platform breakpoints (stored in fPlatformBPs) on the target. - // We need to use a background thread for this operation because we are + // Install the platform breakpoints (stored in fPlatformBPs) on the target. + // We need to use a background thread for this operation because we are // accessing the resources system to retrieve the breakpoint attributes. // Accessing the resources system potentially requires using global locks. // Also we will be calling IBreakpointAttributeTranslator which is prohibited // from being called on the session executor thread. new Job("MI Debugger: Install initial breakpoint list.") { //$NON-NLS-1$ - { setSystem(true); } + { + setSystem(true); + } // Get the stored breakpoints from the platform BreakpointManager // and install them on the target - @Override - protected IStatus run(IProgressMonitor monitor) { - // Read initial breakpoints from platform. Copy the breakpoint attributes into a local map. - // Note that we cannot write data into fPlatformBPs table here directly because we are not - // executing on the dispatch thread. - final Map<IBreakpoint, List<Map<String, Object>>> initialPlatformBPs = - new HashMap<IBreakpoint, List<Map<String, Object>>>(); - try { - // Get the stored breakpoint list from the platform BreakpointManager - IBreakpoint[] bps = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(); - // Single out the installable breakpoints... - for (IBreakpoint bp : bps) { - if (fAttributeTranslator.supportsBreakpoint(bp)) { - // Retrieve the breakpoint attributes - List<Map<String, Object>> attrsArray = - fAttributeTranslator.getBreakpointAttributes(bp, fBreakpointManager.isEnabled()); - // Store it for now (will be installed on the dispatcher thread) - initialPlatformBPs.put(bp, attrsArray); - } - } - } catch (CoreException e) { - IStatus status = new Status( - IStatus.ERROR, DsfPlugin.PLUGIN_ID, REQUEST_FAILED, "Unable to read initial breakpoint attributes", e); //$NON-NLS-1$ - rm.setStatus(status); - rm.done(); - return status; - } - - // Submit the runnable to plant the breakpoints on dispatch thread. - getExecutor().submit(new Runnable() { - @Override - public void run() { - installInitialBreakpoints(breakpointsDmc, initialPlatformBPs, rm); - } - }); - - return Status.OK_STATUS; - } - }.schedule(); - } - - /** - * Installs the breakpoints that existed prior to the activation of this - * breakpoints context. - */ - private void installInitialBreakpoints(final IBreakpointsTargetDMContext dmc, - Map<IBreakpoint, List<Map<String, Object>>> initialPlatformBPs, - RequestMonitor rm) - { - // Retrieve the set of platform breakpoints for this context - Map<IBreakpoint, List<Map<String, Object>>> platformBPs = fPlatformBPs.get(dmc); - if (platformBPs == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ - rm.done(); - return; - } - - // Install the individual breakpoints on the executor thread - // Requires a counting monitor to know when we're done - final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm); - countingRm.setDoneCount(initialPlatformBPs.size()); - - for (final IBreakpoint bp : initialPlatformBPs.keySet()) { - final List<Map<String, Object>> attrs = initialPlatformBPs.get(bp); - // Upon determining the debuggerPath, the breakpoint is installed - installBreakpoint(dmc, bp, attrs, new RequestMonitor(getExecutor(), countingRm)); - } - } - - - public void stopTrackingBreakpoints(final IBreakpointsTargetDMContext dmc, final RequestMonitor rm) { - // - Remove the target breakpoints for the given execution context - // - Update the maps - - // Remove the breakpoints for given DMC from the internal maps. - Map<IBreakpoint, List<Map<String, Object>>> platformBPs = fPlatformBPs.get(dmc); - if (platformBPs == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INTERNAL_ERROR, "Breakpoints not installed for given context", null)); //$NON-NLS-1$ - rm.done(); - return; - } - - // Uninstall the individual breakpoints on the executor thread - // Requires a counting monitor to know when we're done - final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm); - countingRm.setDoneCount(platformBPs.size()); - - for (final IBreakpoint bp : platformBPs.keySet()) { - uninstallBreakpoint(dmc, bp, - new RequestMonitor(getExecutor(), countingRm) { - @Override - protected void handleCompleted() { - // After the breakpoint is removed from target. Call the attribute - // translator to refresh breakpoint status based on the new target - // breakpoint status. - new Job("Breakpoint status update") { //$NON-NLS-1$ - { setSystem(true); } - @Override - protected IStatus run(IProgressMonitor monitor) { - fAttributeTranslator.updateBreakpointStatus(bp); - return Status.OK_STATUS; - }; - }.schedule(); - - countingRm.done(); - } - }); - } - } - - /////////////////////////////////////////////////////////////////////////// - // Back-end interface functions - /////////////////////////////////////////////////////////////////////////// + @Override + protected IStatus run(IProgressMonitor monitor) { + // Read initial breakpoints from platform. Copy the breakpoint attributes into a local map. + // Note that we cannot write data into fPlatformBPs table here directly because we are not + // executing on the dispatch thread. + final Map<IBreakpoint, List<Map<String, Object>>> initialPlatformBPs = new HashMap<IBreakpoint, List<Map<String, Object>>>(); + try { + // Get the stored breakpoint list from the platform BreakpointManager + IBreakpoint[] bps = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(); + // Single out the installable breakpoints... + for (IBreakpoint bp : bps) { + if (fAttributeTranslator.supportsBreakpoint(bp)) { + // Retrieve the breakpoint attributes + List<Map<String, Object>> attrsArray = fAttributeTranslator.getBreakpointAttributes(bp, + fBreakpointManager.isEnabled()); + // Store it for now (will be installed on the dispatcher thread) + initialPlatformBPs.put(bp, attrsArray); + } + } + } catch (CoreException e) { + IStatus status = new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, REQUEST_FAILED, + "Unable to read initial breakpoint attributes", e); //$NON-NLS-1$ + rm.setStatus(status); + rm.done(); + return status; + } + + // Submit the runnable to plant the breakpoints on dispatch thread. + getExecutor().submit(new Runnable() { + @Override + public void run() { + installInitialBreakpoints(breakpointsDmc, initialPlatformBPs, rm); + } + }); + + return Status.OK_STATUS; + } + }.schedule(); + } + + /** + * Installs the breakpoints that existed prior to the activation of this + * breakpoints context. + */ + private void installInitialBreakpoints(final IBreakpointsTargetDMContext dmc, + Map<IBreakpoint, List<Map<String, Object>>> initialPlatformBPs, RequestMonitor rm) { + // Retrieve the set of platform breakpoints for this context + Map<IBreakpoint, List<Map<String, Object>>> platformBPs = fPlatformBPs.get(dmc); + if (platformBPs == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Install the individual breakpoints on the executor thread + // Requires a counting monitor to know when we're done + final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm); + countingRm.setDoneCount(initialPlatformBPs.size()); + + for (final IBreakpoint bp : initialPlatformBPs.keySet()) { + final List<Map<String, Object>> attrs = initialPlatformBPs.get(bp); + // Upon determining the debuggerPath, the breakpoint is installed + installBreakpoint(dmc, bp, attrs, new RequestMonitor(getExecutor(), countingRm)); + } + } + + public void stopTrackingBreakpoints(final IBreakpointsTargetDMContext dmc, final RequestMonitor rm) { + // - Remove the target breakpoints for the given execution context + // - Update the maps + + // Remove the breakpoints for given DMC from the internal maps. + Map<IBreakpoint, List<Map<String, Object>>> platformBPs = fPlatformBPs.get(dmc); + if (platformBPs == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INTERNAL_ERROR, + "Breakpoints not installed for given context", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Uninstall the individual breakpoints on the executor thread + // Requires a counting monitor to know when we're done + final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm); + countingRm.setDoneCount(platformBPs.size()); + + for (final IBreakpoint bp : platformBPs.keySet()) { + uninstallBreakpoint(dmc, bp, new RequestMonitor(getExecutor(), countingRm) { + @Override + protected void handleCompleted() { + // After the breakpoint is removed from target. Call the attribute + // translator to refresh breakpoint status based on the new target + // breakpoint status. + new Job("Breakpoint status update") { //$NON-NLS-1$ + { + setSystem(true); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + fAttributeTranslator.updateBreakpointStatus(bp); + return Status.OK_STATUS; + }; + }.schedule(); + + countingRm.done(); + } + }); + } + } + + /////////////////////////////////////////////////////////////////////////// + // Back-end interface functions + /////////////////////////////////////////////////////////////////////////// /** * Install a new platform breakpoint on the back-end. A platform breakpoint * can resolve into multiple back-end breakpoints when threads are taken * into account. - * + * * @param dmc * @param breakpoint * @param attrsList * @param rm */ private void installBreakpoint(IBreakpointsTargetDMContext dmc, final IBreakpoint breakpoint, - final List<Map<String, Object>> attrsList, final RequestMonitor rm) - { - // Retrieve the set of breakpoints for this context - final Map<IBreakpoint, List<Map<String, Object>>> platformBPs = fPlatformBPs.get(dmc); - assert platformBPs != null; - - final Map<IBreakpoint, List<IBreakpointDMContext>> breakpointIDs = fBreakpointDMContexts.get(dmc); - assert breakpointIDs != null; // fBreakpointIds should be updated in parallel with fPlatformBPs - - // Ensure the breakpoint is not already installed - if (platformBPs.containsKey(breakpoint)) { - rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_STATE, "Breakpoint already installed", null)); //$NON-NLS-1$ - rm.done(); - return; - } - - // Update the breakpoint status when all back-end breakpoints have been installed - final CountingRequestMonitor installRM = new CountingRequestMonitor(getExecutor(), rm) { + final List<Map<String, Object>> attrsList, final RequestMonitor rm) { + // Retrieve the set of breakpoints for this context + final Map<IBreakpoint, List<Map<String, Object>>> platformBPs = fPlatformBPs.get(dmc); + assert platformBPs != null; + + final Map<IBreakpoint, List<IBreakpointDMContext>> breakpointIDs = fBreakpointDMContexts.get(dmc); + assert breakpointIDs != null; // fBreakpointIds should be updated in parallel with fPlatformBPs + + // Ensure the breakpoint is not already installed + if (platformBPs.containsKey(breakpoint)) { + rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_STATE, "Breakpoint already installed", //$NON-NLS-1$ + null)); + rm.done(); + return; + } + + // Update the breakpoint status when all back-end breakpoints have been installed + final CountingRequestMonitor installRM = new CountingRequestMonitor(getExecutor(), rm) { @Override protected void handleCompleted() { // Store the platform breakpoint platformBPs.put(breakpoint, attrsList); - new Job("Breakpoint status update") { //$NON-NLS-1$ - { setSystem(true); } - @Override - protected IStatus run(IProgressMonitor monitor) { - fAttributeTranslator.updateBreakpointStatus(breakpoint); - return Status.OK_STATUS; - }; - }.schedule(); - rm.done(); + new Job("Breakpoint status update") { //$NON-NLS-1$ + { + setSystem(true); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + fAttributeTranslator.updateBreakpointStatus(breakpoint); + return Status.OK_STATUS; + }; + }.schedule(); + rm.done(); } }; - // A back-end breakpoint needs to be installed for each specified attributes map. + // A back-end breakpoint needs to be installed for each specified attributes map. installRM.setDoneCount(attrsList.size()); // Install the back-end breakpoint(s) for (Map<String, Object> attrs : attrsList) { - fBreakpoints.insertBreakpoint( - dmc, attrs, - new DataRequestMonitor<IBreakpointDMContext>(getExecutor(), installRM) { - @Override - protected void handleCompleted() { - List<IBreakpointDMContext> list = breakpointIDs.get(breakpoint); - if (list == null) { - list = new LinkedList<IBreakpointDMContext>(); - breakpointIDs.put(breakpoint, list); - } - - if (isSuccess()) { - // Add the breakpoint back-end mapping - list.add(getData()); - } else { - // TODO (bug 219841): need to add breakpoint error status tracking - // in addition to fBreakpointDMContexts. - } - installRM.done(); - } - }); + fBreakpoints.insertBreakpoint(dmc, attrs, + new DataRequestMonitor<IBreakpointDMContext>(getExecutor(), installRM) { + @Override + protected void handleCompleted() { + List<IBreakpointDMContext> list = breakpointIDs.get(breakpoint); + if (list == null) { + list = new LinkedList<IBreakpointDMContext>(); + breakpointIDs.put(breakpoint, list); + } + + if (isSuccess()) { + // Add the breakpoint back-end mapping + list.add(getData()); + } else { + // TODO (bug 219841): need to add breakpoint error status tracking + // in addition to fBreakpointDMContexts. + } + installRM.done(); + } + }); } } - /** - * Un-install an individual breakpoint on the back-end. For one platform - * breakpoint, there could be multiple corresponding back-end breakpoints. - * - * @param dmc - * @param breakpoint - * @param rm - */ - private void uninstallBreakpoint(final IBreakpointsTargetDMContext dmc, final IBreakpoint breakpoint, - final RequestMonitor rm) - { - // Remove completion monitor - CountingRequestMonitor removeRM = new CountingRequestMonitor(getExecutor(), rm) { + /** + * Un-install an individual breakpoint on the back-end. For one platform + * breakpoint, there could be multiple corresponding back-end breakpoints. + * + * @param dmc + * @param breakpoint + * @param rm + */ + private void uninstallBreakpoint(final IBreakpointsTargetDMContext dmc, final IBreakpoint breakpoint, + final RequestMonitor rm) { + // Remove completion monitor + CountingRequestMonitor removeRM = new CountingRequestMonitor(getExecutor(), rm) { @Override protected void handleCompleted() { - // Remove the attributes mapping - Map<IBreakpoint, List<Map<String, Object>>> platformBPs = fPlatformBPs.get(dmc); - if (platformBPs == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ - rm.done(); - return; - } - platformBPs.remove(breakpoint); + // Remove the attributes mapping + Map<IBreakpoint, List<Map<String, Object>>> platformBPs = fPlatformBPs.get(dmc); + if (platformBPs == null) { + rm.setStatus( + new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.done(); + return; + } + platformBPs.remove(breakpoint); // Remove the back-end mapping - Map<IBreakpoint, List<IBreakpointDMContext>> breakpointIDs = fBreakpointDMContexts.get(dmc); - if (breakpointIDs == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid breakpoint", null)); //$NON-NLS-1$ - rm.done(); - return; - } - breakpointIDs.get(breakpoint).clear(); - breakpointIDs.remove(breakpoint); - - // Update breakpoint status - new Job("Breakpoint status update") { //$NON-NLS-1$ - { setSystem(true); } - @Override - protected IStatus run(IProgressMonitor monitor) { - fAttributeTranslator.updateBreakpointStatus(breakpoint); - return Status.OK_STATUS; - }; - }.schedule(); - - rm.done(); + Map<IBreakpoint, List<IBreakpointDMContext>> breakpointIDs = fBreakpointDMContexts.get(dmc); + if (breakpointIDs == null) { + rm.setStatus( + new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid breakpoint", null)); //$NON-NLS-1$ + rm.done(); + return; + } + breakpointIDs.get(breakpoint).clear(); + breakpointIDs.remove(breakpoint); + + // Update breakpoint status + new Job("Breakpoint status update") { //$NON-NLS-1$ + { + setSystem(true); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + fAttributeTranslator.updateBreakpointStatus(breakpoint); + return Status.OK_STATUS; + }; + }.schedule(); + + rm.done(); } }; // Remove the back-end breakpoints Map<IBreakpoint, List<IBreakpointDMContext>> breakpointIDs = fBreakpointDMContexts.get(dmc); - if (breakpointIDs == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid breakpoint", null)); //$NON-NLS-1$ - rm.done(); - return; - } - - List<IBreakpointDMContext> list = breakpointIDs.get(breakpoint); - int count = 0; - if (list != null) { - for (IBreakpointDMContext bp : list) { - fBreakpoints.removeBreakpoint(bp, removeRM); - } - count = list.size(); - } - removeRM.setDoneCount(count); - } - + if (breakpointIDs == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid breakpoint", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + List<IBreakpointDMContext> list = breakpointIDs.get(breakpoint); + int count = 0; + if (list != null) { + for (IBreakpointDMContext bp : list) { + fBreakpoints.removeBreakpoint(bp, removeRM); + } + count = list.size(); + } + removeRM.setDoneCount(count); + } + /** * Modify an individual breakpoint - * + * * @param context * @param breakpoint * @param attributes @@ -535,245 +539,247 @@ public class BreakpointsMediator extends AbstractDsfService implements IBreakpoi * @throws CoreException */ private void modifyBreakpoint(final IBreakpointsTargetDMContext context, final IBreakpoint breakpoint, - final List<Map<String, Object>> newAttrsList0, final IMarkerDelta oldValues, final RequestMonitor rm) - { - // This method uses several lists to track the changed breakpoints: - // commonAttrsList - attributes which have not changed - // oldAttrsList - attributes for the breakpoint before the change - // newAttrsList - attributes for the breakpoint after the change - // oldBpContexts - target-side breakpoints from before the change - // newBpContexts - target-side breakpoints after the change - // attrDeltasList - changes in the attributes for each attribute map in - // oldAttrsList and newAttrsList - - // Get the maps - final Map<IBreakpoint, List<Map<String, Object>>> platformBPs = fPlatformBPs.get(context); - final Map<IBreakpoint, List<IBreakpointDMContext>> breakpointIDs = fBreakpointDMContexts.get(context); - if (platformBPs == null || breakpointIDs == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ - rm.done(); - return; - } - - // Get the original breakpoint attributes - final List<Map<String, Object>> oldAttrsList0 = platformBPs.get(breakpoint); - if (oldAttrsList0 == null) { - rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid breakpoint", null)); //$NON-NLS-1$ - rm.done(); - return; - } - - // Get the list of corresponding back-end breakpoints - final List<IBreakpointDMContext> oldBpContexts = new ArrayList<IBreakpointDMContext>(breakpointIDs.get(breakpoint)); - - // Calculate the list of attributes maps that have not changed. - // Immediately add these to the list of new breakpoint contexts, - // and remove them from further breakpoint attribute comparisons. - final List<Map<String, Object>> commonAttrsList = getCommonAttributeMaps(newAttrsList0, oldAttrsList0); - final List<IBreakpointDMContext> newBpContexts = new ArrayList<IBreakpointDMContext>(commonAttrsList.size()); - - final List<Map<String, Object>> newAttrsList = new ArrayList<Map<String, Object>>(newAttrsList0); - newAttrsList.removeAll(commonAttrsList); - - List<Map<String, Object>> oldAttrsList = new ArrayList<Map<String, Object>>(oldAttrsList0); - for (int i = 0; i < oldAttrsList.size(); i++) { - if (commonAttrsList.contains(oldAttrsList.get(i))) { - if (oldBpContexts.size() > i) { - newBpContexts.add(oldBpContexts.remove(i)); - } - } - } - oldAttrsList.removeAll(commonAttrsList); - - // Create a list of attribute changes. The length of this list will - // always be max(oldAttrList.size(), newAttrsList.size()), padded with - // null's if oldAttrsList was longer. - final List<Map<String, Object>> attrDeltasList = getAttributesDeltas(oldAttrsList, newAttrsList); - - // Create the request monitor that will be called when all - // modifying/inserting/removing is complete. - final CountingRequestMonitor countingRM = new CountingRequestMonitor(getExecutor(), rm) { - @Override - protected void handleCompleted() { - // Save the new list of breakpoint contexts and attributes - breakpointIDs.put(breakpoint, newBpContexts); - newAttrsList.addAll(commonAttrsList); - platformBPs.put(breakpoint, newAttrsList); - - // Update breakpoint status. updateBreakpointStatus() cannot - // be called on the executor thread, so we need to - // use a Job. - new Job("Breakpoint status update") { //$NON-NLS-1$ - { setSystem(true); } - @Override - protected IStatus run(IProgressMonitor monitor) { - fAttributeTranslator.updateBreakpointStatus(breakpoint); - return Status.OK_STATUS; - }; - }.schedule(); - - super.handleCompleted(); - } - }; - - // Set the count, if could be zero if no breakpoints have actually changed. - countingRM.setDoneCount(attrDeltasList.size()); - - // Process the changed breakpoints. - for (int i = 0; i < attrDeltasList.size(); i++) { - if (attrDeltasList.get(i) == null) { - // The list of new attribute maps was shorter than the old. - // Remove the corresponding target-side bp. - fBreakpoints.removeBreakpoint(oldBpContexts.get(i), countingRM); - } else if ( i >= oldBpContexts.size()) { - // The list of new attribute maps was longer, just insert - // the new breakpoint - final Map<String, Object> attrs = newAttrsList.get(i); - fBreakpoints.insertBreakpoint( - context, attrs, - new DataRequestMonitor<IBreakpointDMContext>(getExecutor(), countingRM) { - @Override - protected void handleSuccess() { - newBpContexts.add(getData()); - countingRM.done(); - } - }); - } else if ( !fAttributeTranslator.canUpdateAttributes(oldBpContexts.get(i), attrDeltasList.get(i)) ) { - // The attribute translator tells us that the debugger cannot modify the - // breakpoint to change the given attributes. Remove the breakpoint - // and insert a new one. - final Map<String, Object> attrs = newAttrsList.get(i); - fBreakpoints.removeBreakpoint( - oldBpContexts.get(i), - new RequestMonitor(getExecutor(), countingRM) { - @Override - protected void handleCompleted() { - fBreakpoints.insertBreakpoint( - context, attrs, - new DataRequestMonitor<IBreakpointDMContext>(getExecutor(), countingRM) { - @Override - protected void handleCompleted() { - if (isSuccess()) { - newBpContexts.add(getData()); - } else { - // TODO (bug 219841): need to add breakpoint error status tracking - // in addition to fBreakpointDMContexts. - } - countingRM.done(); - } - }); - } - }); - } else { - // The back end can modify the breakpoint. Update the breakpoint with the - // new attributes. - final IBreakpointDMContext bpCtx = oldBpContexts.get(i); - fBreakpoints.updateBreakpoint( - oldBpContexts.get(i), newAttrsList.get(i), - new RequestMonitor(getExecutor(), countingRM) { - @Override - protected void handleSuccess() { - newBpContexts.add(bpCtx); - countingRM.done(); - } - }); - } - } - } - - private List<Map<String, Object>> getCommonAttributeMaps(List<Map<String, Object>> array1, List<Map<String, Object>> array2) - { - List<Map<String, Object>> intersection = new LinkedList<Map<String, Object>>(); - List<Map<String, Object>> list2 = new ArrayList<Map<String, Object>>(array2); - for (Map<String, Object> array1Map : array1) { - if (list2.remove(array1Map)) { - intersection.add(array1Map); - } - } - return intersection; + final List<Map<String, Object>> newAttrsList0, final IMarkerDelta oldValues, final RequestMonitor rm) { + // This method uses several lists to track the changed breakpoints: + // commonAttrsList - attributes which have not changed + // oldAttrsList - attributes for the breakpoint before the change + // newAttrsList - attributes for the breakpoint after the change + // oldBpContexts - target-side breakpoints from before the change + // newBpContexts - target-side breakpoints after the change + // attrDeltasList - changes in the attributes for each attribute map in + // oldAttrsList and newAttrsList + + // Get the maps + final Map<IBreakpoint, List<Map<String, Object>>> platformBPs = fPlatformBPs.get(context); + final Map<IBreakpoint, List<IBreakpointDMContext>> breakpointIDs = fBreakpointDMContexts.get(context); + if (platformBPs == null || breakpointIDs == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Get the original breakpoint attributes + final List<Map<String, Object>> oldAttrsList0 = platformBPs.get(breakpoint); + if (oldAttrsList0 == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid breakpoint", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + // Get the list of corresponding back-end breakpoints + final List<IBreakpointDMContext> oldBpContexts = new ArrayList<IBreakpointDMContext>( + breakpointIDs.get(breakpoint)); + + // Calculate the list of attributes maps that have not changed. + // Immediately add these to the list of new breakpoint contexts, + // and remove them from further breakpoint attribute comparisons. + final List<Map<String, Object>> commonAttrsList = getCommonAttributeMaps(newAttrsList0, oldAttrsList0); + final List<IBreakpointDMContext> newBpContexts = new ArrayList<IBreakpointDMContext>(commonAttrsList.size()); + + final List<Map<String, Object>> newAttrsList = new ArrayList<Map<String, Object>>(newAttrsList0); + newAttrsList.removeAll(commonAttrsList); + + List<Map<String, Object>> oldAttrsList = new ArrayList<Map<String, Object>>(oldAttrsList0); + for (int i = 0; i < oldAttrsList.size(); i++) { + if (commonAttrsList.contains(oldAttrsList.get(i))) { + if (oldBpContexts.size() > i) { + newBpContexts.add(oldBpContexts.remove(i)); + } + } + } + oldAttrsList.removeAll(commonAttrsList); + + // Create a list of attribute changes. The length of this list will + // always be max(oldAttrList.size(), newAttrsList.size()), padded with + // null's if oldAttrsList was longer. + final List<Map<String, Object>> attrDeltasList = getAttributesDeltas(oldAttrsList, newAttrsList); + + // Create the request monitor that will be called when all + // modifying/inserting/removing is complete. + final CountingRequestMonitor countingRM = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + // Save the new list of breakpoint contexts and attributes + breakpointIDs.put(breakpoint, newBpContexts); + newAttrsList.addAll(commonAttrsList); + platformBPs.put(breakpoint, newAttrsList); + + // Update breakpoint status. updateBreakpointStatus() cannot + // be called on the executor thread, so we need to + // use a Job. + new Job("Breakpoint status update") { //$NON-NLS-1$ + { + setSystem(true); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + fAttributeTranslator.updateBreakpointStatus(breakpoint); + return Status.OK_STATUS; + }; + }.schedule(); + + super.handleCompleted(); + } + }; + + // Set the count, if could be zero if no breakpoints have actually changed. + countingRM.setDoneCount(attrDeltasList.size()); + + // Process the changed breakpoints. + for (int i = 0; i < attrDeltasList.size(); i++) { + if (attrDeltasList.get(i) == null) { + // The list of new attribute maps was shorter than the old. + // Remove the corresponding target-side bp. + fBreakpoints.removeBreakpoint(oldBpContexts.get(i), countingRM); + } else if (i >= oldBpContexts.size()) { + // The list of new attribute maps was longer, just insert + // the new breakpoint + final Map<String, Object> attrs = newAttrsList.get(i); + fBreakpoints.insertBreakpoint(context, attrs, + new DataRequestMonitor<IBreakpointDMContext>(getExecutor(), countingRM) { + @Override + protected void handleSuccess() { + newBpContexts.add(getData()); + countingRM.done(); + } + }); + } else if (!fAttributeTranslator.canUpdateAttributes(oldBpContexts.get(i), attrDeltasList.get(i))) { + // The attribute translator tells us that the debugger cannot modify the + // breakpoint to change the given attributes. Remove the breakpoint + // and insert a new one. + final Map<String, Object> attrs = newAttrsList.get(i); + fBreakpoints.removeBreakpoint(oldBpContexts.get(i), new RequestMonitor(getExecutor(), countingRM) { + @Override + protected void handleCompleted() { + fBreakpoints.insertBreakpoint(context, attrs, + new DataRequestMonitor<IBreakpointDMContext>(getExecutor(), countingRM) { + @Override + protected void handleCompleted() { + if (isSuccess()) { + newBpContexts.add(getData()); + } else { + // TODO (bug 219841): need to add breakpoint error status tracking + // in addition to fBreakpointDMContexts. + } + countingRM.done(); + } + }); + } + }); + } else { + // The back end can modify the breakpoint. Update the breakpoint with the + // new attributes. + final IBreakpointDMContext bpCtx = oldBpContexts.get(i); + fBreakpoints.updateBreakpoint(oldBpContexts.get(i), newAttrsList.get(i), + new RequestMonitor(getExecutor(), countingRM) { + @Override + protected void handleSuccess() { + newBpContexts.add(bpCtx); + countingRM.done(); + } + }); + } + } + } + + private List<Map<String, Object>> getCommonAttributeMaps(List<Map<String, Object>> array1, + List<Map<String, Object>> array2) { + List<Map<String, Object>> intersection = new LinkedList<Map<String, Object>>(); + List<Map<String, Object>> list2 = new ArrayList<Map<String, Object>>(array2); + for (Map<String, Object> array1Map : array1) { + if (list2.remove(array1Map)) { + intersection.add(array1Map); + } + } + return intersection; } - + /** * Determine the set of modified attributes - * + * * @param oldAttributes * @param newAttributes * @return */ - private List<Map<String, Object>> getAttributesDeltas(List<Map<String, Object>> oldAttributesList, List<Map<String, Object>> newAttributesList) { - List<Map<String, Object>> deltas = new ArrayList<Map<String, Object>>(oldAttributesList.size()); - - // Go through the bp attributes common to the old and the new lists and calculate - // their deltas. - for (int i = 0; i < oldAttributesList.size() && i < newAttributesList.size(); i++) { - Map<String, Object> oldAttributes = oldAttributesList.get(i); - Map<String, Object> newAttributes = newAttributesList.get(i); - - Map<String, Object> delta = new HashMap<String, Object>(); - - Set<String> oldKeySet = oldAttributes.keySet(); - Set<String> newKeySet = newAttributes.keySet(); - - Set<String> commonKeys = new HashSet<String>(newKeySet); commonKeys.retainAll(oldKeySet); - Set<String> addedKeys = new HashSet<String>(newKeySet); addedKeys.removeAll(oldKeySet); - Set<String> removedKeys = new HashSet<String>(oldKeySet); removedKeys.removeAll(newKeySet); - - // Add the modified attributes - for (String key : commonKeys) { - if (!(oldAttributes.get(key).equals(newAttributes.get(key)))) - delta.put(key, newAttributes.get(key)); - } - - // Add the new attributes - for (String key : addedKeys) { - delta.put(key, newAttributes.get(key)); - } - - // Remove the deleted attributes - for (String key : removedKeys) { - delta.put(key, null); - } - deltas.add(delta); - } - - // Add all the new attributes as deltas - for (int i = deltas.size(); i < newAttributesList.size(); i++) { - deltas.add(newAttributesList.get(i)); - } - - // For any old attribute Maps that were removed, insert a null value in the deltas list. - for (int i = deltas.size(); i < oldAttributesList.size(); i++) { - deltas.add(null); - } - - return deltas; + private List<Map<String, Object>> getAttributesDeltas(List<Map<String, Object>> oldAttributesList, + List<Map<String, Object>> newAttributesList) { + List<Map<String, Object>> deltas = new ArrayList<Map<String, Object>>(oldAttributesList.size()); + + // Go through the bp attributes common to the old and the new lists and calculate + // their deltas. + for (int i = 0; i < oldAttributesList.size() && i < newAttributesList.size(); i++) { + Map<String, Object> oldAttributes = oldAttributesList.get(i); + Map<String, Object> newAttributes = newAttributesList.get(i); + + Map<String, Object> delta = new HashMap<String, Object>(); + + Set<String> oldKeySet = oldAttributes.keySet(); + Set<String> newKeySet = newAttributes.keySet(); + + Set<String> commonKeys = new HashSet<String>(newKeySet); + commonKeys.retainAll(oldKeySet); + Set<String> addedKeys = new HashSet<String>(newKeySet); + addedKeys.removeAll(oldKeySet); + Set<String> removedKeys = new HashSet<String>(oldKeySet); + removedKeys.removeAll(newKeySet); + + // Add the modified attributes + for (String key : commonKeys) { + if (!(oldAttributes.get(key).equals(newAttributes.get(key)))) + delta.put(key, newAttributes.get(key)); + } + + // Add the new attributes + for (String key : addedKeys) { + delta.put(key, newAttributes.get(key)); + } + + // Remove the deleted attributes + for (String key : removedKeys) { + delta.put(key, null); + } + deltas.add(delta); + } + + // Add all the new attributes as deltas + for (int i = deltas.size(); i < newAttributesList.size(); i++) { + deltas.add(newAttributesList.get(i)); + } + + // For any old attribute Maps that were removed, insert a null value in the deltas list. + for (int i = deltas.size(); i < oldAttributesList.size(); i++) { + deltas.add(null); + } + + return deltas; } - /////////////////////////////////////////////////////////////////////////// - // IBreakpointManagerListener implementation - /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + // IBreakpointManagerListener implementation + /////////////////////////////////////////////////////////////////////////// - @Override + @Override public void breakpointManagerEnablementChanged(boolean enabled) { for (IBreakpoint breakpoint : fBreakpointManager.getBreakpoints()) { - breakpointChanged(breakpoint, null); + breakpointChanged(breakpoint, null); } } @ThreadSafe - @Override + @Override public void breakpointAdded(final IBreakpoint breakpoint) { if (fAttributeTranslator.supportsBreakpoint(breakpoint)) { try { - // Retrieve the breakpoint attributes - final List<Map<String, Object>> attrsArray = - fAttributeTranslator.getBreakpointAttributes(breakpoint, fBreakpointManager.isEnabled()); + // Retrieve the breakpoint attributes + final List<Map<String, Object>> attrsArray = fAttributeTranslator.getBreakpointAttributes(breakpoint, + fBreakpointManager.isEnabled()); - getExecutor().execute(new DsfRunnable() { - @Override + getExecutor().execute(new DsfRunnable() { + @Override public void run() { - //TODO pp: need to track pending requests - + //TODO pp: need to track pending requests + final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), null) { @Override protected void handleError() { @@ -786,121 +792,126 @@ public class BreakpointsMediator extends AbstractDsfService implements IBreakpoi // Install the breakpoint in all the execution contexts for (final IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) { - installBreakpoint(dmc, breakpoint, attrsArray, new RequestMonitor(getExecutor(), countingRm)); + installBreakpoint(dmc, breakpoint, attrsArray, + new RequestMonitor(getExecutor(), countingRm)); } } }); } catch (CoreException e) { - DsfPlugin.getDefault().getLog().log(e.getStatus()); + DsfPlugin.getDefault().getLog().log(e.getStatus()); } catch (RejectedExecutionException e) { } } } - - /////////////////////////////////////////////////////////////////////////// - // IBreakpointListener implementation - /////////////////////////////////////////////////////////////////////////// - @Override + /////////////////////////////////////////////////////////////////////////// + // IBreakpointListener implementation + /////////////////////////////////////////////////////////////////////////// + + @Override public void breakpointChanged(final IBreakpoint breakpoint, final IMarkerDelta delta) { if (fAttributeTranslator.supportsBreakpoint(breakpoint)) { try { - // Retrieve the breakpoint attributes - final List<Map<String, Object>> attrsArray = - fAttributeTranslator.getBreakpointAttributes(breakpoint, fBreakpointManager.isEnabled()); + // Retrieve the breakpoint attributes + final List<Map<String, Object>> attrsArray = fAttributeTranslator.getBreakpointAttributes(breakpoint, + fBreakpointManager.isEnabled()); // Modify the breakpoint in all the target contexts - getExecutor().execute( new DsfRunnable() { - @Override - public void run() { + getExecutor().execute(new DsfRunnable() { + @Override + public void run() { - // If the breakpoint is currently being updated, queue the request and exit - if (fPendingRequests.contains(breakpoint)) { - fPendingBreakpoints.add(breakpoint); + // If the breakpoint is currently being updated, queue the request and exit + if (fPendingRequests.contains(breakpoint)) { + fPendingBreakpoints.add(breakpoint); return; - } - - // Keep track of the updates - final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), null) { - @Override - protected void handleCompleted() { - - if (!isSuccess()) { - if (getStatus().getSeverity() == IStatus.ERROR) { - DsfPlugin.getDefault().getLog().log(getStatus()); - } - } - - // Indicate that the pending request has completed - fPendingRequests.remove(breakpoint); - - // Process the next pending update for this breakpoint - if (fPendingBreakpoints.contains(breakpoint)) { - fPendingBreakpoints.remove(breakpoint); - new Job("Deferred breakpoint changed job") { //$NON-NLS-1$ - { setSystem(true); } - @Override - protected IStatus run(IProgressMonitor monitor) { - breakpointChanged(breakpoint, delta); - return Status.OK_STATUS; - }; - }.schedule(); - } - } - }; - countingRm.setDoneCount(fPlatformBPs.size()); - - // Mark the breakpoint as being updated and go - fPendingRequests.add(breakpoint); - - // Modify the breakpoint in all the execution contexts - for (final IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) { - modifyBreakpoint(dmc, breakpoint, attrsArray, delta, new RequestMonitor(getExecutor(), countingRm)); - } - } - }); - } catch (CoreException e) { - DsfPlugin.getDefault().getLog().log(e.getStatus()); - } catch (RejectedExecutionException e) { - } + } + + // Keep track of the updates + final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + + if (!isSuccess()) { + if (getStatus().getSeverity() == IStatus.ERROR) { + DsfPlugin.getDefault().getLog().log(getStatus()); + } + } + + // Indicate that the pending request has completed + fPendingRequests.remove(breakpoint); + + // Process the next pending update for this breakpoint + if (fPendingBreakpoints.contains(breakpoint)) { + fPendingBreakpoints.remove(breakpoint); + new Job("Deferred breakpoint changed job") { //$NON-NLS-1$ + { + setSystem(true); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + breakpointChanged(breakpoint, delta); + return Status.OK_STATUS; + }; + }.schedule(); + } + } + }; + countingRm.setDoneCount(fPlatformBPs.size()); + + // Mark the breakpoint as being updated and go + fPendingRequests.add(breakpoint); + + // Modify the breakpoint in all the execution contexts + for (final IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) { + modifyBreakpoint(dmc, breakpoint, attrsArray, delta, + new RequestMonitor(getExecutor(), countingRm)); + } + } + }); + } catch (CoreException e) { + DsfPlugin.getDefault().getLog().log(e.getStatus()); + } catch (RejectedExecutionException e) { + } } } - @Override + @Override public void breakpointRemoved(final IBreakpoint breakpoint, IMarkerDelta delta) { - if (fAttributeTranslator.supportsBreakpoint(breakpoint)) { - try { - getExecutor().execute(new DsfRunnable() { - @Override - public void run() { - //TODO pp: need to track pending requests - - CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), null) { - @Override - protected void handleError() { - if (getStatus().getSeverity() == IStatus.ERROR) { - DsfPlugin.getDefault().getLog().log(getStatus()); - } - } - }; - countingRm.setDoneCount(fPlatformBPs.size()); - - // Remove the breakpoint in all the execution contexts - for (IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) { - if (fPlatformBPs.get(dmc).remove(breakpoint) != null) { - uninstallBreakpoint(dmc, breakpoint, countingRm); - } else { - // Breakpoint not installed for given context, do nothing. - } - } - } - }); - } catch (RejectedExecutionException e) { - } - } - + if (fAttributeTranslator.supportsBreakpoint(breakpoint)) { + try { + getExecutor().execute(new DsfRunnable() { + @Override + public void run() { + //TODO pp: need to track pending requests + + CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), null) { + @Override + protected void handleError() { + if (getStatus().getSeverity() == IStatus.ERROR) { + DsfPlugin.getDefault().getLog().log(getStatus()); + } + } + }; + countingRm.setDoneCount(fPlatformBPs.size()); + + // Remove the breakpoint in all the execution contexts + for (IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) { + if (fPlatformBPs.get(dmc).remove(breakpoint) != null) { + uninstallBreakpoint(dmc, breakpoint, countingRm); + } else { + // Breakpoint not installed for given context, do nothing. + } + } + } + }); + } catch (RejectedExecutionException e) { + } + } + } } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/BreakpointsMediator2.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/BreakpointsMediator2.java index 189b2ae2a44..3cc49fe4c85 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/BreakpointsMediator2.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/BreakpointsMediator2.java @@ -54,98 +54,99 @@ import org.osgi.framework.BundleContext; /** /** - * Breakpoints mediator is a DSF service which synchronizes breakpoints in the - * IDE and breakpoints in the debugger. The IDE breakpoints are managed by the - * {@link IBreakpointManager} while the debugger breakpoints are accessed + * Breakpoints mediator is a DSF service which synchronizes breakpoints in the + * IDE and breakpoints in the debugger. The IDE breakpoints are managed by the + * {@link IBreakpointManager} while the debugger breakpoints are accessed * through the {@link IBreakpoints} service. * <p> * This class is not intended to be extended by clients. Instead clients should * implement the {@link IBreakpointAttributeTranslator2} interface which is used * to translate breakpoint attributes between the IDE and debugger breakpoints. * <p> - * Note: This breakpoint mediator is a second generation implementation that - * succeeds {@link BreakpointsMediator}. This new implementation includes + * Note: This breakpoint mediator is a second generation implementation that + * succeeds {@link BreakpointsMediator}. This new implementation includes * the following additional features: * <ul> * <li> support for multiple target breakpoints for each IDE breakpoint, </li> - * <li> support for retrieving the mapping between IDE breakpoints and + * <li> support for retrieving the mapping between IDE breakpoints and * debugger breakpoints,</li> * <li> support for updating IDE breakpoint status based on full target * breakpoint data. </li> * </ul> - * + * * @see IBreakpointAttributeTranslator2 * @see BreakpointsMediator - * + * * @since 2.1 */ -public class BreakpointsMediator2 extends AbstractDsfService implements IBreakpointsListener -{ - public enum BreakpointEventType {ADDED, REMOVED, MODIFIED}; - - /** - * The attribute translator that this service will use to map the platform - * breakpoint attributes to the corresponding target attributes, and vice - * versa. - */ - private IBreakpointAttributeTranslator2 fAttributeTranslator2; - - /** - * DSF Debug service for creating breakpoints. - */ - IBreakpoints fBreakpointsService; - - /** - * Platform breakpoint manager - */ - IBreakpointManager fBreakpointManager; - - /** - * Object describing the information about a single target breakpoint - * corresponding to specific platform breakpoint and breakpoint target - * context. - */ - public interface ITargetBreakpointInfo { - - /** - * Returns the breakpoint attributes as returned by the attribute translator. - */ - public Map<String, Object> getAttributes(); - - /** - * Returns the target breakpoint context. Returns <code>null</code> if the - * breakpoint failed to install on target. - */ - public IBreakpointDMContext getTargetBreakpoint(); - - /** - * Returns the status result of the last breakpoint operation (install/remove). - */ - public IStatus getStatus(); - } - - private static class TargetBP implements ITargetBreakpointInfo { - - private Map<String, Object> fAttributes; - private IBreakpointDMContext fTargetBPContext; - private IStatus fStatus; - - public TargetBP(Map<String, Object> attrs) { - fAttributes = attrs; - } - - @Override - public Map<String, Object> getAttributes() { +public class BreakpointsMediator2 extends AbstractDsfService implements IBreakpointsListener { + public enum BreakpointEventType { + ADDED, REMOVED, MODIFIED + }; + + /** + * The attribute translator that this service will use to map the platform + * breakpoint attributes to the corresponding target attributes, and vice + * versa. + */ + private IBreakpointAttributeTranslator2 fAttributeTranslator2; + + /** + * DSF Debug service for creating breakpoints. + */ + IBreakpoints fBreakpointsService; + + /** + * Platform breakpoint manager + */ + IBreakpointManager fBreakpointManager; + + /** + * Object describing the information about a single target breakpoint + * corresponding to specific platform breakpoint and breakpoint target + * context. + */ + public interface ITargetBreakpointInfo { + + /** + * Returns the breakpoint attributes as returned by the attribute translator. + */ + public Map<String, Object> getAttributes(); + + /** + * Returns the target breakpoint context. Returns <code>null</code> if the + * breakpoint failed to install on target. + */ + public IBreakpointDMContext getTargetBreakpoint(); + + /** + * Returns the status result of the last breakpoint operation (install/remove). + */ + public IStatus getStatus(); + } + + private static class TargetBP implements ITargetBreakpointInfo { + + private Map<String, Object> fAttributes; + private IBreakpointDMContext fTargetBPContext; + private IStatus fStatus; + + public TargetBP(Map<String, Object> attrs) { + fAttributes = attrs; + } + + @Override + public Map<String, Object> getAttributes() { return fAttributes; } - - @Override - public IBreakpointDMContext getTargetBreakpoint() { + + @Override + public IBreakpointDMContext getTargetBreakpoint() { return fTargetBPContext; } - - @Override - public IStatus getStatus() { + + @Override + public IStatus getStatus() { return fStatus; } @@ -156,14 +157,14 @@ public class BreakpointsMediator2 extends AbstractDsfService implements IBreakpo public void setStatus(IStatus status) { this.fStatus = status; } - } - + } + private class PlatformBreakpointInfo { - IBreakpoint breakpoint; - boolean enabled; + IBreakpoint breakpoint; + boolean enabled; // All attributes available from UI, including standard and extended ones. - Map<String, Object> attributes; - + Map<String, Object> attributes; + public PlatformBreakpointInfo(IBreakpoint bp, boolean enabled, Map<String, Object> attributes) { super(); breakpoint = bp; @@ -173,27 +174,26 @@ public class BreakpointsMediator2 extends AbstractDsfService implements IBreakpo } /////////////////////////////////////////////////////////////////////////// - // Breakpoints tracking - /////////////////////////////////////////////////////////////////////////// - - /** - * Holds the set of platform breakpoints with their breakpoint information - * structures, per context (i.e. each platform breakpoint is - * replicated for each execution context). - * - Context entry added/removed on start/stopTrackingBreakpoints() - * - Augmented on breakpointAdded() - * - Modified on breakpointChanged() - * - Diminished on breakpointRemoved() - */ - private Map<IBreakpointsTargetDMContext, Map<IBreakpoint, List<ITargetBreakpointInfo>>> fPlatformBPs = - new HashMap<IBreakpointsTargetDMContext, Map<IBreakpoint, List<ITargetBreakpointInfo>>>(); + // Breakpoints tracking + /////////////////////////////////////////////////////////////////////////// + + /** + * Holds the set of platform breakpoints with their breakpoint information + * structures, per context (i.e. each platform breakpoint is + * replicated for each execution context). + * - Context entry added/removed on start/stopTrackingBreakpoints() + * - Augmented on breakpointAdded() + * - Modified on breakpointChanged() + * - Diminished on breakpointRemoved() + */ + private Map<IBreakpointsTargetDMContext, Map<IBreakpoint, List<ITargetBreakpointInfo>>> fPlatformBPs = new HashMap<IBreakpointsTargetDMContext, Map<IBreakpoint, List<ITargetBreakpointInfo>>>(); /** * BreakpointsTargetDMContext's that are being removed from {@link #fPlatformBPs}. * See where this is used for more. */ - private List<IBreakpointsTargetDMContext> fBPTargetDMCsBeingRemoved = new ArrayList<IBreakpoints.IBreakpointsTargetDMContext>(); - + private List<IBreakpointsTargetDMContext> fBPTargetDMCsBeingRemoved = new ArrayList<IBreakpoints.IBreakpointsTargetDMContext>(); + /** * Mapping of platform breakpoints to all their attributes (standard ones and * extended ones) from UI. This will be used to check what attributes have @@ -202,9 +202,8 @@ public class BreakpointsMediator2 extends AbstractDsfService implements IBreakpo * 2. updated in breakpointsChanged(); <br> * 3. diminished in breakpointsRemoved(); */ - private Map<IBreakpoint, Map<String, Object>> fBreakpointAttributes = - new HashMap<IBreakpoint, Map<String, Object>>(); - + private Map<IBreakpoint, Map<String, Object>> fBreakpointAttributes = new HashMap<IBreakpoint, Map<String, Object>>(); + /** * Hold info about a breakpoint events (added, removed, changed) for later * handling. @@ -218,7 +217,7 @@ public class BreakpointsMediator2 extends AbstractDsfService implements IBreakpo fRequestMonitor = rm; fAttributeDelta = null; } - + PendingEventInfo(BreakpointEventType eventType, Collection<IBreakpointsTargetDMContext> updateContexts, Map<String, Object> attrDelta) { fEventType = eventType; @@ -232,201 +231,205 @@ public class BreakpointsMediator2 extends AbstractDsfService implements IBreakpo RequestMonitor fRequestMonitor; BreakpointEventType fEventType; Collection<IBreakpointsTargetDMContext> fBPTargetContexts; - Map<String, Object> fAttributeDelta; // for change event only + Map<String, Object> fAttributeDelta; // for change event only } - - /** - * Due to the very asynchronous nature of DSF, a new breakpoint request can - * pop up at any time before an ongoing one is completed. The following set - * is used to store requests until the ongoing operation completes. - */ - private Set<IBreakpoint> fRunningEvents = new HashSet<IBreakpoint>(); - - private Map<IBreakpoint, LinkedList<PendingEventInfo>> fPendingEvents = - new HashMap<IBreakpoint, LinkedList<PendingEventInfo>>(); - - /////////////////////////////////////////////////////////////////////////// - // AbstractDsfService - /////////////////////////////////////////////////////////////////////////// + + /** + * Due to the very asynchronous nature of DSF, a new breakpoint request can + * pop up at any time before an ongoing one is completed. The following set + * is used to store requests until the ongoing operation completes. + */ + private Set<IBreakpoint> fRunningEvents = new HashSet<IBreakpoint>(); + + private Map<IBreakpoint, LinkedList<PendingEventInfo>> fPendingEvents = new HashMap<IBreakpoint, LinkedList<PendingEventInfo>>(); + + /////////////////////////////////////////////////////////////////////////// + // AbstractDsfService + /////////////////////////////////////////////////////////////////////////// /** * The service constructor - * + * * @param session * @param debugModelId */ public BreakpointsMediator2(DsfSession session, IBreakpointAttributeTranslator2 attributeTranslator) { - super(session); - fAttributeTranslator2 = attributeTranslator; + super(session); + fAttributeTranslator2 = attributeTranslator; + } + + @Override + public void initialize(final RequestMonitor rm) { + // - Collect references for the services we interact with + // - Register to interesting events + // - Obtain the list of platform breakpoints + // - Register the service for interested parties + super.initialize(new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + doInitialize(rm); + } + }); + } + + /** + * Asynchronous service initialization + * + * @param requestMonitor + */ + private void doInitialize(RequestMonitor rm) { + + // Get the services references + fBreakpointsService = getServicesTracker().getService(IBreakpoints.class); + fBreakpointManager = DebugPlugin.getDefault().getBreakpointManager(); + fAttributeTranslator2.initialize(this); + + // Register to the useful events + fBreakpointManager.addBreakpointListener(this); + + // Register this service + register(new String[] { BreakpointsMediator2.class.getName() }, new Hashtable<String, String>()); + + rm.done(); + } + + @Override + public void shutdown(final RequestMonitor rm) { + // - Un-register the service + // - Stop listening to events + // - Remove the breakpoints installed by this service + // + // Since we are shutting down, there is no overwhelming need + // to keep the maps coherent... + + // Stop accepting requests and events + unregister(); + fBreakpointManager.removeBreakpointListener(this); + fAttributeTranslator2.dispose(); + + // Cleanup the breakpoints that are still installed by the service. + // Use a counting monitor which will call mom to complete the shutdown + // after the breakpoints are un-installed (successfully or not). + CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + BreakpointsMediator2.super.shutdown(rm); + } + }; + + // We have to make a copy of the fPlatformBPs keys because uninstallBreakpoints() + // modifies the map as it walks through it. + List<IBreakpointsTargetDMContext> platformBPKeysCopy = new ArrayList<IBreakpointsTargetDMContext>( + fPlatformBPs.size()); + platformBPKeysCopy.addAll(0, fPlatformBPs.keySet()); + for (IBreakpointsTargetDMContext dmc : platformBPKeysCopy) { + stopTrackingBreakpoints(dmc, countingRm); + } + countingRm.setDoneCount(platformBPKeysCopy.size()); } - @Override - public void initialize(final RequestMonitor rm) { - // - Collect references for the services we interact with - // - Register to interesting events - // - Obtain the list of platform breakpoints - // - Register the service for interested parties - super.initialize( - new RequestMonitor(getExecutor(), rm) { - @Override - protected void handleSuccess() { - doInitialize(rm); - }}); - } - - /** - * Asynchronous service initialization - * - * @param requestMonitor - */ - private void doInitialize(RequestMonitor rm) { - - // Get the services references - fBreakpointsService = getServicesTracker().getService(IBreakpoints.class); - fBreakpointManager = DebugPlugin.getDefault().getBreakpointManager(); - fAttributeTranslator2.initialize(this); - - // Register to the useful events - fBreakpointManager.addBreakpointListener(this); - - // Register this service - register(new String[] { BreakpointsMediator2.class.getName() }, - new Hashtable<String, String>()); - - rm.done(); - } - - @Override - public void shutdown(final RequestMonitor rm) { - // - Un-register the service - // - Stop listening to events - // - Remove the breakpoints installed by this service - // - // Since we are shutting down, there is no overwhelming need - // to keep the maps coherent... - - // Stop accepting requests and events - unregister(); - fBreakpointManager.removeBreakpointListener(this); - fAttributeTranslator2.dispose(); - - // Cleanup the breakpoints that are still installed by the service. - // Use a counting monitor which will call mom to complete the shutdown - // after the breakpoints are un-installed (successfully or not). - CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) { - @Override - protected void handleCompleted() { - BreakpointsMediator2.super.shutdown(rm); - } - }; - - // We have to make a copy of the fPlatformBPs keys because uninstallBreakpoints() - // modifies the map as it walks through it. - List<IBreakpointsTargetDMContext> platformBPKeysCopy = new ArrayList<IBreakpointsTargetDMContext>(fPlatformBPs.size()); - platformBPKeysCopy.addAll(0, fPlatformBPs.keySet()); - for (IBreakpointsTargetDMContext dmc : platformBPKeysCopy) { - stopTrackingBreakpoints(dmc, countingRm); - } - countingRm.setDoneCount(platformBPKeysCopy.size()); - } - @Override - protected BundleContext getBundleContext() { - return DsfPlugin.getBundleContext(); - } + protected BundleContext getBundleContext() { + return DsfPlugin.getBundleContext(); + } - protected String getPluginID() { - return DsfPlugin.PLUGIN_ID; - } + protected String getPluginID() { + return DsfPlugin.PLUGIN_ID; + } - protected Plugin getPlugin() { - return DsfPlugin.getDefault(); - } + protected Plugin getPlugin() { + return DsfPlugin.getDefault(); + } /** - * Install and begin tracking breakpoints for given context. The service - * will keep installing new breakpoints that appear in the IDE for this - * context until {@link #stopTrackingBreakpoints} is called for that - * context. - * @param dmc Context to start tracking breakpoints for. - * @param rm Completion callback. - */ - public void startTrackingBreakpoints(final IBreakpointsTargetDMContext dmc, final RequestMonitor rm) { - // - Augment the maps with the new execution context - // - Install the platform breakpoints on the selected target - - // Make sure a mapping for this execution context does not already exist + * Install and begin tracking breakpoints for given context. The service + * will keep installing new breakpoints that appear in the IDE for this + * context until {@link #stopTrackingBreakpoints} is called for that + * context. + * @param dmc Context to start tracking breakpoints for. + * @param rm Completion callback. + */ + public void startTrackingBreakpoints(final IBreakpointsTargetDMContext dmc, final RequestMonitor rm) { + // - Augment the maps with the new execution context + // - Install the platform breakpoints on the selected target + + // Make sure a mapping for this execution context does not already exist Map<IBreakpoint, List<ITargetBreakpointInfo>> platformBPs = fPlatformBPs.get(dmc); if (platformBPs != null) { - rm.setStatus(new Status(IStatus.ERROR, getPluginID(), INTERNAL_ERROR, "Context already initialized", null)); //$NON-NLS-1$ - rm.done(); - return; + rm.setStatus(new Status(IStatus.ERROR, getPluginID(), INTERNAL_ERROR, "Context already initialized", null)); //$NON-NLS-1$ + rm.done(); + return; } - // Create entries in the breakpoint tables for the new context. These entries should only - // be removed when this service stops tracking breakpoints for the given context. - fPlatformBPs.put(dmc, new HashMap<IBreakpoint, List<ITargetBreakpointInfo>>()); + // Create entries in the breakpoint tables for the new context. These entries should only + // be removed when this service stops tracking breakpoints for the given context. + fPlatformBPs.put(dmc, new HashMap<IBreakpoint, List<ITargetBreakpointInfo>>()); - // Install the platform breakpoints (stored in fPlatformBPs) on the target. - // We need to use a background thread for this operation because we are + // Install the platform breakpoints (stored in fPlatformBPs) on the target. + // We need to use a background thread for this operation because we are // accessing the resources system to retrieve the breakpoint attributes. // Accessing the resources system potentially requires using global locks. - // Also we will be calling some IBreakpointAttributeTranslator2 methods - // that are prohibited from being called on the session executor thread. + // Also we will be calling some IBreakpointAttributeTranslator2 methods + // that are prohibited from being called on the session executor thread. new Job("Install initial breakpoint list.") { //$NON-NLS-1$ - { setSystem(true); } + { + setSystem(true); + } // Get the stored breakpoints from the platform BreakpointManager // and install them on the target - @Override - protected IStatus run(IProgressMonitor monitor) { - doBreakpointsAdded(DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(), dmc, rm); - return Status.OK_STATUS; - } - }.schedule(); - } - - /** - * Remove and stop installing breakpoints for the given breakpoints target context. - * @param dmc Context to stop tracking breakpoints for. - * @param rm Completion callback. - */ - public void stopTrackingBreakpoints(final IBreakpointsTargetDMContext dmc, final RequestMonitor rm) { - // - Remove the target breakpoints for the given DMC - // - Remove the given DMC from the internal maps. - // - Map<IBreakpoint, List<ITargetBreakpointInfo>> platformBPs = fPlatformBPs.get(dmc); - if (platformBPs == null) { - rm.setStatus(new Status(IStatus.INFO /* NOT error */, getPluginID(), INTERNAL_ERROR, "Breakpoints not installed for given context", null)); //$NON-NLS-1$ - rm.done(); - return; - } - - if (platformBPs.size() == 0) { - fPlatformBPs.remove(dmc); // dmc tracked but no bps installed for it. - rm.done(); - return; - } - - // The stopTrackingBreakpoints() may be called twice for the same DMC - // on debugger termination (one on process death and one on debugger shutdown). - // This is to prevent double killing. - if (fBPTargetDMCsBeingRemoved.contains(dmc)) { // "stop" is already underway - rm.done(); - return; - } - - fBPTargetDMCsBeingRemoved.add(dmc); - - // Just remove the IBreakpoints installed for the "dmc". - final IBreakpoint[] bps = platformBPs.keySet().toArray(new IBreakpoint[platformBPs.size()]); - + @Override + protected IStatus run(IProgressMonitor monitor) { + doBreakpointsAdded(DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(), dmc, rm); + return Status.OK_STATUS; + } + }.schedule(); + } + + /** + * Remove and stop installing breakpoints for the given breakpoints target context. + * @param dmc Context to stop tracking breakpoints for. + * @param rm Completion callback. + */ + public void stopTrackingBreakpoints(final IBreakpointsTargetDMContext dmc, final RequestMonitor rm) { + // - Remove the target breakpoints for the given DMC + // - Remove the given DMC from the internal maps. + // + Map<IBreakpoint, List<ITargetBreakpointInfo>> platformBPs = fPlatformBPs.get(dmc); + if (platformBPs == null) { + rm.setStatus(new Status(IStatus.INFO /* NOT error */, getPluginID(), INTERNAL_ERROR, + "Breakpoints not installed for given context", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + if (platformBPs.size() == 0) { + fPlatformBPs.remove(dmc); // dmc tracked but no bps installed for it. + rm.done(); + return; + } + + // The stopTrackingBreakpoints() may be called twice for the same DMC + // on debugger termination (one on process death and one on debugger shutdown). + // This is to prevent double killing. + if (fBPTargetDMCsBeingRemoved.contains(dmc)) { // "stop" is already underway + rm.done(); + return; + } + + fBPTargetDMCsBeingRemoved.add(dmc); + + // Just remove the IBreakpoints installed for the "dmc". + final IBreakpoint[] bps = platformBPs.keySet().toArray(new IBreakpoint[platformBPs.size()]); + new Job("Uninstall target breakpoints list.") { //$NON-NLS-1$ - { setSystem(true); } + { + setSystem(true); + } - @Override - protected IStatus run(IProgressMonitor monitor) { - doBreakpointsRemoved(bps, dmc, new RequestMonitor(getExecutor(), rm){ + @Override + protected IStatus run(IProgressMonitor monitor) { + doBreakpointsRemoved(bps, dmc, new RequestMonitor(getExecutor(), rm) { @Override protected void handleCompleted() { // Regardless of success or failure in removing the breakpoints, @@ -434,145 +437,142 @@ public class BreakpointsMediator2 extends AbstractDsfService implements IBreakpo // from the map. fPlatformBPs.remove(dmc); fBPTargetDMCsBeingRemoved.remove(dmc); - + super.handleCompleted(); - }}); - return Status.OK_STATUS; - } - }.schedule(); - } - - /** - * Find target breakpoints installed in the given context that are resolved - * from the given platform breakpoint. - * - * @param dmc - context - * @param platformBp - platform breakpoint - * @return array of target breakpoints. - */ - public ITargetBreakpointInfo[] getTargetBreakpoints(IBreakpointsTargetDMContext dmc, IBreakpoint platformBp) { - assert getExecutor().isInExecutorThread(); - - Map<IBreakpoint, List<ITargetBreakpointInfo>> platformBPs = fPlatformBPs.get(dmc); - - if (platformBPs != null) - { - List<ITargetBreakpointInfo> bpInfo = platformBPs.get(platformBp); - if (bpInfo != null) { - return bpInfo.toArray(new ITargetBreakpointInfo[bpInfo.size()]); - } - } - return null; - } - - /** - * Find the platform breakpoint that's mapped to the given target breakpoint. - * - * @param dmc - context of the target breakpoint, can be null. - * @param bp - target breakpoint - * @return platform breakpoint. null if not found. - */ - public IBreakpoint getPlatformBreakpoint(IBreakpointsTargetDMContext dmc, IBreakpointDMContext bp) { - assert getExecutor().isInExecutorThread(); - - for (IBreakpointsTargetDMContext bpContext : fPlatformBPs.keySet()) { - if (dmc != null && !dmc.equals(bpContext)) - continue; - - Map<IBreakpoint, List<ITargetBreakpointInfo>> platformBPs = fPlatformBPs.get(bpContext); - - if (platformBPs != null && !platformBPs.isEmpty()) - { - for(Map.Entry<IBreakpoint, List<ITargetBreakpointInfo>> e: platformBPs.entrySet()) - { - // Stop at the first occurrence - for (ITargetBreakpointInfo tbp : e.getValue()) { - IBreakpointDMContext targetBreakpoint = tbp.getTargetBreakpoint(); - if(targetBreakpoint != null && targetBreakpoint.equals(bp)) - return e.getKey(); - } - } - } - } - - return null; - } - - /////////////////////////////////////////////////////////////////////////// - // Back-end interface functions - /////////////////////////////////////////////////////////////////////////// + } + }); + return Status.OK_STATUS; + } + }.schedule(); + } + + /** + * Find target breakpoints installed in the given context that are resolved + * from the given platform breakpoint. + * + * @param dmc - context + * @param platformBp - platform breakpoint + * @return array of target breakpoints. + */ + public ITargetBreakpointInfo[] getTargetBreakpoints(IBreakpointsTargetDMContext dmc, IBreakpoint platformBp) { + assert getExecutor().isInExecutorThread(); + + Map<IBreakpoint, List<ITargetBreakpointInfo>> platformBPs = fPlatformBPs.get(dmc); + + if (platformBPs != null) { + List<ITargetBreakpointInfo> bpInfo = platformBPs.get(platformBp); + if (bpInfo != null) { + return bpInfo.toArray(new ITargetBreakpointInfo[bpInfo.size()]); + } + } + return null; + } + + /** + * Find the platform breakpoint that's mapped to the given target breakpoint. + * + * @param dmc - context of the target breakpoint, can be null. + * @param bp - target breakpoint + * @return platform breakpoint. null if not found. + */ + public IBreakpoint getPlatformBreakpoint(IBreakpointsTargetDMContext dmc, IBreakpointDMContext bp) { + assert getExecutor().isInExecutorThread(); + + for (IBreakpointsTargetDMContext bpContext : fPlatformBPs.keySet()) { + if (dmc != null && !dmc.equals(bpContext)) + continue; + + Map<IBreakpoint, List<ITargetBreakpointInfo>> platformBPs = fPlatformBPs.get(bpContext); + + if (platformBPs != null && !platformBPs.isEmpty()) { + for (Map.Entry<IBreakpoint, List<ITargetBreakpointInfo>> e : platformBPs.entrySet()) { + // Stop at the first occurrence + for (ITargetBreakpointInfo tbp : e.getValue()) { + IBreakpointDMContext targetBreakpoint = tbp.getTargetBreakpoint(); + if (targetBreakpoint != null && targetBreakpoint.equals(bp)) + return e.getKey(); + } + } + } + } + + return null; + } + + /////////////////////////////////////////////////////////////////////////// + // Back-end interface functions + /////////////////////////////////////////////////////////////////////////// /** * Install a new platform breakpoint on the back-end. A platform breakpoint * can resolve into multiple back-end breakpoints, e.g. when threads are taken * into account. - * + * * @param dmc * @param breakpoint * @param attrsList - list of attribute map, each mapping to a potential target BP. * @param rm */ private void installBreakpoint(IBreakpointsTargetDMContext dmc, final IBreakpoint breakpoint, - final List<Map<String, Object>> attrsList, final DataRequestMonitor<List<TargetBP>> rm) - { - // Retrieve the set of breakpoints for this context - final Map<IBreakpoint, List<ITargetBreakpointInfo>> platformBPs = fPlatformBPs.get(dmc); - assert platformBPs != null; - - // Ensure the breakpoint is not already installed - assert !platformBPs.containsKey(breakpoint); - - final ArrayList<TargetBP> targetBPsAttempted = new ArrayList<TargetBP>(attrsList.size()); - for (int i = 0; i < attrsList.size(); i++) { - targetBPsAttempted.add(new TargetBP(attrsList.get(i))); - } - - final ArrayList<ITargetBreakpointInfo> targetBPsInstalled = new ArrayList<ITargetBreakpointInfo>(attrsList.size()); - - // Update the breakpoint status when all back-end breakpoints have been installed - final CountingRequestMonitor installRM = new CountingRequestMonitor(getExecutor(), rm) { + final List<Map<String, Object>> attrsList, final DataRequestMonitor<List<TargetBP>> rm) { + // Retrieve the set of breakpoints for this context + final Map<IBreakpoint, List<ITargetBreakpointInfo>> platformBPs = fPlatformBPs.get(dmc); + assert platformBPs != null; + + // Ensure the breakpoint is not already installed + assert !platformBPs.containsKey(breakpoint); + + final ArrayList<TargetBP> targetBPsAttempted = new ArrayList<TargetBP>(attrsList.size()); + for (int i = 0; i < attrsList.size(); i++) { + targetBPsAttempted.add(new TargetBP(attrsList.get(i))); + } + + final ArrayList<ITargetBreakpointInfo> targetBPsInstalled = new ArrayList<ITargetBreakpointInfo>( + attrsList.size()); + + // Update the breakpoint status when all back-end breakpoints have been installed + final CountingRequestMonitor installRM = new CountingRequestMonitor(getExecutor(), rm) { @Override protected void handleCompleted() { // Store successful targetBPs with the platform breakpoint if (!targetBPsInstalled.isEmpty()) platformBPs.put(breakpoint, targetBPsInstalled); - + // Store all targetBPs, success or failure, in the rm. rm.setData(targetBPsAttempted); - rm.done(); + rm.done(); } }; - // A back-end breakpoint needs to be installed for each specified attributes map. + // A back-end breakpoint needs to be installed for each specified attributes map. installRM.setDoneCount(attrsList.size()); // Install the back-end breakpoint(s) for (int _i = 0; _i < attrsList.size(); _i++) { final int i = _i; - fBreakpointsService.insertBreakpoint( - dmc, attrsList.get(i), - new DataRequestMonitor<IBreakpointDMContext>(getExecutor(), installRM) { - @Override - protected void handleCompleted() { - TargetBP targetBP = targetBPsAttempted.get(i); - if (isSuccess()) { - // Add the breakpoint back-end mapping - targetBP.setTargetBreakpoint(getData()); - - targetBPsInstalled.add(targetBP); - } - targetBP.setStatus(getStatus()); - - installRM.done(); - } - }); + fBreakpointsService.insertBreakpoint(dmc, attrsList.get(i), + new DataRequestMonitor<IBreakpointDMContext>(getExecutor(), installRM) { + @Override + protected void handleCompleted() { + TargetBP targetBP = targetBPsAttempted.get(i); + if (isSuccess()) { + // Add the breakpoint back-end mapping + targetBP.setTargetBreakpoint(getData()); + + targetBPsInstalled.add(targetBP); + } + targetBP.setStatus(getStatus()); + + installRM.done(); + } + }); } } /** * Un-install an individual breakpoint on the back-end. For one platform * breakpoint, there could be multiple corresponding back-end breakpoints. - * + * * @param dmc * the context for which to remove the breakpoint. * @param breakpoint @@ -580,78 +580,77 @@ public class BreakpointsMediator2 extends AbstractDsfService implements IBreakpo * contains list of Target breakpoints that are removed * regardless of success or failure in the removal. */ - private void uninstallBreakpoint(final IBreakpointsTargetDMContext dmc, final IBreakpoint breakpoint, - final DataRequestMonitor<List<ITargetBreakpointInfo>> drm) - { + private void uninstallBreakpoint(final IBreakpointsTargetDMContext dmc, final IBreakpoint breakpoint, + final DataRequestMonitor<List<ITargetBreakpointInfo>> drm) { // Remove the back-end breakpoints final Map<IBreakpoint, List<ITargetBreakpointInfo>> platformBPs = fPlatformBPs.get(dmc); - if (platformBPs == null) { - drm.setStatus(new Status(IStatus.ERROR, getPluginID(), INVALID_HANDLE, "Invalid breakpoint", null)); //$NON-NLS-1$ - drm.done(); - return; - } - - final List<ITargetBreakpointInfo> bpList = platformBPs.get(breakpoint); - assert bpList != null; - - // Only try to remove those targetBPs that are successfully installed. - - // Remove completion monitor - final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), drm) { + if (platformBPs == null) { + drm.setStatus(new Status(IStatus.ERROR, getPluginID(), INVALID_HANDLE, "Invalid breakpoint", null)); //$NON-NLS-1$ + drm.done(); + return; + } + + final List<ITargetBreakpointInfo> bpList = platformBPs.get(breakpoint); + assert bpList != null; + + // Only try to remove those targetBPs that are successfully installed. + + // Remove completion monitor + final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), drm) { @Override protected void handleCompleted() { platformBPs.remove(breakpoint); - // Complete the request monitor. - drm.setData(bpList); - drm.done(); + // Complete the request monitor. + drm.setData(bpList); + drm.done(); } }; - int count = 0; - for (int i = 0; i < bpList.size(); i++) { - final ITargetBreakpointInfo bp = bpList.get(i); - if (bp.getTargetBreakpoint() != null) { - fBreakpointsService.removeBreakpoint( - bp.getTargetBreakpoint(), - new RequestMonitor(getExecutor(), countingRm) { - @Override - protected void handleCompleted() { - // Remember result of the removal, success or failure. - ((TargetBP)bp).setStatus(getStatus()); - if (isSuccess()) { - ((TargetBP)bp).setTargetBreakpoint(null); - } - countingRm.done(); - } - }); - count++; - } else { - ((TargetBP)bp).setStatus(Status.OK_STATUS); - } - } - countingRm.setDoneCount(count); - } - - /////////////////////////////////////////////////////////////////////////// - // IBreakpointManagerListener implementation - /////////////////////////////////////////////////////////////////////////// - - /** - * @noreference This method is not intended to be referenced by clients. - */ - @ThreadSafeAndProhibitedFromDsfExecutor("getExecutor()") - @Override + int count = 0; + for (int i = 0; i < bpList.size(); i++) { + final ITargetBreakpointInfo bp = bpList.get(i); + if (bp.getTargetBreakpoint() != null) { + fBreakpointsService.removeBreakpoint(bp.getTargetBreakpoint(), + new RequestMonitor(getExecutor(), countingRm) { + @Override + protected void handleCompleted() { + // Remember result of the removal, success or failure. + ((TargetBP) bp).setStatus(getStatus()); + if (isSuccess()) { + ((TargetBP) bp).setTargetBreakpoint(null); + } + countingRm.done(); + } + }); + count++; + } else { + ((TargetBP) bp).setStatus(Status.OK_STATUS); + } + } + countingRm.setDoneCount(count); + } + + /////////////////////////////////////////////////////////////////////////// + // IBreakpointManagerListener implementation + /////////////////////////////////////////////////////////////////////////// + + /** + * @noreference This method is not intended to be referenced by clients. + */ + @ThreadSafeAndProhibitedFromDsfExecutor("getExecutor()") + @Override public void breakpointsAdded(final IBreakpoint[] bps) { doBreakpointsAdded(bps, null, null); } - - protected void doBreakpointsAdded(final IBreakpoint[] bps, final IBreakpointsTargetDMContext bpsTargetDmc, final RequestMonitor rm) { + + protected void doBreakpointsAdded(final IBreakpoint[] bps, final IBreakpointsTargetDMContext bpsTargetDmc, + final RequestMonitor rm) { // Collect attributes (which will access system resource) // in non DSF dispatch thread. // final PlatformBreakpointInfo[] bpsInfo = collectBreakpointsInfo(bps); - + // Nothing to do if (bpsInfo.length == 0) { if (rm != null) { @@ -661,8 +660,8 @@ public class BreakpointsMediator2 extends AbstractDsfService implements IBreakpo } try { - getExecutor().execute(new DsfRunnable() { - @Override + getExecutor().execute(new DsfRunnable() { + @Override public void run() { Collection<IBreakpointsTargetDMContext> dmcs = new ArrayList<IBreakpointsTargetDMContext>(); if (bpsTargetDmc == null) @@ -674,162 +673,171 @@ public class BreakpointsMediator2 extends AbstractDsfService implements IBreakpo } }); } catch (RejectedExecutionException e) { - IStatus status = new Status(IStatus.ERROR, getPluginID(), IDsfStatusConstants.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in a rejected execution exception.", e);//$NON-NLS-1$ //$NON-NLS-2$ + IStatus status = new Status(IStatus.ERROR, getPluginID(), IDsfStatusConstants.INTERNAL_ERROR, + "Request for monitor: '" + toString() + "' resulted in a rejected execution exception.", e);//$NON-NLS-1$ //$NON-NLS-2$ if (rm != null) { rm.setStatus(status); rm.done(); } else { - getPlugin().getLog().log(status); + getPlugin().getLog().log(status); } } } - + /** * Collect breakpoint info. This method must not be called in DSF dispatch thread. * @param bps * @return */ - private PlatformBreakpointInfo[] collectBreakpointsInfo(IBreakpoint[] bps) { + private PlatformBreakpointInfo[] collectBreakpointsInfo(IBreakpoint[] bps) { List<PlatformBreakpointInfo> bpsInfo = new ArrayList<PlatformBreakpointInfo>(bps.length); - + for (IBreakpoint bp : bps) { if (bp.getMarker() == null) continue; - + if (fAttributeTranslator2.supportsBreakpoint(bp)) { try { - Map<String, Object> attrs = fAttributeTranslator2.getAllBreakpointAttributes(bp, fBreakpointManager.isEnabled()); - boolean enabled = bp.isEnabled() && fBreakpointManager.isEnabled(); + Map<String, Object> attrs = fAttributeTranslator2.getAllBreakpointAttributes(bp, + fBreakpointManager.isEnabled()); + boolean enabled = bp.isEnabled() && fBreakpointManager.isEnabled(); bpsInfo.add(new PlatformBreakpointInfo(bp, enabled, attrs)); } catch (CoreException e) { getPlugin().getLog().log(e.getStatus()); } } } - + return bpsInfo.toArray(new PlatformBreakpointInfo[bpsInfo.size()]); } - private void doBreakpointsAddedInExecutor(PlatformBreakpointInfo[] bpsInfo, Collection<IBreakpointsTargetDMContext> bpTargetDMCs, final RequestMonitor rm) { - final Map<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>> eventBPs = - new HashMap<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>>(bpsInfo.length, 1); - - CountingRequestMonitor processPendingCountingRm = new CountingRequestMonitor(getExecutor(), rm) { - @Override - protected void handleCompleted() { - processPendingRequests(); - for (Map.Entry<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>> eventEntry : eventBPs.entrySet()) { - for (Map.Entry<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]> bpEntry : eventEntry.getValue().entrySet()) { - fPlatformBPs.get(bpEntry.getKey()).put(eventEntry.getKey(), Arrays.asList( bpEntry.getValue() )); - } - } - fireUpdateBreakpointsStatus(eventBPs, BreakpointEventType.ADDED); - if (rm != null) - // don't call this if "rm" is null as this will - // log errors if any and pack Eclipse error - // log view with errors meaningless to user. - super.handleCompleted(); - } - }; - int processPendingCountingRmCount = 0; - - for (final PlatformBreakpointInfo bpinfo : bpsInfo) { - final Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]> targetBPs = - new HashMap<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>(fPlatformBPs.size(), 1); - eventBPs.put(bpinfo.breakpoint, targetBPs); - + private void doBreakpointsAddedInExecutor(PlatformBreakpointInfo[] bpsInfo, + Collection<IBreakpointsTargetDMContext> bpTargetDMCs, final RequestMonitor rm) { + final Map<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>> eventBPs = new HashMap<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>>( + bpsInfo.length, 1); + + CountingRequestMonitor processPendingCountingRm = new CountingRequestMonitor(getExecutor(), rm) { + @Override + protected void handleCompleted() { + processPendingRequests(); + for (Map.Entry<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>> eventEntry : eventBPs + .entrySet()) { + for (Map.Entry<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]> bpEntry : eventEntry.getValue() + .entrySet()) { + fPlatformBPs.get(bpEntry.getKey()).put(eventEntry.getKey(), Arrays.asList(bpEntry.getValue())); + } + } + fireUpdateBreakpointsStatus(eventBPs, BreakpointEventType.ADDED); + if (rm != null) + // don't call this if "rm" is null as this will + // log errors if any and pack Eclipse error + // log view with errors meaningless to user. + super.handleCompleted(); + } + }; + int processPendingCountingRmCount = 0; + + for (final PlatformBreakpointInfo bpinfo : bpsInfo) { + final Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]> targetBPs = new HashMap<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>( + fPlatformBPs.size(), 1); + eventBPs.put(bpinfo.breakpoint, targetBPs); + // Remember the new attributes of the bp in our global buffer, // even if we cannot or fail to install the bp. fBreakpointAttributes.put(bpinfo.breakpoint, bpinfo.attributes); - + if (fRunningEvents.contains(bpinfo.breakpoint)) { - PendingEventInfo pendingEvent = new PendingEventInfo(BreakpointEventType.ADDED, bpinfo, bpTargetDMCs, processPendingCountingRm); + PendingEventInfo pendingEvent = new PendingEventInfo(BreakpointEventType.ADDED, bpinfo, bpTargetDMCs, + processPendingCountingRm); processPendingCountingRmCount++; updatePendingRequest(bpinfo.breakpoint, pendingEvent); continue; } - + processPendingCountingRmCount++; - // Mark the breakpoint as being updated and go - fRunningEvents.add(bpinfo.breakpoint); + // Mark the breakpoint as being updated and go + fRunningEvents.add(bpinfo.breakpoint); - final CountingRequestMonitor bpTargetsCountingRm = new CountingRequestMonitor(getExecutor(), processPendingCountingRm) { + final CountingRequestMonitor bpTargetsCountingRm = new CountingRequestMonitor(getExecutor(), + processPendingCountingRm) { @Override protected void handleCompleted() { - // Indicate that the running event has completed - fRunningEvents.remove(bpinfo.breakpoint); - super.handleCompleted(); + // Indicate that the running event has completed + fRunningEvents.remove(bpinfo.breakpoint); + super.handleCompleted(); } - }; + }; int bpTargetsCountingRmCount = 0; // Install the breakpoint in all the execution contexts for (final IBreakpointsTargetDMContext dmc : bpTargetDMCs) { - - // Now ask lower level to set the bp. + + // Now ask lower level to set the bp. // // if the breakpoint is disabled, ask back-end if it can set (and manage) // disabled breakpoint. If not, just bail out. // - if (! bpinfo.enabled) { + if (!bpinfo.enabled) { Map<String, Object> attr = new HashMap<String, Object>(1); attr.put(IBreakpoint.ENABLED, Boolean.FALSE); Map<String, Object> targetEnablementAttr = fAttributeTranslator2.convertAttributes(attr); - if (! fAttributeTranslator2.canUpdateAttributes(bpinfo.breakpoint, dmc, targetEnablementAttr)) { + if (!fAttributeTranslator2.canUpdateAttributes(bpinfo.breakpoint, dmc, targetEnablementAttr)) { // bail out. Continue with the next dmc & breakpoint. continue; } } - + // Now do the real work. // fAttributeTranslator2.resolveBreakpoint(dmc, bpinfo.breakpoint, bpinfo.attributes, - new DataRequestMonitor<List<Map<String,Object>>>(getExecutor(), bpTargetsCountingRm){ + new DataRequestMonitor<List<Map<String, Object>>>(getExecutor(), bpTargetsCountingRm) { @Override protected void handleSuccess() { - installBreakpoint( - dmc, bpinfo.breakpoint, getData(), - new DataRequestMonitor<List<TargetBP>>(getExecutor(), bpTargetsCountingRm) { - @Override + installBreakpoint(dmc, bpinfo.breakpoint, getData(), + new DataRequestMonitor<List<TargetBP>>(getExecutor(), bpTargetsCountingRm) { + @Override protected void handleSuccess() { - targetBPs.put(dmc, getData().toArray(new ITargetBreakpointInfo[getData().size()])); - super.handleSuccess(); - }; - }); - }}); - + targetBPs.put(dmc, + getData().toArray(new ITargetBreakpointInfo[getData().size()])); + super.handleSuccess(); + }; + }); + } + }); + bpTargetsCountingRmCount++; } - + bpTargetsCountingRm.setDoneCount(bpTargetsCountingRmCount); - } - - processPendingCountingRm.setDoneCount(processPendingCountingRmCount); + } + + processPendingCountingRm.setDoneCount(processPendingCountingRmCount); } - /** - * @noreference This method is not intended to be referenced by clients. - */ + /** + * @noreference This method is not intended to be referenced by clients. + */ @ThreadSafeAndProhibitedFromDsfExecutor("getExecutor()") - @Override + @Override public void breakpointsChanged(IBreakpoint[] bps, IMarkerDelta[] deltas) { if (fAttributeTranslator2 == null) return; - + final PlatformBreakpointInfo[] bpsInfo = collectBreakpointsInfo(bps); - - if (bpsInfo.length == 0) + + if (bpsInfo.length == 0) return; // nothing to do - + try { - getExecutor().execute( new DsfRunnable() { - @Override - public void run() { - Map<String, Object> tmp = new HashMap<String, Object>(1); + getExecutor().execute(new DsfRunnable() { + @Override + public void run() { + Map<String, Object> tmp = new HashMap<String, Object>(1); tmp.put(IBreakpoint.ENABLED, true); - final String targetEnablementKey = fAttributeTranslator2.convertAttributes(tmp).keySet().iterator().next(); + final String targetEnablementKey = fAttributeTranslator2.convertAttributes(tmp).keySet().iterator() + .next(); for (PlatformBreakpointInfo bpinfo : bpsInfo) { /* @@ -840,74 +848,74 @@ public class BreakpointsMediator2 extends AbstractDsfService implements IBreakpo */ Map<String, Object> newAttrs = bpinfo.attributes; Map<String, Object> oldAttrs = fBreakpointAttributes.get(bpinfo.breakpoint); - + // remember the new attributes. fBreakpointAttributes.put(bpinfo.breakpoint, newAttrs); - + if (oldAttrs == null) continue; - + final Map<String, Object> attrDelta = getAttributesDelta(oldAttrs, newAttrs); - if (attrDelta.size() == 0) + if (attrDelta.size() == 0) continue; final List<IBreakpointsTargetDMContext> reinstallContexts = new ArrayList<IBreakpointsTargetDMContext>(); - + List<IBreakpointsTargetDMContext> updateContexts = new ArrayList<IBreakpointsTargetDMContext>(); - + // Now change the breakpoint for each known context. // for (final IBreakpointsTargetDMContext btContext : fPlatformBPs.keySet()) { - - if (! fAttributeTranslator2.canUpdateAttributes(bpinfo.breakpoint, btContext, attrDelta)) { + + if (!fAttributeTranslator2.canUpdateAttributes(bpinfo.breakpoint, btContext, attrDelta)) { // backend cannot handle at least one of the platform BP attribute change, // we'll re-install the bp. reinstallContexts.add(btContext); - } - else { + } else { // Backend claims it can handle the attributes change, let it do it. updateContexts.add(btContext); } - + } - final PlatformBreakpointInfo[] oneBPInfo = new PlatformBreakpointInfo[] {bpinfo}; - IBreakpoint[] oneBP = new IBreakpoint[] {bpinfo.breakpoint}; + final PlatformBreakpointInfo[] oneBPInfo = new PlatformBreakpointInfo[] { bpinfo }; + IBreakpoint[] oneBP = new IBreakpoint[] { bpinfo.breakpoint }; if (!reinstallContexts.isEmpty()) { - // Check if it's only enablement change (user click enable/disable + // Check if it's only enablement change (user click enable/disable // button or "Skip all breakpoints" button), which is common operation. // - if (attrDelta.size() == 1 && attrDelta.containsKey(targetEnablementKey)) { // only enablement changed. - if (bpinfo.enabled) { + if (attrDelta.size() == 1 && attrDelta.containsKey(targetEnablementKey)) { // only enablement changed. + if (bpinfo.enabled) { // change from disable to enable. Install the bp. doBreakpointsAddedInExecutor(oneBPInfo, reinstallContexts, null); - } - else { + } else { // change from enable to disable. Remove the bp. - doBreakpointsRemovedInExecutor(oneBP, reinstallContexts, null); + doBreakpointsRemovedInExecutor(oneBP, reinstallContexts, null); } - } - else { - doBreakpointsRemovedInExecutor(oneBP, reinstallContexts, new RequestMonitor(getExecutor(), null) { - // What should we do if removal of some or all targetBP fails ? - // Go on with the installation of new targetBPs and let clients (i.e. AttributeTranslators) - // handle the errors. - @Override - protected void handleCompleted() { - doBreakpointsAddedInExecutor(oneBPInfo, reinstallContexts, null); - }}); + } else { + doBreakpointsRemovedInExecutor(oneBP, reinstallContexts, + new RequestMonitor(getExecutor(), null) { + // What should we do if removal of some or all targetBP fails ? + // Go on with the installation of new targetBPs and let clients (i.e. AttributeTranslators) + // handle the errors. + @Override + protected void handleCompleted() { + doBreakpointsAddedInExecutor(oneBPInfo, reinstallContexts, null); + } + }); } } - + if (!updateContexts.isEmpty()) modifyTargetBreakpoints(bpinfo.breakpoint, updateContexts, attrDelta); - } - } - }); - } catch (RejectedExecutionException e) { - getPlugin().getLog().log(new Status(IStatus.ERROR, getPluginID(), IDsfStatusConstants.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in a rejected execution exception.", e)); //$NON-NLS-1$ //$NON-NLS-2$ - } + } + } + }); + } catch (RejectedExecutionException e) { + getPlugin().getLog().log(new Status(IStatus.ERROR, getPluginID(), IDsfStatusConstants.INTERNAL_ERROR, + "Request for monitor: '" + toString() + "' resulted in a rejected execution exception.", e)); //$NON-NLS-1$ //$NON-NLS-2$ + } } @@ -915,186 +923,193 @@ public class BreakpointsMediator2 extends AbstractDsfService implements IBreakpo * For the given platform BP, ask the backend to modify all its target BPs * with the given attribute change. <br> * This must be called in DSF executor thread. - * + * * @param bp - * @param updateContexts + * @param updateContexts * target contexts in which to do the modification. * @param targetAttrDelta * target-recognizable attribute(s) with new values. */ - private void modifyTargetBreakpoints(final IBreakpoint bp, Collection<IBreakpointsTargetDMContext> updateContexts, Map<String, Object> targetAttrDelta) { + private void modifyTargetBreakpoints(final IBreakpoint bp, Collection<IBreakpointsTargetDMContext> updateContexts, + Map<String, Object> targetAttrDelta) { // If the breakpoint is currently being updated, queue the request and exit - if (fRunningEvents.contains(bp)) { - PendingEventInfo pendingEvent = new PendingEventInfo(BreakpointEventType.MODIFIED, updateContexts, targetAttrDelta); - updatePendingRequest(bp, pendingEvent); + if (fRunningEvents.contains(bp)) { + PendingEventInfo pendingEvent = new PendingEventInfo(BreakpointEventType.MODIFIED, updateContexts, + targetAttrDelta); + updatePendingRequest(bp, pendingEvent); return; - } - - CountingRequestMonitor modifyTargetBPCRM = new CountingRequestMonitor(getExecutor(), null) { + } + + CountingRequestMonitor modifyTargetBPCRM = new CountingRequestMonitor(getExecutor(), null) { @Override protected void handleCompleted() { fRunningEvents.remove(bp); - }}; - - int targetBPCount = 0; - - fRunningEvents.add(bp); - + } + }; + + int targetBPCount = 0; + + fRunningEvents.add(bp); + for (IBreakpointsTargetDMContext context : updateContexts) { List<ITargetBreakpointInfo> targetBPs = fPlatformBPs.get(context).get(bp); if (targetBPs != null) { for (ITargetBreakpointInfo tbp : targetBPs) { // this must be an installed breakpoint. assert (tbp.getTargetBreakpoint() != null); - + targetBPCount++; fBreakpointsService.updateBreakpoint(tbp.getTargetBreakpoint(), targetAttrDelta, modifyTargetBPCRM); } } } - + modifyTargetBPCRM.setDoneCount(targetBPCount); } /** * @noreference This method is not intended to be referenced by clients. */ - @ThreadSafeAndProhibitedFromDsfExecutor("getExecutor()") - @Override + @ThreadSafeAndProhibitedFromDsfExecutor("getExecutor()") + @Override public void breakpointsRemoved(final IBreakpoint[] bps, IMarkerDelta delta[]) { getExecutor().execute(new DsfRunnable() { - @Override + @Override public void run() { for (IBreakpoint bp : bps) fBreakpointAttributes.remove(bp); } }); - + doBreakpointsRemoved(bps, null, null); } - - private void doBreakpointsRemoved(final IBreakpoint[] bps, final IBreakpointsTargetDMContext bpsTargetDmc, final RequestMonitor rm) { - + + private void doBreakpointsRemoved(final IBreakpoint[] bps, final IBreakpointsTargetDMContext bpsTargetDmc, + final RequestMonitor rm) { + final List<IBreakpoint> bpCandidates = new ArrayList<IBreakpoint>(); - + for (int i = 0; i < bps.length; i++) { IBreakpoint bp = bps[i]; - + if (fAttributeTranslator2.supportsBreakpoint(bp)) { bpCandidates.add(bp); } } - + if (bpCandidates.isEmpty()) { // nothing to do if (rm != null) rm.done(); return; } - + try { - getExecutor().execute(new DsfRunnable() { - @Override - public void run() { + getExecutor().execute(new DsfRunnable() { + @Override + public void run() { Collection<IBreakpointsTargetDMContext> contexts = new ArrayList<IBreakpointsTargetDMContext>(); if (bpsTargetDmc == null) contexts.addAll(fPlatformBPs.keySet()); else contexts.add(bpsTargetDmc); - doBreakpointsRemovedInExecutor(bpCandidates.toArray(new IBreakpoint[bpCandidates.size()]), contexts, rm); - } - }); - } catch (RejectedExecutionException e) { - IStatus status = new Status(IStatus.ERROR, getPluginID(), IDsfStatusConstants.INTERNAL_ERROR, + doBreakpointsRemovedInExecutor(bpCandidates.toArray(new IBreakpoint[bpCandidates.size()]), contexts, + rm); + } + }); + } catch (RejectedExecutionException e) { + IStatus status = new Status(IStatus.ERROR, getPluginID(), IDsfStatusConstants.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in a rejected execution exception.", e);//$NON-NLS-1$ //$NON-NLS-2$ if (rm != null) { rm.setStatus(status); rm.done(); } else { - getPlugin().getLog().log(status); + getPlugin().getLog().log(status); } - } + } } - - private void doBreakpointsRemovedInExecutor(IBreakpoint[] bpCandidates, + + private void doBreakpointsRemovedInExecutor(IBreakpoint[] bpCandidates, Collection<IBreakpointsTargetDMContext> targetContexts, final RequestMonitor rm) { - - final Map<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>> eventBPs = - new HashMap<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>>(bpCandidates.length, 1); + + final Map<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>> eventBPs = new HashMap<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>>( + bpCandidates.length, 1); CountingRequestMonitor processPendingCountingRm = new CountingRequestMonitor(getExecutor(), rm) { @Override protected void handleCompleted() { processPendingRequests(); - fireUpdateBreakpointsStatus(eventBPs, BreakpointEventType.REMOVED); - for (Map.Entry<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>> eventEntry : eventBPs.entrySet()) { - for (IBreakpointsTargetDMContext bpTarget : eventEntry.getValue().keySet()) { - fPlatformBPs.get(bpTarget).remove(eventEntry.getKey()); - } - } - if (rm != null) - // don't call this if "rm" is null as this will - // log errors if any and pack Eclipse error - // log view with errors meaningless to user. - super.handleCompleted(); + fireUpdateBreakpointsStatus(eventBPs, BreakpointEventType.REMOVED); + for (Map.Entry<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>> eventEntry : eventBPs + .entrySet()) { + for (IBreakpointsTargetDMContext bpTarget : eventEntry.getValue().keySet()) { + fPlatformBPs.get(bpTarget).remove(eventEntry.getKey()); + } + } + if (rm != null) + // don't call this if "rm" is null as this will + // log errors if any and pack Eclipse error + // log view with errors meaningless to user. + super.handleCompleted(); } }; int processPendingCountingRmCount = 0; - + for (final IBreakpoint breakpoint : bpCandidates) { // If the breakpoint is currently being updated, queue the request and exit - if (fRunningEvents.contains(breakpoint)) { - PendingEventInfo pendingEvent = new PendingEventInfo(BreakpointEventType.REMOVED, null, targetContexts, processPendingCountingRm); - processPendingCountingRmCount++; - updatePendingRequest(breakpoint, pendingEvent); - continue; // handle next breakpoint - } - - processPendingCountingRmCount++; - - final Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]> targetBPs = - new HashMap<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>(fPlatformBPs.size(), 1); - eventBPs.put(breakpoint, targetBPs); - - CountingRequestMonitor bpTargetsCountingRM = new CountingRequestMonitor(getExecutor(), processPendingCountingRm) { + if (fRunningEvents.contains(breakpoint)) { + PendingEventInfo pendingEvent = new PendingEventInfo(BreakpointEventType.REMOVED, null, targetContexts, + processPendingCountingRm); + processPendingCountingRmCount++; + updatePendingRequest(breakpoint, pendingEvent); + continue; // handle next breakpoint + } + + processPendingCountingRmCount++; + + final Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]> targetBPs = new HashMap<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>( + fPlatformBPs.size(), 1); + eventBPs.put(breakpoint, targetBPs); + + CountingRequestMonitor bpTargetsCountingRM = new CountingRequestMonitor(getExecutor(), + processPendingCountingRm) { @Override protected void handleCompleted() { // Indicate that the running event has completed - fRunningEvents.remove(breakpoint); - super.handleCompleted(); + fRunningEvents.remove(breakpoint); + super.handleCompleted(); } }; - + int bpTargetsCoutingRMCount = 0; - // Mark the breakpoint as being updated and go - fRunningEvents.add(breakpoint); - - // Remove the breakpoint in all the execution contexts - for (final IBreakpointsTargetDMContext dmc : targetContexts) { - - if (fPlatformBPs.get(dmc).containsKey(breakpoint)) { // there are targetBPs installed - // now do time-consuming part of the work. - - uninstallBreakpoint( - dmc, breakpoint, - new DataRequestMonitor<List<ITargetBreakpointInfo>>(getExecutor(), bpTargetsCountingRM) { - @Override + // Mark the breakpoint as being updated and go + fRunningEvents.add(breakpoint); + + // Remove the breakpoint in all the execution contexts + for (final IBreakpointsTargetDMContext dmc : targetContexts) { + + if (fPlatformBPs.get(dmc).containsKey(breakpoint)) { // there are targetBPs installed + // now do time-consuming part of the work. + + uninstallBreakpoint(dmc, breakpoint, + new DataRequestMonitor<List<ITargetBreakpointInfo>>(getExecutor(), bpTargetsCountingRM) { + @Override protected void handleSuccess() { - targetBPs.put(dmc, getData().toArray(new ITargetBreakpointInfo[getData().size()])); - super.handleSuccess(); - }; - }); - bpTargetsCoutingRMCount++; - } else { - // Breakpoint not installed for given context, do nothing. - } - } - - bpTargetsCountingRM.setDoneCount(bpTargetsCoutingRMCount); + targetBPs.put(dmc, getData().toArray(new ITargetBreakpointInfo[getData().size()])); + super.handleSuccess(); + }; + }); + bpTargetsCoutingRMCount++; + } else { + // Breakpoint not installed for given context, do nothing. + } + } + + bpTargetsCountingRM.setDoneCount(bpTargetsCoutingRMCount); } - + processPendingCountingRm.setDoneCount(processPendingCountingRmCount); } @@ -1104,96 +1119,107 @@ public class BreakpointsMediator2 extends AbstractDsfService implements IBreakpo pendingEventsList = new LinkedList<PendingEventInfo>(); fPendingEvents.put(breakpoint, pendingEventsList); } - if (!pendingEventsList.isEmpty() && - pendingEventsList.getLast().fEventType == BreakpointEventType.MODIFIED) { + if (!pendingEventsList.isEmpty() && pendingEventsList.getLast().fEventType == BreakpointEventType.MODIFIED) { pendingEventsList.removeLast(); } pendingEventsList.add(pendingEvent); } - + private void processPendingRequests() { /* * This will process only first pending request for each breakpoint, - * whose RequestMonitor (see "processPendingCountingRm" in such methods as - * doBreakpointsRemovedInExecutor()) will invoke this method again. + * whose RequestMonitor (see "processPendingCountingRm" in such methods as + * doBreakpointsRemovedInExecutor()) will invoke this method again. */ - if (fPendingEvents.isEmpty()) return; // Nothing to do - + if (fPendingEvents.isEmpty()) + return; // Nothing to do + // Make a copy to avoid ConcurrentModificationException // as we are deleting element in the loop. - Set<IBreakpoint> bpsInPendingEvents = new HashSet<IBreakpoint>(fPendingEvents.keySet()); + Set<IBreakpoint> bpsInPendingEvents = new HashSet<IBreakpoint>(fPendingEvents.keySet()); for (IBreakpoint bp : bpsInPendingEvents) { - if (! fRunningEvents.contains(bp)) { + if (!fRunningEvents.contains(bp)) { LinkedList<PendingEventInfo> eventInfoList = fPendingEvents.get(bp); - // Process the first pending request for this breakpoint - PendingEventInfo eventInfo = eventInfoList.removeFirst(); - + // Process the first pending request for this breakpoint + PendingEventInfo eventInfo = eventInfoList.removeFirst(); + if (eventInfoList.isEmpty()) fPendingEvents.remove(bp); - + switch (eventInfo.fEventType) { case ADDED: - doBreakpointsAddedInExecutor(new PlatformBreakpointInfo[] {eventInfo.fBPInfo}, eventInfo.fBPTargetContexts, eventInfo.fRequestMonitor); + doBreakpointsAddedInExecutor(new PlatformBreakpointInfo[] { eventInfo.fBPInfo }, + eventInfo.fBPTargetContexts, eventInfo.fRequestMonitor); break; case MODIFIED: modifyTargetBreakpoints(bp, eventInfo.fBPTargetContexts, eventInfo.fAttributeDelta); break; case REMOVED: - doBreakpointsRemovedInExecutor(new IBreakpoint[]{bp}, eventInfo.fBPTargetContexts, eventInfo.fRequestMonitor); + doBreakpointsRemovedInExecutor(new IBreakpoint[] { bp }, eventInfo.fBPTargetContexts, + eventInfo.fRequestMonitor); break; } - } + } } } - - private void fireUpdateBreakpointsStatus(final Map<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>> eventBPs, final BreakpointEventType eventType) { - // Update breakpoint status - new Job("Breakpoint status update") { //$NON-NLS-1$ - { setSystem(true); } - @Override - protected IStatus run(IProgressMonitor monitor) { - fAttributeTranslator2.updateBreakpointsStatus(eventBPs, eventType); - return Status.OK_STATUS; - }; - }.schedule(); - + + private void fireUpdateBreakpointsStatus( + final Map<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>> eventBPs, + final BreakpointEventType eventType) { + // Update breakpoint status + new Job("Breakpoint status update") { //$NON-NLS-1$ + { + setSystem(true); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + fAttributeTranslator2.updateBreakpointsStatus(eventBPs, eventType); + return Status.OK_STATUS; + }; + }.schedule(); + } - /** - * Determine the set of modified attributes. - * - * @param oldAttributes old map of attributes. - * @param newAttributes new map of attributes. - * @return new and changed attribute in the new map. May be empty indicating the two maps are equal. - */ - private Map<String, Object> getAttributesDelta(Map<String, Object> oldAttributes, Map<String, Object> newAttributes) { - - Map<String, Object> delta = new HashMap<String,Object>(); - - Set<String> oldKeySet = oldAttributes.keySet(); - Set<String> newKeySet = newAttributes.keySet(); - - Set<String> commonKeys = new HashSet<String>(newKeySet); commonKeys.retainAll(oldKeySet); - Set<String> addedKeys = new HashSet<String>(newKeySet); addedKeys.removeAll(oldKeySet); - Set<String> removedKeys = new HashSet<String>(oldKeySet); removedKeys.removeAll(newKeySet); - - // Add the modified attributes - for (String key : commonKeys) { - if (!(oldAttributes.get(key).equals(newAttributes.get(key)))) - delta.put(key, newAttributes.get(key)); - } - - // Add the new attributes - for (String key : addedKeys) { - delta.put(key, newAttributes.get(key)); - } - - // Remove the deleted attributes - for (String key : removedKeys) { - delta.put(key, null); - } - - return delta; - } + /** + * Determine the set of modified attributes. + * + * @param oldAttributes old map of attributes. + * @param newAttributes new map of attributes. + * @return new and changed attribute in the new map. May be empty indicating the two maps are equal. + */ + private Map<String, Object> getAttributesDelta(Map<String, Object> oldAttributes, + Map<String, Object> newAttributes) { + + Map<String, Object> delta = new HashMap<String, Object>(); + + Set<String> oldKeySet = oldAttributes.keySet(); + Set<String> newKeySet = newAttributes.keySet(); + + Set<String> commonKeys = new HashSet<String>(newKeySet); + commonKeys.retainAll(oldKeySet); + Set<String> addedKeys = new HashSet<String>(newKeySet); + addedKeys.removeAll(oldKeySet); + Set<String> removedKeys = new HashSet<String>(oldKeySet); + removedKeys.removeAll(newKeySet); + + // Add the modified attributes + for (String key : commonKeys) { + if (!(oldAttributes.get(key).equals(newAttributes.get(key)))) + delta.put(key, newAttributes.get(key)); + } + + // Add the new attributes + for (String key : addedKeys) { + delta.put(key, newAttributes.get(key)); + } + + // Remove the deleted attributes + for (String key : removedKeys) { + delta.put(key, null); + } + + return delta; + } } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IBreakpointAttributeTranslator.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IBreakpointAttributeTranslator.java index 37ef0a9bc0f..c43239d3597 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IBreakpointAttributeTranslator.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IBreakpointAttributeTranslator.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ @@ -23,55 +23,56 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.model.IBreakpoint; /** - * Breakpoint attribute translator is used by the {@link BreakpointsMediator} - * to map IDE breakpoint attributes to debugger breakpoint attributes. + * Breakpoint attribute translator is used by the {@link BreakpointsMediator} + * to map IDE breakpoint attributes to debugger breakpoint attributes. * <p> * Note: The attribute translator is expected to access IDE breakpoint manager - * objects which are synchronized using the resource system. Therefore all the + * objects which are synchronized using the resource system. Therefore all the * translator methods are called using background threads. When the attribute - * translator needs to access DSF services, it needs to schedule a runnable using + * translator needs to access DSF services, it needs to schedule a runnable using * the DSF session executable. - * + * * @see BreakpointMediator * @since 1.0 */ @ThreadSafeAndProhibitedFromDsfExecutor("") public interface IBreakpointAttributeTranslator { - - /** - * Initializes the translator. This method is called by the breakpoint - * mediator service, when the mediator service is initialized. - */ - @ConfinedToDsfExecutor("") - public void initialize(BreakpointsMediator mediator); - /** - * Disposes the translator. Also called by the mediator upon service - * shutdown. - */ - @ConfinedToDsfExecutor("") - public void dispose(); + /** + * Initializes the translator. This method is called by the breakpoint + * mediator service, when the mediator service is initialized. + */ + @ConfinedToDsfExecutor("") + public void initialize(BreakpointsMediator mediator); + + /** + * Disposes the translator. Also called by the mediator upon service + * shutdown. + */ + @ConfinedToDsfExecutor("") + public void dispose(); + + /** + * Returns whether the given IDE breakpoint is supported by this debugger. + */ + public boolean supportsBreakpoint(IBreakpoint bp); - /** - * Returns whether the given IDE breakpoint is supported by this debugger. - */ - public boolean supportsBreakpoint(IBreakpoint bp); + /** + * Returns the target breakpoint attributes for the given IDE breakpoint. + */ + public List<Map<String, Object>> getBreakpointAttributes(IBreakpoint breakpoint, boolean bpManagerEnabled) + throws CoreException; - /** - * Returns the target breakpoint attributes for the given IDE breakpoint. - */ - public List<Map<String, Object>> getBreakpointAttributes(IBreakpoint breakpoint, boolean bpManagerEnabled) throws CoreException; - - /** - * Based on the given change in IDE breakpoint attributes, this method returns - * whether the given target breakpoint can be modified using - * {@link IBreakpoints#updateBreakpoint(IBreakpointDMContext, Map, org.eclipse.cdt.dsf.concurrent.RequestMonitor)} - * method. - */ - public boolean canUpdateAttributes(IBreakpointDMContext bp, Map<String, Object> delta); + /** + * Based on the given change in IDE breakpoint attributes, this method returns + * whether the given target breakpoint can be modified using + * {@link IBreakpoints#updateBreakpoint(IBreakpointDMContext, Map, org.eclipse.cdt.dsf.concurrent.RequestMonitor)} + * method. + */ + public boolean canUpdateAttributes(IBreakpointDMContext bp, Map<String, Object> delta); - /** - * Notifies the translator to update the given IDE breakpoint's status. - */ - public void updateBreakpointStatus(IBreakpoint bp); + /** + * Notifies the translator to update the given IDE breakpoint's status. + */ + public void updateBreakpointStatus(IBreakpoint bp); }
\ No newline at end of file diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IBreakpointAttributeTranslator2.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IBreakpointAttributeTranslator2.java index 212ab8b8988..dcb8bfef01d 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IBreakpointAttributeTranslator2.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IBreakpointAttributeTranslator2.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation * Nokia - enhanced to work for both GDB and EDC. Nov. 2009. @@ -28,41 +28,41 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.model.IBreakpoint; /** - * Breakpoint attribute translator is used by the {@link BreakpointsMediator2} - * to map IDE breakpoint attributes to debugger breakpoint attributes. + * Breakpoint attribute translator is used by the {@link BreakpointsMediator2} + * to map IDE breakpoint attributes to debugger breakpoint attributes. * <p> * Note: The attribute translator is expected to access IDE breakpoint manager * objects which are synchronized using the resource system. It may also need to - * access DSF services using the DSF session executor. Therefore, the - * implementation needs to pay special attention to the synchronization + * access DSF services using the DSF session executor. Therefore, the + * implementation needs to pay special attention to the synchronization * annotations on each method of the interface. - * + * * @see BreakpointsMediator2 * @since 2.1 */ public interface IBreakpointAttributeTranslator2 { - /** - * Initializes the translator. This method is called by the breakpoint - * mediator service, when the mediator service is initialized. - */ - @ConfinedToDsfExecutor("") + /** + * Initializes the translator. This method is called by the breakpoint + * mediator service, when the mediator service is initialized. + */ + @ConfinedToDsfExecutor("") public void initialize(BreakpointsMediator2 mediator); - - /** - * Disposes the translator. Also called by the mediator upon service - * shutdown. - */ + + /** + * Disposes the translator. Also called by the mediator upon service + * shutdown. + */ @ConfinedToDsfExecutor("") - public void dispose(); - - /** - * Returns whether the given IDE breakpoint is supported by this debugger. - */ - @ThreadSafeAndProhibitedFromDsfExecutor("") - public boolean supportsBreakpoint(IBreakpoint bp); + public void dispose(); - /** + /** + * Returns whether the given IDE breakpoint is supported by this debugger. + */ + @ThreadSafeAndProhibitedFromDsfExecutor("") + public boolean supportsBreakpoint(IBreakpoint bp); + + /** * Resolve the breakpoint in given context. A platform BP may be mapped to * one or more target BPs, e.g. a breakpoint in an in-line function may be * mapped to several target BPs, or a thread-specific BP may be mapped to @@ -70,7 +70,7 @@ public interface IBreakpointAttributeTranslator2 { * the list of attribute maps each of which corresponds to one target BP. * <p> * This method is and must be called in DSF execution thread. - * + * * @param context * a IBreakpointsTargetDMContext object (which could be a * process or a loaded module) in which we locate target BPs for @@ -86,58 +86,61 @@ public interface IBreakpointAttributeTranslator2 { * corresponding to one target breakpoint. * @throws CoreException */ - @ConfinedToDsfExecutor("") - public void resolveBreakpoint(IBreakpointsTargetDMContext context, IBreakpoint breakpoint, - Map<String, Object> bpAttributes, DataRequestMonitor<List<Map<String, Object>>> drm); + @ConfinedToDsfExecutor("") + public void resolveBreakpoint(IBreakpointsTargetDMContext context, IBreakpoint breakpoint, + Map<String, Object> bpAttributes, DataRequestMonitor<List<Map<String, Object>>> drm); /** * Get all platform defined attributes for a breakpoint plus all attributes * defined by any breakpoint extension such as ICBreakpointExtension in CDT. - * In other words, get all attributes available from UI. + * In other words, get all attributes available from UI. * <p> * The attributes returned are independent of runtime context (process, * module, etc), whereas attributes from * {@link #resolveBreakpoint(IBreakpointsTargetDMContext, IBreakpoint, Map, DataRequestMonitor)} - * are context sensitive. + * are context sensitive. * <p> * Note this method must not be called in DSF dispatch thread because we are * accessing the resources system to retrieve the breakpoint attributes. * Accessing the resources system potentially requires using global locks. - * + * * @param platformBP * @param bpManagerEnabled * @return list of target (debugger implementation) recognizable attributes. * @throws CoreException */ - @ThreadSafeAndProhibitedFromDsfExecutor("") - public Map<String, Object> getAllBreakpointAttributes(IBreakpoint platformBP, boolean bpManagerEnabled) throws CoreException; + @ThreadSafeAndProhibitedFromDsfExecutor("") + public Map<String, Object> getAllBreakpointAttributes(IBreakpoint platformBP, boolean bpManagerEnabled) + throws CoreException; /** * Convert platform breakpoint attributes to target attributes. This usually * involves changing attributes keys to target recognizable ones. For - * instance, GDB integration has its own breakpoint attribute keys. + * instance, GDB integration has its own breakpoint attribute keys. * <p> - * This method overlaps somewhat with the {@link #resolveBreakpoint} - * method. However, this method is currently only used by the mediator in - * conjunction with the {@link #canUpdateAttributes} method. - * + * This method overlaps somewhat with the {@link #resolveBreakpoint} + * method. However, this method is currently only used by the mediator in + * conjunction with the {@link #canUpdateAttributes} method. + * * @param platformBPAttr * @return */ - @ThreadSafe - public Map<String, Object> convertAttributes(Map<String, Object> platformBPAttr); - - /** - * Update platform about breakpoint status change, e.g. breakpoint installed on target successfully or breakpoint - * removed from target successfully. - * <p> - * Note this method is not and must not be called in DSF dispatch thread. - * - * @param bpsInfo - * @param eventType - */ - @ThreadSafeAndProhibitedFromDsfExecutor("") - public void updateBreakpointsStatus(Map<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>> bpsInfo, BreakpointEventType eventType); + @ThreadSafe + public Map<String, Object> convertAttributes(Map<String, Object> platformBPAttr); + + /** + * Update platform about breakpoint status change, e.g. breakpoint installed on target successfully or breakpoint + * removed from target successfully. + * <p> + * Note this method is not and must not be called in DSF dispatch thread. + * + * @param bpsInfo + * @param eventType + */ + @ThreadSafeAndProhibitedFromDsfExecutor("") + public void updateBreakpointsStatus( + Map<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>> bpsInfo, + BreakpointEventType eventType); /** * This is enhanced version of @@ -146,12 +149,13 @@ public interface IBreakpointAttributeTranslator2 { * decision on a finer granularity when needed. * <p> * This will be called in DSF dispatch thread. - * + * * @param bp platform breakpoint. - * @param context + * @param context * @param attributes target-recognizable attributes. * @return false as long as one of the attributes cannot be updated by client, otherwise true. */ - @ConfinedToDsfExecutor("") - public boolean canUpdateAttributes(IBreakpoint bp, IBreakpointsTargetDMContext context, Map<String, Object> attributes); + @ConfinedToDsfExecutor("") + public boolean canUpdateAttributes(IBreakpoint bp, IBreakpointsTargetDMContext context, + Map<String, Object> attributes); }
\ No newline at end of file diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IBreakpoints.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IBreakpoints.java index 6289219358c..cf756562721 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IBreakpoints.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IBreakpoints.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation * Ericsson - Revisited the API @@ -27,120 +27,129 @@ import org.eclipse.cdt.dsf.service.IDsfService; /** * Breakpoint service interface - * + * * @since 1.0 */ public interface IBreakpoints extends IDsfService { + /** + * Marker interface for a context for which breakpoints can be installed + */ + public interface IBreakpointsTargetDMContext extends IDMContext { + } + + /** + * Specific breakpoint context + */ + @Immutable + public interface IBreakpointDMContext extends IDMContext { + } - /** - * Marker interface for a context for which breakpoints can be installed - */ - public interface IBreakpointsTargetDMContext extends IDMContext {} - - /** - * Specific breakpoint context - */ - @Immutable - public interface IBreakpointDMContext extends IDMContext {} - - /** + /** * Breakpoint events */ - public interface IBreakpointsChangedEvent extends IDMEvent<IBreakpointsTargetDMContext> { - public IBreakpointDMContext[] getBreakpoints(); - } - - public interface IBreakpointsAddedEvent extends IBreakpointsChangedEvent {} - public interface IBreakpointsUpdatedEvent extends IBreakpointsChangedEvent {} - public interface IBreakpointsRemovedEvent extends IBreakpointsChangedEvent {} - - /** - * Effective breakpoint data as held by the back-end. - */ - public interface IBreakpointDMData extends IDMData { - - public String getBreakpointType(); - public String getFileName(); - public int getLineNumber(); - public String getFunctionName(); - public IAddress[] getAddresses(); - public String getCondition(); - public int getIgnoreCount(); - public boolean isEnabled(); - public String getExpression(); - } - - /** - * Retrieves the list of breakpoints installed in the context. - * - * Use getBreakpointDMData() to retrieve individual breakpoints. - * - * @param context the execution context of the breakpoint - * @param drm the list of breakpoints in the execution context - */ - public void getBreakpoints(IBreakpointsTargetDMContext context, - DataRequestMonitor<IBreakpointDMContext[]> drm); + public interface IBreakpointsChangedEvent extends IDMEvent<IBreakpointsTargetDMContext> { + public IBreakpointDMContext[] getBreakpoints(); + } + + public interface IBreakpointsAddedEvent extends IBreakpointsChangedEvent { + } + + public interface IBreakpointsUpdatedEvent extends IBreakpointsChangedEvent { + } + + public interface IBreakpointsRemovedEvent extends IBreakpointsChangedEvent { + } + + /** + * Effective breakpoint data as held by the back-end. + */ + public interface IBreakpointDMData extends IDMData { + + public String getBreakpointType(); + + public String getFileName(); + + public int getLineNumber(); + + public String getFunctionName(); + + public IAddress[] getAddresses(); + + public String getCondition(); + + public int getIgnoreCount(); + + public boolean isEnabled(); + + public String getExpression(); + } + + /** + * Retrieves the list of breakpoints installed in the context. + * + * Use getBreakpointDMData() to retrieve individual breakpoints. + * + * @param context the execution context of the breakpoint + * @param drm the list of breakpoints in the execution context + */ + public void getBreakpoints(IBreakpointsTargetDMContext context, DataRequestMonitor<IBreakpointDMContext[]> drm); /** - * Retrieves a specific breakpoint from the service. - * - * @param dmc the breakpoint reference - * @param drm the DRM returning the breakpoint data - */ - public void getBreakpointDMData(IBreakpointDMContext dmc, - DataRequestMonitor<IBreakpointDMData> drm); + * Retrieves a specific breakpoint from the service. + * + * @param dmc the breakpoint reference + * @param drm the DRM returning the breakpoint data + */ + public void getBreakpointDMData(IBreakpointDMContext dmc, DataRequestMonitor<IBreakpointDMData> drm); /** - * Adds a breakpoint on the target. - * - * The breakpoint context is returned in the DRM. The actual breakpoint - * object can be later be retrieved using getBreakpoint(bp_context). - * - * E.g.: - * IBreakpointDMContext ref = insertBreakpoint(...); - * IBreakpointDMData bp = getBreakpointDMData(ref); - * - * If the breakpoint is a duplicate (already set previously), then it is up to - * the back-end to decide if it is an error or not. - * - * @param context the execution context of the breakpoint - * @param attributes the breakpoint attributes - * @param drm the DRM returning the breakpoint reference - */ - public void insertBreakpoint(IBreakpointsTargetDMContext context, - Map<String,Object> attributes, + * Adds a breakpoint on the target. + * + * The breakpoint context is returned in the DRM. The actual breakpoint + * object can be later be retrieved using getBreakpoint(bp_context). + * + * E.g.: + * IBreakpointDMContext ref = insertBreakpoint(...); + * IBreakpointDMData bp = getBreakpointDMData(ref); + * + * If the breakpoint is a duplicate (already set previously), then it is up to + * the back-end to decide if it is an error or not. + * + * @param context the execution context of the breakpoint + * @param attributes the breakpoint attributes + * @param drm the DRM returning the breakpoint reference + */ + public void insertBreakpoint(IBreakpointsTargetDMContext context, Map<String, Object> attributes, DataRequestMonitor<IBreakpointDMContext> drm); /** - * Removes the breakpoint on the target. - * - * If the breakpoint doesn't exist, silently ignore it. - * - * @param dmc the context of the breakpoints to remove - * @param rm the asynchronous request monitor - */ - public void removeBreakpoint(IBreakpointDMContext dmc, - RequestMonitor rm); + * Removes the breakpoint on the target. + * + * If the breakpoint doesn't exist, silently ignore it. + * + * @param dmc the context of the breakpoints to remove + * @param rm the asynchronous request monitor + */ + public void removeBreakpoint(IBreakpointDMContext dmc, RequestMonitor rm); /** - * Updates the breakpoint properties on the target. - * - * To add/update/remove a property, simply create a map with - * the desired value(s) for the given key(s). - * - * Properties that affect the breakpoint nature or location - * should not be updated. Instead, the breakpoint should be - * removed then re-inserted. - * - * A null value is used for removal of a property e.g.: - * delta.set(some_key, null); - * - * @param delta the delta properties - * @param dmc the context of the breakpoints to modify - * @param rm the asynchronous request monitor - */ - public void updateBreakpoint(IBreakpointDMContext dmc, - Map<String,Object> delta, RequestMonitor drm); + * Updates the breakpoint properties on the target. + * + * To add/update/remove a property, simply create a map with + * the desired value(s) for the given key(s). + * + * Properties that affect the breakpoint nature or location + * should not be updated. Instead, the breakpoint should be + * removed then re-inserted. + * + * A null value is used for removal of a property e.g.: + * delta.set(some_key, null); + * + * @param delta the delta properties + * @param dmc the context of the breakpoints to modify + * @param rm the asynchronous request monitor + */ + public void updateBreakpoint(IBreakpointDMContext dmc, Map<String, Object> delta, RequestMonitor drm); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IBreakpointsExtension.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IBreakpointsExtension.java index ec50bbca33c..80a02cc075c 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IBreakpointsExtension.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IBreakpointsExtension.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ @@ -18,35 +18,35 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent; /** - * Extension to the Breakpoints service which adds support for correlating + * Extension to the Breakpoints service which adds support for correlating * breakpoints and execution contexts. * @since 2.1 */ public interface IBreakpointsExtension extends IBreakpoints { - /** - * Event indicating that a given thread or container was suspended - * by the given breakpoint(s). - */ - public interface IBreakpointHitDMEvent extends ISuspendedDMEvent { - - /** - * Returns the breakpoints that suspended the thread. - */ - IBreakpointDMContext[] getBreakpoints(); - } + /** + * Event indicating that a given thread or container was suspended + * by the given breakpoint(s). + */ + public interface IBreakpointHitDMEvent extends ISuspendedDMEvent { + + /** + * Returns the breakpoints that suspended the thread. + */ + IBreakpointDMContext[] getBreakpoints(); + } - /** - * If a given execution context was suspended due to hitting a breakpoint, - * this method should return the breakpoints which caused the thread or - * container to suspend. - * <p> - * If the given thread is not suspended or is not suspended at a - * breakpoint, an empty array or an error with an INVALID_STATE code - * will be returned. - * - * @param ctx Thread or container to get breakpoints for. - * @param rm Breakpoints that the thread or container is suspended on. - */ - public void getExecutionContextBreakpoints(IExecutionDMContext ctx, DataRequestMonitor<IBreakpointDMContext[]> rm); + /** + * If a given execution context was suspended due to hitting a breakpoint, + * this method should return the breakpoints which caused the thread or + * container to suspend. + * <p> + * If the given thread is not suspended or is not suspended at a + * breakpoint, an empty array or an error with an INVALID_STATE code + * will be returned. + * + * @param ctx Thread or container to get breakpoints for. + * @param rm Breakpoints that the thread or container is suspended on. + */ + public void getExecutionContextBreakpoints(IExecutionDMContext ctx, DataRequestMonitor<IBreakpointDMContext[]> rm); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/ICachingService.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/ICachingService.java index f882d453587..634b6e1c6b2 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/ICachingService.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/ICachingService.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ @@ -17,16 +17,16 @@ import org.eclipse.cdt.dsf.datamodel.IDMContext; /** * Interface for services which use an internal cache for data. - * - * @since 1.1 + * + * @since 1.1 */ public interface ICachingService { - - /** - * Clears the service cache entries which have the given context in their - * hierarchy. - * @param context Root context to flush. May be <code>null</code> to flush - * the entire cache. - */ - public void flushCache(IDMContext context); + + /** + * Clears the service cache entries which have the given context in their + * hierarchy. + * @param context Root context to flush. May be <code>null</code> to flush + * the entire cache. + */ + public void flushCache(IDMContext context); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDisassembly.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDisassembly.java index 7fd038ff79d..a7691d189c6 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDisassembly.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDisassembly.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Ericsson - initial API and implementation *******************************************************************************/ @@ -22,16 +22,17 @@ import org.eclipse.cdt.dsf.service.IDsfService; /** * Disassembly service interface - * + * * @since 1.0 */ public interface IDisassembly extends IDsfService { - public interface IDisassemblyDMContext extends IDMContext {} + public interface IDisassemblyDMContext extends IDMContext { + } /** * Gets a block of disassembled code given an address range. - * + * * @param context * Context of the disassembly code * @param startAddress @@ -44,16 +45,13 @@ public interface IDisassembly extends IDsfService { * @param drm * Disassembled code */ - public void getInstructions( - IDisassemblyDMContext context, - BigInteger startAddress, - BigInteger endAddress, - DataRequestMonitor<IInstruction[]> drm); + public void getInstructions(IDisassemblyDMContext context, BigInteger startAddress, BigInteger endAddress, + DataRequestMonitor<IInstruction[]> drm); /** * Gets a block of disassembled code given a filename, line number, and line * count. - * + * * @param context * Context of the disassembly code * @param filename @@ -65,20 +63,16 @@ public interface IDisassembly extends IDsfService { * @param instructionCount * Number of instructions to disassemble. -1 means all * available instructions (starting at [linenum]) - * + * * @param drm * Disassembled code */ - public void getInstructions( - IDisassemblyDMContext context, - String filename, - int linenum, - int instrtuctionCount, - DataRequestMonitor<IInstruction[]> drm); + public void getInstructions(IDisassemblyDMContext context, String filename, int linenum, int instrtuctionCount, + DataRequestMonitor<IInstruction[]> drm); /** * Gets a block of mixed disassembled code given an address range. - * + * * @param context * Context of the disassembly code * @param startAddress @@ -89,15 +83,12 @@ public interface IDisassembly extends IDsfService { * @param drm * Disassembled code */ - public void getMixedInstructions( - IDisassemblyDMContext context, - BigInteger startAddress, - BigInteger endAddress, - DataRequestMonitor<IMixedInstruction[]> drm); + public void getMixedInstructions(IDisassemblyDMContext context, BigInteger startAddress, BigInteger endAddress, + DataRequestMonitor<IMixedInstruction[]> drm); /** * Gets a block of mixed disassembled code given a filename, line number, and line count. - * + * * @param context * Context of the disassembly code * @param filename @@ -112,11 +103,7 @@ public interface IDisassembly extends IDsfService { * @param drm * Disassembled code */ - public void getMixedInstructions( - IDisassemblyDMContext context, - String filename, - int linenum, - int instructionCount, - DataRequestMonitor<IMixedInstruction[]> drm); + public void getMixedInstructions(IDisassemblyDMContext context, String filename, int linenum, int instructionCount, + DataRequestMonitor<IMixedInstruction[]> drm); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDisassembly2.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDisassembly2.java index aa0a5e920be..77c923d2bc6 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDisassembly2.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDisassembly2.java @@ -20,21 +20,18 @@ import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; /** * This interface extends the disassembly service with support for * address alignment extension request. - * + * * @since 2.2 */ public interface IDisassembly2 extends IDisassembly { /** * Aligns the given opCode address. This method will be call for each - * disassembly request, the service should try to resolve + * disassembly request, the service should try to resolve * the given address and align it to a valid opCode address. - * + * * @param context context of the disassembly code * @param address the address to align * @param drm aligned address */ - void alignOpCodeAddress( - IDisassemblyDMContext context, - BigInteger address, - DataRequestMonitor<BigInteger> drm); + void alignOpCodeAddress(IDisassemblyDMContext context, BigInteger address, DataRequestMonitor<BigInteger> drm); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDisassembly3.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDisassembly3.java index 30b4a87259c..12e1d0244bc 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDisassembly3.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDisassembly3.java @@ -19,15 +19,15 @@ import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; /** * This interface extends the disassembly service with support for raw opcodes - * + * * @since 2.5 - * + * */ public interface IDisassembly3 extends IDisassembly2 { /** * Gets a block of disassembled code given an address range. - * + * * @param context * Context of the disassembly code * @param startAddress @@ -42,14 +42,13 @@ public interface IDisassembly3 extends IDisassembly2 { * @param drm * Disassembled code */ - public void getInstructions(IDisassemblyDMContext context, - BigInteger startAddress, BigInteger endAddress, boolean opCodes, - DataRequestMonitor<IInstruction[]> drm); + public void getInstructions(IDisassemblyDMContext context, BigInteger startAddress, BigInteger endAddress, + boolean opCodes, DataRequestMonitor<IInstruction[]> drm); /** * Gets a block of disassembled code given a filename, line number, and line * count. - * + * * @param context * Context of the disassembly code * @param filename @@ -63,17 +62,16 @@ public interface IDisassembly3 extends IDisassembly2 { * instructions (starting at [linenum]) * @param opCodes * If raw opcodes should be retrieved - * + * * @param drm * Disassembled code */ - public void getInstructions(IDisassemblyDMContext context, String filename, - int linenum, int instructionCount, boolean opCodes, - DataRequestMonitor<IInstruction[]> drm); + public void getInstructions(IDisassemblyDMContext context, String filename, int linenum, int instructionCount, + boolean opCodes, DataRequestMonitor<IInstruction[]> drm); /** * Gets a block of mixed disassembled code given an address range. - * + * * @param context * Context of the disassembly code * @param startAddress @@ -86,14 +84,13 @@ public interface IDisassembly3 extends IDisassembly2 { * @param drm * Disassembled code */ - public void getMixedInstructions(IDisassemblyDMContext context, - BigInteger startAddress, BigInteger endAddress, boolean opCodes, - DataRequestMonitor<IMixedInstruction[]> drm); + public void getMixedInstructions(IDisassemblyDMContext context, BigInteger startAddress, BigInteger endAddress, + boolean opCodes, DataRequestMonitor<IMixedInstruction[]> drm); /** * Gets a block of mixed disassembled code given a filename, line number, * and line count. - * + * * @param context * Context of the disassembly code * @param filename @@ -110,8 +107,7 @@ public interface IDisassembly3 extends IDisassembly2 { * @param drm * Disassembled code */ - public void getMixedInstructions(IDisassemblyDMContext context, - String filename, int linenum, int instructionCount, + public void getMixedInstructions(IDisassemblyDMContext context, String filename, int linenum, int instructionCount, boolean opCodes, DataRequestMonitor<IMixedInstruction[]> drm); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDsfBreakpointExtension.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDsfBreakpointExtension.java index 6ba04a0b742..a4b87c0a879 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDsfBreakpointExtension.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDsfBreakpointExtension.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation * Marc Khouzam (Ericsson) - Adding javadoc (Bug 355833) @@ -21,78 +21,78 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.core.runtime.CoreException; /** - * An extension to {@link ICBreakpoint} with model-specific breakpoint - * attributes. Different debug models can use the standard C breakpoints that - * extend the basic <code>ICBreakpoint</code>. They can use this extension - * mechanism to edit and store model-specific data in the original breakpoint + * An extension to {@link ICBreakpoint} with model-specific breakpoint + * attributes. Different debug models can use the standard C breakpoints that + * extend the basic <code>ICBreakpoint</code>. They can use this extension + * mechanism to edit and store model-specific data in the original breakpoint * object. - * - * A breakpoint extension is defined by an extension of kind + * + * A breakpoint extension is defined by an extension of kind * <code>"org.eclipse.cdt.debug.core.BreakpointExtension"</code></li>. - * The <code>ICBreakpoint</code> implementation instantiates breakpoint + * The <code>ICBreakpoint</code> implementation instantiates breakpoint * extensions registered for its specific marker type when a client requests - * extensions for a given debug model type. Thus the extension classes and - * plugins that declare them are not loaded unless requested by a client. - * + * extensions for a given debug model type. Thus the extension classes and + * plugins that declare them are not loaded unless requested by a client. + * * @see ICBreakpoint#getExtension(String, Class) * @since 1.0 */ public interface IDsfBreakpointExtension extends ICBreakpointExtension { - - /** - * Add the given target to the list of this breakpoint's targets. - * Target filters are not persisted across workbench invocations. - * - * @param target the container to add to the list of this breakpoint's targets. - * @throws CoreException if unable to set the target filter - */ + + /** + * Add the given target to the list of this breakpoint's targets. + * Target filters are not persisted across workbench invocations. + * + * @param target the container to add to the list of this breakpoint's targets. + * @throws CoreException if unable to set the target filter + */ public void setTargetFilter(IContainerDMContext target) throws CoreException; - - /** - * Removes the given target from the breakpoint's target list. - * The breakpoint has no effect in the given target. - * - * @param target the container filter to be removed - * @exception CoreException if unable to remove the target filter - */ - public void removeTargetFilter(IContainerDMContext target) throws CoreException; - - /** - * Returns all target filters set on this breakpoint. - * - * @return the targets that this breakpoint is restricted to - * @exception CoreException if unable to determine this breakpoint's target filters - */ - public IContainerDMContext[] getTargetFilters() throws CoreException; - /** - * Restricts this breakpoint to suspend only in the given threads - * when encountered in the given threads' target. - * All threads must be from the same target. - * Thread filters are not persisted across workbench invocations. - * - * @param threads the thread filters to be set - * @exception CoreException if unable to set the thread filters - */ - public void setThreadFilters(IExecutionDMContext[] threads) throws CoreException; + /** + * Removes the given target from the breakpoint's target list. + * The breakpoint has no effect in the given target. + * + * @param target the container filter to be removed + * @exception CoreException if unable to remove the target filter + */ + public void removeTargetFilter(IContainerDMContext target) throws CoreException; + + /** + * Returns all target filters set on this breakpoint. + * + * @return the targets that this breakpoint is restricted to + * @exception CoreException if unable to determine this breakpoint's target filters + */ + public IContainerDMContext[] getTargetFilters() throws CoreException; + + /** + * Restricts this breakpoint to suspend only in the given threads + * when encountered in the given threads' target. + * All threads must be from the same target. + * Thread filters are not persisted across workbench invocations. + * + * @param threads the thread filters to be set + * @exception CoreException if unable to set the thread filters + */ + public void setThreadFilters(IExecutionDMContext[] threads) throws CoreException; + + /** + * Removes this breakpoint's thread filters in the given target, if any. + * Has no effect if this breakpoint does not have filters in the given target. + * All threads must be from the same target. + * + * @param threads the thread filters to be removed + * @exception CoreException if unable to remove the thread filter + */ + public void removeThreadFilters(IExecutionDMContext[] threads) throws CoreException; - /** - * Removes this breakpoint's thread filters in the given target, if any. - * Has no effect if this breakpoint does not have filters in the given target. - * All threads must be from the same target. - * - * @param threads the thread filters to be removed - * @exception CoreException if unable to remove the thread filter - */ - public void removeThreadFilters(IExecutionDMContext[] threads) throws CoreException; - - /** - * Returns the threads in the given target in which this breakpoint - * is enabled or <code>null</code> if this breakpoint is enabled in - * all threads in the given target. - * - * @return the threads in the given target that this breakpoint is enabled for - * @exception CoreException if unable to determine this breakpoint's thread filters - */ - public IExecutionDMContext[] getThreadFilters(IContainerDMContext target) throws CoreException; + /** + * Returns the threads in the given target in which this breakpoint + * is enabled or <code>null</code> if this breakpoint is enabled in + * all threads in the given target. + * + * @return the threads in the given target that this breakpoint is enabled for + * @exception CoreException if unable to determine this breakpoint's thread filters + */ + public IExecutionDMContext[] getThreadFilters(IContainerDMContext target) throws CoreException; } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDsfDebugServicesFactory.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDsfDebugServicesFactory.java index 58d5809bdfb..72cae146718 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDsfDebugServicesFactory.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDsfDebugServicesFactory.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Ericsson - initial API and implementation *******************************************************************************/ @@ -18,9 +18,9 @@ import org.eclipse.cdt.dsf.service.DsfSession; /** * A factory to create DSF services. Using this interface allows * to easily have different service implementation for different backends. - * + * * @since 1.1 */ public interface IDsfDebugServicesFactory { - <V> V createService(Class<V> clazz, DsfSession session, Object ... optionalArguments); + <V> V createService(Class<V> clazz, DsfSession session, Object... optionalArguments); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions.java index 710c3624c05..1cdcf7d4609 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation * Ericsson - Update for GDB/MI @@ -27,33 +27,33 @@ import org.eclipse.cdt.dsf.datamodel.IDMEvent; /** * Expressions service provides access to the debugger's expression evaluator. This service has - * dependencies on the Stack service, as it is be used to provide context for an + * dependencies on the Stack service, as it is be used to provide context for an * expression to be evaluated. - * + * * @since 1.0 */ @SuppressWarnings("nls") public interface IExpressions extends IFormattedValues { - - /** - * Expression context. - */ - public interface IExpressionDMContext extends IFormattedDataDMContext { - /** - * Returns a fully qualified expression string represented by this context. This - * expression string is the same as the string that is sent to the debug engine to be - * evaluated in context of a stack frame, thread, or a symbol context. - */ - String getExpression(); - } - - /** - * To avoid SWT performance issues large arrays are divided into partitions. - * This interface represents the context of such a partition. - * - * @since 2.3 - */ - public interface IIndexedPartitionDMContext extends IExpressionDMContext { + + /** + * Expression context. + */ + public interface IExpressionDMContext extends IFormattedDataDMContext { + /** + * Returns a fully qualified expression string represented by this context. This + * expression string is the same as the string that is sent to the debug engine to be + * evaluated in context of a stack frame, thread, or a symbol context. + */ + String getExpression(); + } + + /** + * To avoid SWT performance issues large arrays are divided into partitions. + * This interface represents the context of such a partition. + * + * @since 2.3 + */ + public interface IIndexedPartitionDMContext extends IExpressionDMContext { /** * Returns the expression string of the parent array. @@ -61,10 +61,10 @@ public interface IExpressions extends IFormattedValues { public String getParentExpression(); /** - * Returns the index of the partition's first element in the parent array. + * Returns the index of the partition's first element in the parent array. */ public int getIndex(); - + /** * Returns the number of array's elements in the partition. */ @@ -73,282 +73,333 @@ public interface IExpressions extends IFormattedValues { /** * Represents a group of expressions. A group of expressions is a list of - * possibly unrelated expressions which are somehow described by an + * possibly unrelated expressions which are somehow described by an * expression-group string. - * + * * Examples of expression-groups that the service could choose to support are: * "myVar1; myVar2" * "=myVar*" - * + * * The sub-expressions of an expression-group are the individual expressions * making up this group. - * + * * @since 2.4 */ - public interface IExpressionGroupDMContext extends IExpressionDMContext {} - - /** - * The address and size of an expression. - */ - public interface IExpressionDMAddress { - - /** - * Returns the address of the expression. - */ - IAddress getAddress(); - - /** - * Returns the size of the address. - */ - int getSize(); - - /** - * @return The memory space - * @since 2.7 - */ - default String getMemorySpaceID() { - return ""; - } - } - - /** - * A representation of an expression location that does not correspond to - * an address. - * - * @since 2.1 - */ - public interface IExpressionDMLocation extends IExpressionDMAddress { - - /** - * A constant that can be returned by {@link IExpressionDMAddress#getAddress()} - * to represent an invalid address. Implementations of - * <code>IExpressionDMLocation</code> can return this constant if no - * valid address can be returned for a given expression location. - */ - public static final IAddress INVALID_ADDRESS = new IAddress() { - @Override public IAddress add(BigInteger offset) { return this; } - @Override public IAddress add(long offset) { return this; } - @Override public BigInteger getMaxOffset() { return BigInteger.ZERO; } - @Override public BigInteger distanceTo(IAddress other) { return BigInteger.ZERO; } - @Override public BigInteger getValue() { return BigInteger.ZERO; } - @Override public boolean isZero() { return false; } - @Override public boolean isMax() { return false; } - @Override public String toString(int radix) { return "INVALID"; } - @Override public String toHexAddressString() { return toString(); } - @Override public String toBinaryAddressString() { return toString(); } - @Override public int getCharsNum() { return 0; } - @Override public int getSize() { return 0; } - @Override public int compareTo(Object o) { return 0; } - }; - - /** - * Returns a string representation of the expression location. - */ - public String getLocation(); - } - - - - /** - * This is the model data interface that corresponds to IExpressionDMContext. - */ - public interface IExpressionDMData extends IDMData { - // These static fields define the possible return values of method getTypeId(). - - final static String TYPEID_UNKNOWN = "TYPEID_UNKNOWN"; - final static String TYPEID_INTEGER = "TYPEID_INTEGER"; - final static String TYPEID_CHAR = "TYPEID_CHAR"; - final static String TYPEID_FLOAT = "TYPEID_FLOAT"; - final static String TYPEID_DOUBLE = "TYPEID_DOUBLE"; - final static String TYPEID_OPAQUE = "TYPEID_OPAQUE"; - - /** - * This enumerates the possible basic types that an expression can have. - * - * @see getBasicType(). - */ - enum BasicType { - unknown, // Unknown type. - basic, // Scalar type (e.g., int, short, float). - pointer, // Pointer to anything. - array, // Array of anything. - composite, // Struct, union, or class. - enumeration, // Enumeration. - function // Function. - } - - /** - * If this expression is a sub-expression of another expression, this method returns - * the expression relative to the parent of this expression. Otherwise this method - * will return the same string as {@link #getExpression()}. - */ - String getName(); - - /** - * @return A BasicType enumerator describing the basic type of an expression. - */ - BasicType getBasicType(); - - /** - * @return The source code type of this expression. This is a string such as "struct Foo", "short", - * "int *", "mytypedef", "(int *)[]", "enum Bar". If the debugger backend cannot supply - * this information, this method returns "<UNKNOWN>" (the angle brackets are there just in - * case there is a type named "UNKNOWN" in the application). - * <p> - * If you implement {@link IExpressions2}, this should return the casted type name, - * if this expression was generated via {@link IExpressions2#createCastedExpression(IDMContext, String, IExpressions2.ICastedExpressionDMContext)} - */ - String getTypeName(); - - /** - * This method needs to be defined. For now, this returns the empty string. - */ - String getEncoding(); - - /** - * @return One of the TYPEID_* static field values defined by this interface. - */ - String getTypeId(); - - /** - * @return A Map in which the keys are strings that are the names of enumerators in the enumeration - * that is the value of this expression and the values are the integer values of the - * enumerators. If the expression type is not an enumeration, this returns an empty Map. - */ - Map<String, Integer> getEnumerations(); - - /** - * This method needs to be defined. - */ - IRegisters.IRegisterDMContext getRegister(); - } - - /** - * Event indicating that a given expression is changed. If an expression is changed, it's implied that all - * the children of that expression are changed too. - */ - public interface IExpressionChangedDMEvent extends IDMEvent<IExpressionDMContext> {} - - - /** - * Retrieves the expression DM data object for the given expression context(<tt>dmc</tt>). - * - * @param dmc - * The ExpressionDMC for the expression to be evaluated. - * @param rm - * The data request monitor that will contain the requested data - */ - void getExpressionData(IExpressionDMContext dmc, DataRequestMonitor<IExpressionDMData> rm); - - /** - * Retrieves the address and size of an expression given by the expression context(<tt>dmc</tt>). - * Non-lvalues do not have an addresses (e.g., "x + 5"). When the expression -- * has no address, the request monitor will have an error with code - * <code>IDsfStatusConstants.REQUEST_FAILED</code> and the data request - * monitor will contain null. - * - * @param dmc - * The ExpressionDMC for the expression - * @param rm - * The data request monitor that will contain the requested data - */ - void getExpressionAddressData(IExpressionDMContext dmc, DataRequestMonitor<IExpressionDMAddress> rm); - - /** - * Returns the data model context object for the specified expression in the context - * specified by <b>ctx</b>. - * - * @param ctx: Context in which to evaluate the expression. This context could include the - * PC location, stack frame, thread, or just a symbol context. - * - * @param expression: The expression to evaluate. - * - * @return An expression data model context object that must be passed to the appropriate - * data retrieval routine to obtain the value of the expression. - */ - IExpressionDMContext createExpression(IDMContext ctx, String expression); - - /** - * Retrieves the sub-expressions of the given expression. Sub-expressions are fields of a struct, union, - * or class, the enumerators of an enumeration, and the element of an array. - * <br> - * Note: Clients may call this method on any valid expression context, and before calling any other - * method to evaluate the expression value. It is up to the implementation to internally evaluate the - * expression if needed, in order to calculate sub expressions. - * - * @param exprCtx: The data model context representing an expression. - * - * @param rm: Request completion monitor containing an array of all sub-expressions - */ - void getSubExpressions(IExpressionDMContext exprCtx, DataRequestMonitor<IExpressionDMContext[]> rm); - - /** - * Retrieves a particular range of sub-expressions of the given expression. - * Sub-expressions are fields of a struct, union, or class, the enumerators - * of an enumeration, and the element of an array. - * <br> - * Note: Clients may call this method on any valid expression context, and before calling any other - * method to evaluate the expression value. It is up to the implementation to internally evaluate the - * expression if needed, in order to calculate sub expressions. - * - * @param exprCtx: The data model context representing an expression. - * startIndex: Index of the first sub-expression to retrieve - * length: Total number of sub-expressions to retrieve - * - * @param rm: Request completion monitor containing an array of the requested - * range of sub-expressions - */ - void getSubExpressions(IExpressionDMContext exprCtx, int startIndex, int length, - DataRequestMonitor<IExpressionDMContext[]> rm); - - /** - * Retrieves the number of sub-expressions of the given expression. Sub-expressions are fields of a struct, union, - * or class, the enumerators of an enumeration, and the element of an array. - * <br> - * Note: Clients may call this method on any valid expression context, and before calling any other - * method to evaluate the expression value. It is up to the implementation to internally evaluate the - * expression if needed, in order to calculate sub expressions. - * - * @param exprCtx: The data model context representing an expression. - * - * @param rm: Request completion monitor containing the number of sub-expressions - * of the specified expression - */ - void getSubExpressionCount(IExpressionDMContext exprCtx, DataRequestMonitor<Integer> rm); - - /** - * For object oriented languages, this method returns the expressions representing base types of - * the given expression type. - * <br> - * Note: Clients may call this method on any valid expression context, and before calling any other - * method to evaluate the expression value. It is up to the implementation to internally evaluate the - * expression if needed, in order to calculate sub expressions. - * - * @param exprContext: The data model context representing an expression. - * - * @param rm: Request completion monitor. - */ - void getBaseExpressions(IExpressionDMContext exprContext, DataRequestMonitor<IExpressionDMContext[]> rm); - - /** - * This method indicates if an expression can be written to. - * - * @param expressionContext: The data model context representing an expression. - * - * @param rm: Data Request monitor containing True if this expression's value can be edited. False otherwise. - */ - void canWriteExpression(IExpressionDMContext expressionContext, DataRequestMonitor<Boolean> rm); - - /** - * This method supports the writing/modifying the value of the expression. - * - * @param expressionContext: The data model context representing an expression. - * - * @param expressionValue: The new value of the expression as a String. - * - * @param formatId: The format ID specifying the format of parameter <b>expressionValue</b>. - * - * @param rm: Request completion monitor. - */ - void writeExpression(IExpressionDMContext expressionContext, String expressionValue, String formatId, RequestMonitor rm); + public interface IExpressionGroupDMContext extends IExpressionDMContext { + } + + /** + * The address and size of an expression. + */ + public interface IExpressionDMAddress { + + /** + * Returns the address of the expression. + */ + IAddress getAddress(); + + /** + * Returns the size of the address. + */ + int getSize(); + + /** + * @return The memory space + * @since 2.7 + */ + default String getMemorySpaceID() { + return ""; + } + } + + /** + * A representation of an expression location that does not correspond to + * an address. + * + * @since 2.1 + */ + public interface IExpressionDMLocation extends IExpressionDMAddress { + + /** + * A constant that can be returned by {@link IExpressionDMAddress#getAddress()} + * to represent an invalid address. Implementations of + * <code>IExpressionDMLocation</code> can return this constant if no + * valid address can be returned for a given expression location. + */ + public static final IAddress INVALID_ADDRESS = new IAddress() { + @Override + public IAddress add(BigInteger offset) { + return this; + } + + @Override + public IAddress add(long offset) { + return this; + } + + @Override + public BigInteger getMaxOffset() { + return BigInteger.ZERO; + } + + @Override + public BigInteger distanceTo(IAddress other) { + return BigInteger.ZERO; + } + + @Override + public BigInteger getValue() { + return BigInteger.ZERO; + } + + @Override + public boolean isZero() { + return false; + } + + @Override + public boolean isMax() { + return false; + } + + @Override + public String toString(int radix) { + return "INVALID"; + } + + @Override + public String toHexAddressString() { + return toString(); + } + + @Override + public String toBinaryAddressString() { + return toString(); + } + + @Override + public int getCharsNum() { + return 0; + } + + @Override + public int getSize() { + return 0; + } + + @Override + public int compareTo(Object o) { + return 0; + } + }; + + /** + * Returns a string representation of the expression location. + */ + public String getLocation(); + } + + /** + * This is the model data interface that corresponds to IExpressionDMContext. + */ + public interface IExpressionDMData extends IDMData { + // These static fields define the possible return values of method getTypeId(). + + final static String TYPEID_UNKNOWN = "TYPEID_UNKNOWN"; + final static String TYPEID_INTEGER = "TYPEID_INTEGER"; + final static String TYPEID_CHAR = "TYPEID_CHAR"; + final static String TYPEID_FLOAT = "TYPEID_FLOAT"; + final static String TYPEID_DOUBLE = "TYPEID_DOUBLE"; + final static String TYPEID_OPAQUE = "TYPEID_OPAQUE"; + + /** + * This enumerates the possible basic types that an expression can have. + * + * @see getBasicType(). + */ + enum BasicType { + unknown, // Unknown type. + basic, // Scalar type (e.g., int, short, float). + pointer, // Pointer to anything. + array, // Array of anything. + composite, // Struct, union, or class. + enumeration, // Enumeration. + function // Function. + } + + /** + * If this expression is a sub-expression of another expression, this method returns + * the expression relative to the parent of this expression. Otherwise this method + * will return the same string as {@link #getExpression()}. + */ + String getName(); + + /** + * @return A BasicType enumerator describing the basic type of an expression. + */ + BasicType getBasicType(); + + /** + * @return The source code type of this expression. This is a string such as "struct Foo", "short", + * "int *", "mytypedef", "(int *)[]", "enum Bar". If the debugger backend cannot supply + * this information, this method returns "<UNKNOWN>" (the angle brackets are there just in + * case there is a type named "UNKNOWN" in the application). + * <p> + * If you implement {@link IExpressions2}, this should return the casted type name, + * if this expression was generated via {@link IExpressions2#createCastedExpression(IDMContext, String, IExpressions2.ICastedExpressionDMContext)} + */ + String getTypeName(); + + /** + * This method needs to be defined. For now, this returns the empty string. + */ + String getEncoding(); + + /** + * @return One of the TYPEID_* static field values defined by this interface. + */ + String getTypeId(); + + /** + * @return A Map in which the keys are strings that are the names of enumerators in the enumeration + * that is the value of this expression and the values are the integer values of the + * enumerators. If the expression type is not an enumeration, this returns an empty Map. + */ + Map<String, Integer> getEnumerations(); + + /** + * This method needs to be defined. + */ + IRegisters.IRegisterDMContext getRegister(); + } + + /** + * Event indicating that a given expression is changed. If an expression is changed, it's implied that all + * the children of that expression are changed too. + */ + public interface IExpressionChangedDMEvent extends IDMEvent<IExpressionDMContext> { + } + + /** + * Retrieves the expression DM data object for the given expression context(<tt>dmc</tt>). + * + * @param dmc + * The ExpressionDMC for the expression to be evaluated. + * @param rm + * The data request monitor that will contain the requested data + */ + void getExpressionData(IExpressionDMContext dmc, DataRequestMonitor<IExpressionDMData> rm); + + /** + * Retrieves the address and size of an expression given by the expression context(<tt>dmc</tt>). + * Non-lvalues do not have an addresses (e.g., "x + 5"). When the expression + - * has no address, the request monitor will have an error with code + * <code>IDsfStatusConstants.REQUEST_FAILED</code> and the data request + * monitor will contain null. + * + * @param dmc + * The ExpressionDMC for the expression + * @param rm + * The data request monitor that will contain the requested data + */ + void getExpressionAddressData(IExpressionDMContext dmc, DataRequestMonitor<IExpressionDMAddress> rm); + + /** + * Returns the data model context object for the specified expression in the context + * specified by <b>ctx</b>. + * + * @param ctx: Context in which to evaluate the expression. This context could include the + * PC location, stack frame, thread, or just a symbol context. + * + * @param expression: The expression to evaluate. + * + * @return An expression data model context object that must be passed to the appropriate + * data retrieval routine to obtain the value of the expression. + */ + IExpressionDMContext createExpression(IDMContext ctx, String expression); + + /** + * Retrieves the sub-expressions of the given expression. Sub-expressions are fields of a struct, union, + * or class, the enumerators of an enumeration, and the element of an array. + * <br> + * Note: Clients may call this method on any valid expression context, and before calling any other + * method to evaluate the expression value. It is up to the implementation to internally evaluate the + * expression if needed, in order to calculate sub expressions. + * + * @param exprCtx: The data model context representing an expression. + * + * @param rm: Request completion monitor containing an array of all sub-expressions + */ + void getSubExpressions(IExpressionDMContext exprCtx, DataRequestMonitor<IExpressionDMContext[]> rm); + + /** + * Retrieves a particular range of sub-expressions of the given expression. + * Sub-expressions are fields of a struct, union, or class, the enumerators + * of an enumeration, and the element of an array. + * <br> + * Note: Clients may call this method on any valid expression context, and before calling any other + * method to evaluate the expression value. It is up to the implementation to internally evaluate the + * expression if needed, in order to calculate sub expressions. + * + * @param exprCtx: The data model context representing an expression. + * startIndex: Index of the first sub-expression to retrieve + * length: Total number of sub-expressions to retrieve + * + * @param rm: Request completion monitor containing an array of the requested + * range of sub-expressions + */ + void getSubExpressions(IExpressionDMContext exprCtx, int startIndex, int length, + DataRequestMonitor<IExpressionDMContext[]> rm); + + /** + * Retrieves the number of sub-expressions of the given expression. Sub-expressions are fields of a struct, union, + * or class, the enumerators of an enumeration, and the element of an array. + * <br> + * Note: Clients may call this method on any valid expression context, and before calling any other + * method to evaluate the expression value. It is up to the implementation to internally evaluate the + * expression if needed, in order to calculate sub expressions. + * + * @param exprCtx: The data model context representing an expression. + * + * @param rm: Request completion monitor containing the number of sub-expressions + * of the specified expression + */ + void getSubExpressionCount(IExpressionDMContext exprCtx, DataRequestMonitor<Integer> rm); + + /** + * For object oriented languages, this method returns the expressions representing base types of + * the given expression type. + * <br> + * Note: Clients may call this method on any valid expression context, and before calling any other + * method to evaluate the expression value. It is up to the implementation to internally evaluate the + * expression if needed, in order to calculate sub expressions. + * + * @param exprContext: The data model context representing an expression. + * + * @param rm: Request completion monitor. + */ + void getBaseExpressions(IExpressionDMContext exprContext, DataRequestMonitor<IExpressionDMContext[]> rm); + + /** + * This method indicates if an expression can be written to. + * + * @param expressionContext: The data model context representing an expression. + * + * @param rm: Data Request monitor containing True if this expression's value can be edited. False otherwise. + */ + void canWriteExpression(IExpressionDMContext expressionContext, DataRequestMonitor<Boolean> rm); + + /** + * This method supports the writing/modifying the value of the expression. + * + * @param expressionContext: The data model context representing an expression. + * + * @param expressionValue: The new value of the expression as a String. + * + * @param formatId: The format ID specifying the format of parameter <b>expressionValue</b>. + * + * @param rm: Request completion monitor. + */ + void writeExpression(IExpressionDMContext expressionContext, String expressionValue, String formatId, + RequestMonitor rm); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions2.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions2.java index 5bb9b87214b..e81dac3ab7d 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions2.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions2.java @@ -18,7 +18,7 @@ import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; /** * This interface extends the expressions service with support for casting to type or - * array. + * array. * @since 2.1 */ public interface IExpressions2 extends IExpressions { @@ -43,7 +43,7 @@ public interface IExpressions2 extends IExpressions { this.arrayStart = arrayStart; this.arrayCount = arrayCount; } - + /** * Create an instance of casting information for casting to type (only) * @param typeString must be non-<code>null</code>; the C/C++ type to which to cast the expression (e.g. "char**") @@ -54,8 +54,7 @@ public interface IExpressions2 extends IExpressions { this.typeString = typeString; this.arrayStart = this.arrayCount = 0; } - - + /** * Create an instance of casting information for showing as an array (only) * @param arrayStart the start index for viewing contents of the expression as an array @@ -78,8 +77,7 @@ public interface IExpressions2 extends IExpressions { int result = 1; result = prime * result + arrayCount; result = prime * result + arrayStart; - result = prime * result - + ((typeString == null) ? 0 : typeString.hashCode()); + result = prime * result + ((typeString == null) ? 0 : typeString.hashCode()); return result; } @@ -115,68 +113,66 @@ public interface IExpressions2 extends IExpressions { public String getTypeString() { return typeString; } - + /** * Get the start index for viewing children as an array. (Only effective if #getCount() > 0) - * @return the index of the first element of the array. 0 means that + * @return the index of the first element of the array. 0 means that * the original element is the first member of the array. This may be negative, too. */ - public int getArrayStartIndex(){ + public int getArrayStartIndex() { return arrayStart; } - + /** * Get the number of elements to show when viewing children as an array. * @return the array size, or <= 0 if not viewing as an array */ - public int getArrayCount(){ + public int getArrayCount() { return arrayCount; } } - + /** * This context identifies a casted expression. Its parent is the original * {@link IExpressionDMContext}. */ public interface ICastedExpressionDMContext extends IExpressionDMContext { CastInfo getCastInfo(); - + } - + /** * Create a variant of the expression which is casted with the given casting info. * <p> - * If {@link ICastInfo#getTypeString()} is not <code>null</code>, such an expression should + * If {@link ICastInfo#getTypeString()} is not <code>null</code>, such an expression should * report the casted type via {@link IExpressionDMData} and generate subexpressions accordingly. * <p> * Note that typically, a cast of a primitive type (int, double, etc.) to another * primitive type is interpreted as "*(other_type*)&(expression)", not merely - * as casting the rvalue of "expression" to another type (which usually only - * truncates or extends the value without much benefit). + * as casting the rvalue of "expression" to another type (which usually only + * truncates or extends the value without much benefit). * <p> * If {@link ICastInfo#getArrayCount()} is greater than <code>0</code>, the expression should * yield that number of elements as subexpressions, as array elements, starting with index - * {@link ICastInfo#getArrayStartIndex()}. (This does not affect the address of the - * expression itself, only which children are returned.) + * {@link ICastInfo#getArrayStartIndex()}. (This does not affect the address of the + * expression itself, only which children are returned.) * <p> * The expected semantics of an array cast ranging from J to K are to take a * pointer-valued expression whose base type is size N, evaluate its value * to A, and yield array elements of the pointer base type at locations * <code>A + N*J</code>, <code>A + N*(J+1)</code>, ..., - * <code>A + N*(J+K-1)</code>. But the address of the expression is <b>not</b> modified - * when an array cast is applied. + * <code>A + N*(J+K-1)</code>. But the address of the expression is <b>not</b> modified + * when an array cast is applied. * <p>An implementation may provide its own semantics for viewing other data as arrays, if so desired. * @param context an existing expression * @param castInfo the casting information * @return a casted expression data model context object that must be passed to the appropriate - * data retrieval routine to obtain the value of the expression. The object must - * report the casted type (if any) via {@link #getExpressionData(IExpressionDMContext, DataRequestMonitor)} - * and report alternate children according to the array casting context via - * {@link #getSubExpressionCount(IExpressionDMContext, DataRequestMonitor)} - * and {@link #getSubExpressions}. + * data retrieval routine to obtain the value of the expression. The object must + * report the casted type (if any) via {@link #getExpressionData(IExpressionDMContext, DataRequestMonitor)} + * and report alternate children according to the array casting context via + * {@link #getSubExpressionCount(IExpressionDMContext, DataRequestMonitor)} + * and {@link #getSubExpressions}. */ - ICastedExpressionDMContext createCastedExpression(IExpressionDMContext context, - CastInfo castInfo); - + ICastedExpressionDMContext createCastedExpression(IExpressionDMContext context, CastInfo castInfo); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions3.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions3.java index 040ae6804bd..7e18f7157a8 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions3.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IExpressions3.java @@ -17,34 +17,32 @@ package org.eclipse.cdt.dsf.debug.service; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; /** - * This interface extends the expressions service with support for + * This interface extends the expressions service with support for * model data extension requests. - * + * * @since 2.2 */ public interface IExpressions3 extends IExpressions2 { - - /** - * The model data interface extension. - */ - public interface IExpressionDMDataExtension extends IExpressionDMData { - - /** - * @return Whether the expression has children. - */ - boolean hasChildren(); - } - /** - * Retrieves the expression data extension object for the given - * expression context(<tt>dmc</tt>). - * - * @param dmc - * The ExpressionDMC for the expression to be evaluated. - * @param rm - * The data request monitor that will contain the requested data - */ - void getExpressionDataExtension( - IExpressionDMContext dmc, - DataRequestMonitor<IExpressionDMDataExtension> rm); + /** + * The model data interface extension. + */ + public interface IExpressionDMDataExtension extends IExpressionDMData { + + /** + * @return Whether the expression has children. + */ + boolean hasChildren(); + } + + /** + * Retrieves the expression data extension object for the given + * expression context(<tt>dmc</tt>). + * + * @param dmc + * The ExpressionDMC for the expression to be evaluated. + * @param rm + * The data request monitor that will contain the requested data + */ + void getExpressionDataExtension(IExpressionDMContext dmc, DataRequestMonitor<IExpressionDMDataExtension> rm); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IFormattedValues.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IFormattedValues.java index 5cb53ee7a0b..aad73321887 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IFormattedValues.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IFormattedValues.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ @@ -24,132 +24,131 @@ import org.eclipse.cdt.dsf.service.IDsfService; * Formatted values interface describes the kinds of formatted information * which may be returned and the methods for obtaining and manipulating * those values. - * + * * @since 1.0 */ public interface IFormattedValues extends IDsfService { - - /** Marker interface for a DMC that has a formatted value. */ - public interface IFormattedDataDMContext extends IDMContext {} - - /** - * These strings represent the standard known formats for any bit stream - * which needs to be formatted. These ID's as well as others which may be - * specifically available from the backend are what is returned from the - * getID() method. - */ - public final static String HEX_FORMAT = "HEX.Format" ; //$NON-NLS-1$ - public final static String OCTAL_FORMAT = "OCTAL.Format" ; //$NON-NLS-1$ - public final static String NATURAL_FORMAT = "NATURAL.Format" ; //$NON-NLS-1$ - public final static String BINARY_FORMAT = "BINARY.Format" ; //$NON-NLS-1$ - public final static String DECIMAL_FORMAT = "DECIMAL.Format" ; //$NON-NLS-1$ - public final static String STRING_FORMAT = "STRING.Format" ; //$NON-NLS-1$ - - /** - * Retrieves the formats that the given data is available in. - * This method is asynchronous because the service may need to retrieve - * information from the backend in order to determine what formats are - * available for the given data context. - * - * @param dmc Context for which to retrieve available formats. - * @param rm Completion monitor returns an array of support formatIds. - */ - public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor<String[]> rm); - - /** - * Creates a FormattedValueDMContext representing the given formatId. - * - * @param dmc Parent context for the context that is being created - * @param formatId Defines format to be used for the returned context. - */ - public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext dmc, String formatId); - - /** - * Retrieves the DM data associated with given formatted value context. - * @param dmc Context to retrieve the value for. - * @param rm Completion monitor returns the formatted value. - */ - public void getFormattedExpressionValue(FormattedValueDMContext dmc, DataRequestMonitor<FormattedValueDMData> rm); - - - /** - * DMC that represents a value with specific format. The format ID can be - * persisted and used for comparison. - */ - public static class FormattedValueDMContext extends AbstractDMContext - { - private final String fFormatID; - - /** + + /** Marker interface for a DMC that has a formatted value. */ + public interface IFormattedDataDMContext extends IDMContext { + } + + /** + * These strings represent the standard known formats for any bit stream + * which needs to be formatted. These ID's as well as others which may be + * specifically available from the backend are what is returned from the + * getID() method. + */ + public final static String HEX_FORMAT = "HEX.Format"; //$NON-NLS-1$ + public final static String OCTAL_FORMAT = "OCTAL.Format"; //$NON-NLS-1$ + public final static String NATURAL_FORMAT = "NATURAL.Format"; //$NON-NLS-1$ + public final static String BINARY_FORMAT = "BINARY.Format"; //$NON-NLS-1$ + public final static String DECIMAL_FORMAT = "DECIMAL.Format"; //$NON-NLS-1$ + public final static String STRING_FORMAT = "STRING.Format"; //$NON-NLS-1$ + + /** + * Retrieves the formats that the given data is available in. + * This method is asynchronous because the service may need to retrieve + * information from the backend in order to determine what formats are + * available for the given data context. + * + * @param dmc Context for which to retrieve available formats. + * @param rm Completion monitor returns an array of support formatIds. + */ + public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor<String[]> rm); + + /** + * Creates a FormattedValueDMContext representing the given formatId. + * + * @param dmc Parent context for the context that is being created + * @param formatId Defines format to be used for the returned context. + */ + public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext dmc, String formatId); + + /** + * Retrieves the DM data associated with given formatted value context. + * @param dmc Context to retrieve the value for. + * @param rm Completion monitor returns the formatted value. + */ + public void getFormattedExpressionValue(FormattedValueDMContext dmc, DataRequestMonitor<FormattedValueDMData> rm); + + /** + * DMC that represents a value with specific format. The format ID can be + * persisted and used for comparison. + */ + public static class FormattedValueDMContext extends AbstractDMContext { + private final String fFormatID; + + /** * @since 2.0 */ - public FormattedValueDMContext(IDsfService service, IDMContext parentValue, String formatId) { - super(service, new IDMContext[] { parentValue }); - fFormatID = formatId; - } - - public FormattedValueDMContext(String sessionId, IDMContext parentValue, String formatId) { - super(sessionId, new IDMContext[] { parentValue }); - fFormatID = formatId; - } - - /** - * Returns the parent context which represents the value on which this - * formatted value is based on. - * - * @since 2.2 - */ - public IDMContext getParentValueDMContext() { - return getParents()[0]; - } - - public String getFormatID() { - return fFormatID; - } - - @Override - public boolean equals(Object obj) { - return baseEquals(obj) && ((FormattedValueDMContext)obj).getFormatID().equals(getFormatID()); - } - - @Override - public int hashCode() { - return baseHashCode() + getFormatID().hashCode(); - } - - @Override - public String toString() { - return baseToString() + ".format(" + getFormatID() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - public static class FormattedValueDMData implements IDMData { - - private final String fValue; - private String fEditableValue; - - public FormattedValueDMData(String value) { - this(value, value); - } - - /** + public FormattedValueDMContext(IDsfService service, IDMContext parentValue, String formatId) { + super(service, new IDMContext[] { parentValue }); + fFormatID = formatId; + } + + public FormattedValueDMContext(String sessionId, IDMContext parentValue, String formatId) { + super(sessionId, new IDMContext[] { parentValue }); + fFormatID = formatId; + } + + /** + * Returns the parent context which represents the value on which this + * formatted value is based on. + * + * @since 2.2 + */ + public IDMContext getParentValueDMContext() { + return getParents()[0]; + } + + public String getFormatID() { + return fFormatID; + } + + @Override + public boolean equals(Object obj) { + return baseEquals(obj) && ((FormattedValueDMContext) obj).getFormatID().equals(getFormatID()); + } + + @Override + public int hashCode() { + return baseHashCode() + getFormatID().hashCode(); + } + + @Override + public String toString() { + return baseToString() + ".format(" + getFormatID() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + public static class FormattedValueDMData implements IDMData { + + private final String fValue; + private String fEditableValue; + + public FormattedValueDMData(String value) { + this(value, value); + } + + /** * @since 2.1 */ - public FormattedValueDMData(String value, String editableValue) { - fValue = value; - fEditableValue = editableValue; - } - - public String getFormattedValue() { - return fValue; - } - - /** + public FormattedValueDMData(String value, String editableValue) { + fValue = value; + fEditableValue = editableValue; + } + + public String getFormattedValue() { + return fValue; + } + + /** * @since 2.1 */ - public String getEditableValue() { - return fEditableValue; - } - - } + public String getEditableValue() { + return fEditableValue; + } + + } }
\ No newline at end of file diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IInstruction.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IInstruction.java index ce6e9612f75..2dc5b430228 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IInstruction.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IInstruction.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Ericsson - initial API and implementation *******************************************************************************/ @@ -22,40 +22,40 @@ import java.math.BigInteger; * Implementers should extend {@link AbstractInstruction} instead of * implementing this interface directly. * </p> - * + * * @since 1.0 * @see IInstructionWithSize */ public interface IInstruction { - /** - * @return the instruction address. - */ - BigInteger getAdress(); - - /** - * @return the function name. - */ - String getFuntionName(); - - /** - * @return the offset of this machine instruction - */ - long getOffset(); - - /** - * @return the instruction. - */ - String getInstruction(); - - /** - * @return the opcode - */ - String getOpcode(); - - /** - * @return any arguments to the instruction - */ - String getArgs(); + /** + * @return the instruction address. + */ + BigInteger getAdress(); + + /** + * @return the function name. + */ + String getFuntionName(); + + /** + * @return the offset of this machine instruction + */ + long getOffset(); + + /** + * @return the instruction. + */ + String getInstruction(); + + /** + * @return the opcode + */ + String getOpcode(); + + /** + * @return any arguments to the instruction + */ + String getArgs(); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IInstructionWithRawOpcodes.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IInstructionWithRawOpcodes.java index 6c35e3f79fd..f3f89b0b497 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IInstructionWithRawOpcodes.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IInstructionWithRawOpcodes.java @@ -21,7 +21,7 @@ import java.math.BigInteger; * Implementers must extend {@link AbstractInstruction} instead of implementing * this interface directly. * </p> - * + * * @since 2.5 * @noimplement This interface is not intended to be implemented by clients. * @noextend This interface is not intended to be extended by clients. diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IInstructionWithSize.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IInstructionWithSize.java index e829910196e..e264ff39c67 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IInstructionWithSize.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IInstructionWithSize.java @@ -28,9 +28,9 @@ import org.eclipse.cdt.dsf.debug.service.IInstruction; */ public interface IInstructionWithSize extends IInstruction { - /** - * @return size of the instruction in bytes or <code>null</code> if unknown - */ - Integer getSize(); + /** + * @return size of the instruction in bytes or <code>null</code> if unknown + */ + Integer getSize(); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMemory.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMemory.java index 0cf16e83966..f921f2f3b4e 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMemory.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMemory.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation * Ericsson AB - extended the API for IMemoryBlockExtension @@ -24,100 +24,101 @@ import org.eclipse.cdt.dsf.service.IDsfService; import org.eclipse.debug.core.model.MemoryByte; /** - * Service for accessing memory. Memory contexts are not meant to be + * Service for accessing memory. Memory contexts are not meant to be * represented in tree or table views, so it doesn't need to implement - * IDMService interface. - * + * IDMService interface. + * * @since 1.0 */ public interface IMemory extends IDsfService { - public interface IMemoryDMContext extends IDMContext {} + public interface IMemoryDMContext extends IDMContext { + } + + /** + * Event generated every time a range of bytes is modified. + * + * A client wishing to receive such events has to register as a service + * event listener and implement the corresponding eventDispatched method. + * + * E.g.: + * + * MyMemoryBlock(MIRunControl fRunControl) + * { + * ... + * fRunControl.getSession().addServiceEventListener(MyMemoryBlock.this, null); + * ... + * } + * + * @DsfServiceEventHandler + * public void eventDispatched(MemoryChangedEvent e) { + * IDMContext<?> context = e.getContext(); + * IAddress[] addresses = e.getAddresses(); + * // do whatever... + * } + */ + public interface IMemoryChangedEvent extends IDMEvent<IMemoryDMContext> { + IAddress[] getAddresses(); + } - /** - * Event generated every time a range of bytes is modified. - * - * A client wishing to receive such events has to register as a service - * event listener and implement the corresponding eventDispatched method. - * - * E.g.: - * - * MyMemoryBlock(MIRunControl fRunControl) - * { - * ... - * fRunControl.getSession().addServiceEventListener(MyMemoryBlock.this, null); - * ... - * } - * - * @DsfServiceEventHandler - * public void eventDispatched(MemoryChangedEvent e) { - * IDMContext<?> context = e.getContext(); - * IAddress[] addresses = e.getAddresses(); - * // do whatever... - * } - */ - public interface IMemoryChangedEvent extends IDMEvent<IMemoryDMContext> { - IAddress[] getAddresses(); - } - - /** - * Reads a memory block from the target. - * - * An asynchronous memory read request at [address] + [offset] for - * [count] memory items, each of size [word_size] bytes, will be - * issued to the target. The result will be stored in [drm] upon - * completion of the call. - * - * The [drm] result buffer will be of size [word_size] * [count]. The - * successfully read bytes will have their MemoryByte.READABLE flag - * set while the bytes in error (unreachable/bad memory) will have their - * flag byte set to 0. The bytes will respect the target "endianness". - * - * @param context the context of the target memory block - * @param address the memory block address (on the target) - * @param offset the offset from the start address - * @param word_size the size, in bytes, of an addressable item - * @param count the number of data elements to read - * @param drm the asynchronous data request monitor - */ - public void getMemory(IMemoryDMContext context, IAddress address, long offset, - int word_size, int count, DataRequestMonitor<MemoryByte[]> drm); + /** + * Reads a memory block from the target. + * + * An asynchronous memory read request at [address] + [offset] for + * [count] memory items, each of size [word_size] bytes, will be + * issued to the target. The result will be stored in [drm] upon + * completion of the call. + * + * The [drm] result buffer will be of size [word_size] * [count]. The + * successfully read bytes will have their MemoryByte.READABLE flag + * set while the bytes in error (unreachable/bad memory) will have their + * flag byte set to 0. The bytes will respect the target "endianness". + * + * @param context the context of the target memory block + * @param address the memory block address (on the target) + * @param offset the offset from the start address + * @param word_size the size, in bytes, of an addressable item + * @param count the number of data elements to read + * @param drm the asynchronous data request monitor + */ + public void getMemory(IMemoryDMContext context, IAddress address, long offset, int word_size, int count, + DataRequestMonitor<MemoryByte[]> drm); - /** - * Writes a memory block on the target. - * - * An asynchronous memory write request at [address] + [offset] for - * [count] * [word_size] bytes will be issued to the target. - * - * The [buffer] must hold at least [count] * [word_size] bytes. - * - * A MemoryChangedEvent will be generated for the range of addresses. - * - * @param context the context of the target memory block - * @param address the memory block address (on the target) - * @param offset the offset from the start address - * @param word_size the size, in bytes, of an addressable item - * @param count the number of data elements to write - * @param buffer the source buffer - * @param rm the asynchronous data request monitor - */ - public void setMemory(IMemoryDMContext context, IAddress address, long offset, - int word_size, int count, byte[] buffer, RequestMonitor rm); + /** + * Writes a memory block on the target. + * + * An asynchronous memory write request at [address] + [offset] for + * [count] * [word_size] bytes will be issued to the target. + * + * The [buffer] must hold at least [count] * [word_size] bytes. + * + * A MemoryChangedEvent will be generated for the range of addresses. + * + * @param context the context of the target memory block + * @param address the memory block address (on the target) + * @param offset the offset from the start address + * @param word_size the size, in bytes, of an addressable item + * @param count the number of data elements to write + * @param buffer the source buffer + * @param rm the asynchronous data request monitor + */ + public void setMemory(IMemoryDMContext context, IAddress address, long offset, int word_size, int count, + byte[] buffer, RequestMonitor rm); - /** - * Writes [pattern] at memory [address] + [offset], [count] times. - * - * A MemoryChangedEvent will be generated for the range of addresses. - * - * @param context the context of the target memory block - * @param address the memory block address (on the target) - * @param offset the offset from the start address - * @param word_size the size, in bytes, of an addressable item - * @param count the number of times [pattern] will be written - * @param pattern the source buffer - * @param rm the asynchronous data request monitor - */ - public void fillMemory(IMemoryDMContext context, IAddress address, long offset, - int word_size, int count, byte[] pattern, RequestMonitor rm); + /** + * Writes [pattern] at memory [address] + [offset], [count] times. + * + * A MemoryChangedEvent will be generated for the range of addresses. + * + * @param context the context of the target memory block + * @param address the memory block address (on the target) + * @param offset the offset from the start address + * @param word_size the size, in bytes, of an addressable item + * @param count the number of times [pattern] will be written + * @param pattern the source buffer + * @param rm the asynchronous data request monitor + */ + public void fillMemory(IMemoryDMContext context, IAddress address, long offset, int word_size, int count, + byte[] pattern, RequestMonitor rm); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMemorySpaces.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMemorySpaces.java index 118f4281f2d..ae3e682e5d7 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMemorySpaces.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMemorySpaces.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Texas Instruments, Freescale Semiconductor - initial API and implementation *******************************************************************************/ @@ -21,15 +21,15 @@ import org.eclipse.core.runtime.CoreException; /** * A memory service that is memory space aware. - * + * * <p> * Memory contexts are not meant to be represented in tree or table views, so it * doesn't need to implement IDMService interface. - * + * * @author Alain Lee and John Cortell * @since 2.1 */ -public interface IMemorySpaces extends IDsfService{ +public interface IMemorySpaces extends IDsfService { /** * A context that represents a particular memory space. Simple targets have @@ -37,11 +37,11 @@ public interface IMemorySpaces extends IDsfService{ * data, virtual, physical. */ public interface IMemorySpaceDMContext extends IMemoryDMContext { - + /** * The string-based handle used to refer to the memory space, as per * what's returned in - * {@link IMemorySpaces#getMemorySpaces(IDMContext, DataRequestMonitor) + * {@link IMemorySpaces#getMemorySpaces(IDMContext, DataRequestMonitor) */ public String getMemorySpaceId(); } @@ -52,7 +52,7 @@ public interface IMemorySpaces extends IDsfService{ * [memory-space-id]:[expression]. If this is adequate, the client can * return null from this method. This method is called when having to * represent a memory-space qualified address as a single string. - * + * * @param expression * the expression representing a location within a memory space. * This can be a simple numeric expression like "0x10000" or @@ -60,7 +60,7 @@ public interface IMemorySpaces extends IDsfService{ * @param memorySpaceID * a string which represents the memory space * @return the encoded string representation of the address, or null to - * indicate no custom encoding is required + * indicate no custom encoding is required */ String encodeAddress(String expression, String memorySpaceID); @@ -68,7 +68,7 @@ public interface IMemorySpaces extends IDsfService{ * The inverse of {@link #encodeAddress(String, String)}. Client should * provide decoding if it provides encoding. Conversely, it should not * provide decoding if it doesn't provide encoding. - * + * * @param str * the encoded string * @return the result of decoding the string into its components, or null to @@ -77,15 +77,16 @@ public interface IMemorySpaces extends IDsfService{ * if decoding and string is not in the expected format */ DecodeResult decodeAddress(String str) throws CoreException; - + interface DecodeResult { String getMemorySpaceId(); + String getExpression(); } /** * Provides the memory spaces available in the given context. - * + * * @param ctx * a context which might <i>contain</i> one or more memory * spaces. Contexts that may be <i>associated</i> with a memory @@ -98,7 +99,7 @@ public interface IMemorySpaces extends IDsfService{ * memory space IDs. Never null, but may be empty. */ void getMemorySpaces(IDMContext context, final DataRequestMonitor<String[]> rm); - + /** * Return true if creating a memory block with a null memory space ID is NOT * supported. Some debuggers may not have the ability to infer the memory @@ -107,23 +108,23 @@ public interface IMemorySpaces extends IDsfService{ */ public boolean creatingBlockRequiresMemorySpaceID(); - /** - * Provides the default memory space to be used in the given context. - * - * @param ctx - * a context which might <i>contain</i> one or more memory - * spaces. Contexts that may be <i>associated</i> with a memory - * space should not be passed in. E.g., an expression might be - * associated with a memory space, but it does not contain memory - * spaces, and is thus not an appropriate context for this - * method. - * @param rm - * the asynchronous data request monitor. Returns a memory space ID. - * Never null, but may be empty. - * @since 2.7 - */ - default void getDefaultMemorySpace(IDMContext context, final DataRequestMonitor<String> rm) { - rm.setData(""); //$NON-NLS-1$ - rm.done(); - } + /** + * Provides the default memory space to be used in the given context. + * + * @param ctx + * a context which might <i>contain</i> one or more memory + * spaces. Contexts that may be <i>associated</i> with a memory + * space should not be passed in. E.g., an expression might be + * associated with a memory space, but it does not contain memory + * spaces, and is thus not an appropriate context for this + * method. + * @param rm + * the asynchronous data request monitor. Returns a memory space ID. + * Never null, but may be empty. + * @since 2.7 + */ + default void getDefaultMemorySpace(IDMContext context, final DataRequestMonitor<String> rm) { + rm.setData(""); //$NON-NLS-1$ + rm.done(); + } } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMemorySpaces2.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMemorySpaces2.java index 2796fa1add1..37de558cfcc 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMemorySpaces2.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMemorySpaces2.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Anders Dahlberg (Ericsson) - Need additional API to extend support for memory spaces (Bug 431627) * Alvaro Sanchez-Leon (Ericsson AB) - Need additional API to extend support for memory spaces (Bug 431627) @@ -19,15 +19,15 @@ import org.eclipse.cdt.dsf.datamodel.IDMContext; /** * This extension allows the decoding of an expression with the help of the external debugger - * + * * @since 2.5 */ public interface IMemorySpaces2 extends IMemorySpaces { /** - * Provides the means to use the debugger backend to help with asynchronous + * Provides the means to use the debugger backend to help with asynchronous * resolution of memory space, expression pair from a single string expression - * + * */ public void decodeExpression(IDMContext context, String expression, DataRequestMonitor<DecodeResult> rm); diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMixedInstruction.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMixedInstruction.java index 0087667843c..5fa546345ec 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMixedInstruction.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMixedInstruction.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Ericsson - initial API and implementation *******************************************************************************/ @@ -16,24 +16,24 @@ package org.eclipse.cdt.dsf.debug.service; /** * Represents the assembly instruction(s) corresponding to a source line - * + * * @since 1.0 */ public interface IMixedInstruction { - /** - * @return the file name - */ - String getFileName(); - - /** - * @return the line Number. - */ - int getLineNumber(); - - /** - * @return the array of instruction. - */ - IInstruction[] getInstructions(); + /** + * @return the file name + */ + String getFileName(); + + /** + * @return the line Number. + */ + int getLineNumber(); + + /** + * @return the array of instruction. + */ + IInstruction[] getInstructions(); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IModules.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IModules.java index c98cdd5ef3a..19f1d6dc0b8 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IModules.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IModules.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ @@ -21,85 +21,101 @@ import org.eclipse.cdt.dsf.service.IDsfService; /** * Debugger service representing module handling logic of a debugger. - * + * * @since 1.0 */ public interface IModules extends IDsfService { - - /** - * Symbol context represents the space into which module symbols are loaded. - * Traditionally symbols are loaded in context of a process, but for other - * types of debugging, like kernel or no-OS debugging, it's useful to - * separate the concept of a symbol context from a process. - */ - public interface ISymbolDMContext extends IDMContext {} - - /** - * Module context represents a single module that is loaded. - */ - public interface IModuleDMContext extends IDMContext {} - - /** - * Event indicating a change in the symbol information for given context. - */ - public interface ModulesChangedDMEvent extends IDMEvent<ISymbolDMContext> {} - - /** - * Specific event identifying that a new module was loaded into a - * symbol context. - */ - public interface ModuleLoadedDMEvent extends ModulesChangedDMEvent { - /** Returns context of the module that was loaded */ - IModuleDMContext getLoadedModuleContext(); - } - - public interface ModuleUnloadedDMEvent extends ModulesChangedDMEvent { - /** Returns context of the module that was un-loaded */ - IModuleDMContext getUnloadedModuleContext(); - } - - /** Module information. */ - public interface IModuleDMData { - String getName(); - String getFile(); - long getTimeStamp(); - String getBaseAddress(); - String getToAddress(); - boolean isSymbolsLoaded(); - long getSize(); - } - - /** Line information about a particular address */ - public interface LineInfo { - IAddress getAddress(); - String getSourceFile(); - int getStartLine(); - int getStartColumn(); - int getEndLine(); - int getEndColumn(); - } - - /** Address information about a particular file/line */ - public interface AddressRange { - IAddress getStartAddress(); - IAddress getEndAddress(); - } - - void getModuleData(IModuleDMContext dmc, DataRequestMonitor<IModuleDMData> rm); - - /** - * Retrieves the list of modules loaded in given symbol context. - */ - void getModules(ISymbolDMContext symCtx, DataRequestMonitor<IModuleDMContext[]> rm); - - /** - * Calculates the line numbers corresponding to the given address. - */ - void calcLineInfo(ISymbolDMContext symCtx, IAddress address, DataRequestMonitor<LineInfo[]> rm); - - /** - * Calculates the addresses corresponding to the given source file location. - */ - void calcAddressInfo(ISymbolDMContext symCtx, String file, int line, int col, DataRequestMonitor<AddressRange[]> rm); + + /** + * Symbol context represents the space into which module symbols are loaded. + * Traditionally symbols are loaded in context of a process, but for other + * types of debugging, like kernel or no-OS debugging, it's useful to + * separate the concept of a symbol context from a process. + */ + public interface ISymbolDMContext extends IDMContext { + } + + /** + * Module context represents a single module that is loaded. + */ + public interface IModuleDMContext extends IDMContext { + } + + /** + * Event indicating a change in the symbol information for given context. + */ + public interface ModulesChangedDMEvent extends IDMEvent<ISymbolDMContext> { + } + + /** + * Specific event identifying that a new module was loaded into a + * symbol context. + */ + public interface ModuleLoadedDMEvent extends ModulesChangedDMEvent { + /** Returns context of the module that was loaded */ + IModuleDMContext getLoadedModuleContext(); + } + + public interface ModuleUnloadedDMEvent extends ModulesChangedDMEvent { + /** Returns context of the module that was un-loaded */ + IModuleDMContext getUnloadedModuleContext(); + } + + /** Module information. */ + public interface IModuleDMData { + String getName(); + + String getFile(); + + long getTimeStamp(); + + String getBaseAddress(); + + String getToAddress(); + + boolean isSymbolsLoaded(); + + long getSize(); + } + + /** Line information about a particular address */ + public interface LineInfo { + IAddress getAddress(); + + String getSourceFile(); + + int getStartLine(); + + int getStartColumn(); + + int getEndLine(); + + int getEndColumn(); + } + + /** Address information about a particular file/line */ + public interface AddressRange { + IAddress getStartAddress(); + + IAddress getEndAddress(); + } + + void getModuleData(IModuleDMContext dmc, DataRequestMonitor<IModuleDMData> rm); + + /** + * Retrieves the list of modules loaded in given symbol context. + */ + void getModules(ISymbolDMContext symCtx, DataRequestMonitor<IModuleDMContext[]> rm); + + /** + * Calculates the line numbers corresponding to the given address. + */ + void calcLineInfo(ISymbolDMContext symCtx, IAddress address, DataRequestMonitor<LineInfo[]> rm); + + /** + * Calculates the addresses corresponding to the given source file location. + */ + void calcAddressInfo(ISymbolDMContext symCtx, String file, int line, int col, + DataRequestMonitor<AddressRange[]> rm); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IModules2.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IModules2.java index 1c41b687848..ffc42018956 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IModules2.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IModules2.java @@ -21,31 +21,33 @@ import org.eclipse.cdt.dsf.datamodel.IDMEvent; * @since 2.6 */ public interface IModules2 extends IModules { - - /** - * Event indicating a change in the symbols of certain modules of the symbol context. - */ - public interface ISymbolsChangedDMEvent extends IDMEvent<ISymbolDMContext> { - public IModuleDMContext[] getModules(); - } - /** - * Indicates symbols were loaded for some modules. - */ - public interface ISymbolsLoadedDMEvent extends ISymbolsChangedDMEvent {} + /** + * Event indicating a change in the symbols of certain modules of the symbol context. + */ + public interface ISymbolsChangedDMEvent extends IDMEvent<ISymbolDMContext> { + public IModuleDMContext[] getModules(); + } - /** - * Indicates symbols were unloaded for some modules. - */ - public interface ISymbolsUnloadedDMEvent extends ISymbolsChangedDMEvent {} + /** + * Indicates symbols were loaded for some modules. + */ + public interface ISymbolsLoadedDMEvent extends ISymbolsChangedDMEvent { + } - /** - * Load symbols for all modules of the specified symbol context + /** + * Indicates symbols were unloaded for some modules. + */ + public interface ISymbolsUnloadedDMEvent extends ISymbolsChangedDMEvent { + } + + /** + * Load symbols for all modules of the specified symbol context */ void loadSymbolsForAllModules(ISymbolDMContext symCtx, RequestMonitor rm); - + /** - * Load symbols for the specified module + * Load symbols for the specified module */ void loadSymbols(IModuleDMContext dmc, RequestMonitor rm); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMultiDetach.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMultiDetach.java index 43a762e0ef3..f224bcc13cb 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMultiDetach.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMultiDetach.java @@ -26,33 +26,33 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext; */ public interface IMultiDetach { - /** - * Checks whether it is possible to detach the debugger from at least one - * of the specified processes. - * - * @param dmcs The contexts to detach the debugger from. Each context - * should have {@link IContainerDMContext} as an ancestor. - * @param rm Request monitor returning whether there is at least one context - * that can be detached from the debugger. - */ - void canDetachDebuggerFromSomeProcesses(IDMContext[] dmcs, DataRequestMonitor<Boolean> rm); + /** + * Checks whether it is possible to detach the debugger from at least one + * of the specified processes. + * + * @param dmcs The contexts to detach the debugger from. Each context + * should have {@link IContainerDMContext} as an ancestor. + * @param rm Request monitor returning whether there is at least one context + * that can be detached from the debugger. + */ + void canDetachDebuggerFromSomeProcesses(IDMContext[] dmcs, DataRequestMonitor<Boolean> rm); - /** - * Checks whether it is possible to detach the debugger from all of the specified processes. - * - * @param dmc The contexts to detach the debugger from. Each context - * should have {@link IContainerDMContext} as an ancestor. - * @param rm Request monitor returning whether all processes specified by the given contexts - * that can be detached from the debugger. - */ - void canDetachDebuggerFromAllProcesses(IDMContext[] dmcs, DataRequestMonitor<Boolean> rm); + /** + * Checks whether it is possible to detach the debugger from all of the specified processes. + * + * @param dmc The contexts to detach the debugger from. Each context + * should have {@link IContainerDMContext} as an ancestor. + * @param rm Request monitor returning whether all processes specified by the given contexts + * that can be detached from the debugger. + */ + void canDetachDebuggerFromAllProcesses(IDMContext[] dmcs, DataRequestMonitor<Boolean> rm); - /** - * Request to detach debugger from the specified processes. Only contexts - * that are in a state that can be detached will be affected, others will be ignored. - * - * @param dmc The contexts to detach the debugger from. Each context - * should have {@link IContainerDMContext} as an ancestor. - */ - void detachDebuggerFromProcesses(IDMContext[] dmcs, RequestMonitor rm); + /** + * Request to detach debugger from the specified processes. Only contexts + * that are in a state that can be detached will be affected, others will be ignored. + * + * @param dmc The contexts to detach the debugger from. Each context + * should have {@link IContainerDMContext} as an ancestor. + */ + void detachDebuggerFromProcesses(IDMContext[] dmcs, RequestMonitor rm); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMultiRunControl.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMultiRunControl.java index 068beb55def..6a2d354aa46 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMultiRunControl.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMultiRunControl.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Marc Khouzam (Ericsson) - initial API and implementation *******************************************************************************/ @@ -18,120 +18,119 @@ import org.eclipse.cdt.dsf.concurrent.RequestMonitor; /** * This interface provides the ability to perform run control operations on multiple contexts. - * + * * @see org.eclipse.cdt.dsf.debug.service.IRunControl - * + * * @since 2.3 */ -public interface IMultiRunControl extends IRunControl -{ - /** - * Check if at least one of the specified contexts can be resumed - * @param context List of execution contexts that want to be resumed - * @param rm Request monitor returning: - * true if at least one of the specified contexts can be resumed - * false if none of the specified contexts can be resumed - */ - void canResumeSome(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm); - - /** - * Check if all of the specified contexts can be resumed - * @param context List of execution contexts that want to be resumed - * @param rm Request monitor returning: - * true if all of the specified contexts can be resumed - * false if any of the specified contexts cannot be resumed - */ - void canResumeAll(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm); +public interface IMultiRunControl extends IRunControl { + /** + * Check if at least one of the specified contexts can be resumed + * @param context List of execution contexts that want to be resumed + * @param rm Request monitor returning: + * true if at least one of the specified contexts can be resumed + * false if none of the specified contexts can be resumed + */ + void canResumeSome(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm); + + /** + * Check if all of the specified contexts can be resumed + * @param context List of execution contexts that want to be resumed + * @param rm Request monitor returning: + * true if all of the specified contexts can be resumed + * false if any of the specified contexts cannot be resumed + */ + void canResumeAll(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm); + + /** + * Check if at least one of the specified contexts can be suspended + * @param context List of execution contexts that want to be suspended + * @param rm Request monitor returning: + * true if at least one of the specified contexts can be suspended + * false if none of the specified contexts can be suspended + */ + void canSuspendSome(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm); + + /** + * Check if all of the specified contexts can be suspended + * @param context List of execution contexts that want to be suspended + * @param rm Request monitor returning: + * true if all of the specified contexts can be suspended + * false if any of the specified contexts cannot be suspended + */ + void canSuspendAll(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm); - /** - * Check if at least one of the specified contexts can be suspended - * @param context List of execution contexts that want to be suspended - * @param rm Request monitor returning: - * true if at least one of the specified contexts can be suspended - * false if none of the specified contexts can be suspended - */ - void canSuspendSome(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm); - - /** - * Check if all of the specified contexts can be suspended - * @param context List of execution contexts that want to be suspended - * @param rm Request monitor returning: - * true if all of the specified contexts can be suspended - * false if any of the specified contexts cannot be suspended - */ - void canSuspendAll(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm); + /** + * Check if any of the specified contexts is suspended. + * @param context List of execution contexts that are to be checked for being suspended + * @param rm Request monitor returning: + * true if any of the specified contexts is suspended, false otherwise + */ + void isSuspendedSome(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm); - /** - * Check if any of the specified contexts is suspended. - * @param context List of execution contexts that are to be checked for being suspended - * @param rm Request monitor returning: - * true if any of the specified contexts is suspended, false otherwise - */ - void isSuspendedSome(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm); + /** + * Check if all of the specified contexts are suspended. + * @param context List of execution contexts that are to be checked for being suspended + * @param rm Request monitor returning: + * true if all of the specified contexts are suspended, false otherwise + */ + void isSuspendedAll(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm); - /** - * Check if all of the specified contexts are suspended. - * @param context List of execution contexts that are to be checked for being suspended - * @param rm Request monitor returning: - * true if all of the specified contexts are suspended, false otherwise - */ - void isSuspendedAll(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm); - - /** - * Check if any of the specified contexts can be stepped using stepType - * @param context List of execution contexts that want to be stepped - * @param stepStype The type of step to be used. - * @param rm Request monitor returning: - * true if any of the specified contexts can be stepped - * false if none of the specified contexts can be stepped - */ - void canStepSome(IExecutionDMContext[] contexts, StepType stepType, DataRequestMonitor<Boolean> rm); + /** + * Check if any of the specified contexts can be stepped using stepType + * @param context List of execution contexts that want to be stepped + * @param stepStype The type of step to be used. + * @param rm Request monitor returning: + * true if any of the specified contexts can be stepped + * false if none of the specified contexts can be stepped + */ + void canStepSome(IExecutionDMContext[] contexts, StepType stepType, DataRequestMonitor<Boolean> rm); - /** - * Check if all of the specified contexts can be stepped using stepType - * @param context List of execution contexts that want to be stepped - * @param stepStype The type of step to be used. - * @param rm Request monitor returning: - * true if all of the specified contexts can be stepped - * false if any of the specified contexts cannot be stepped - */ - void canStepAll(IExecutionDMContext[] contexts, StepType stepType, DataRequestMonitor<Boolean> rm); + /** + * Check if all of the specified contexts can be stepped using stepType + * @param context List of execution contexts that want to be stepped + * @param stepStype The type of step to be used. + * @param rm Request monitor returning: + * true if all of the specified contexts can be stepped + * false if any of the specified contexts cannot be stepped + */ + void canStepAll(IExecutionDMContext[] contexts, StepType stepType, DataRequestMonitor<Boolean> rm); - /** - * Check if any of the specified contexts is currently stepping. - * @param context List of execution contexts that are to be checked for stepping - * @param rm Request monitor returning: - * true if any of the specified contexts is stepping, false otherwise - */ - void isSteppingSome(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm); + /** + * Check if any of the specified contexts is currently stepping. + * @param context List of execution contexts that are to be checked for stepping + * @param rm Request monitor returning: + * true if any of the specified contexts is stepping, false otherwise + */ + void isSteppingSome(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm); - /** - * Check if all of the specified contexts are currently stepping. - * @param context List of execution contexts that are to be checked for stepping - * @param rm Request monitor returning: - * true if all of the specified contexts are stepping, false otherwise - */ - void isSteppingAll(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm); + /** + * Check if all of the specified contexts are currently stepping. + * @param context List of execution contexts that are to be checked for stepping + * @param rm Request monitor returning: + * true if all of the specified contexts are stepping, false otherwise + */ + void isSteppingAll(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm); - /** - * Request that all specified contexts be resumed. Only contexts that are in a - * state that can be resumed will be affected, others will be ignored. - * @param context List of execution contexts that are to be resumed - */ - void resume(IExecutionDMContext[] contexts, RequestMonitor rm); + /** + * Request that all specified contexts be resumed. Only contexts that are in a + * state that can be resumed will be affected, others will be ignored. + * @param context List of execution contexts that are to be resumed + */ + void resume(IExecutionDMContext[] contexts, RequestMonitor rm); - /** - * Request that all specified contexts be suspended. Only contexts that are in a - * state that can be suspended will be affected, others will be ignored. - * @param context List of execution contexts that are to be suspended - */ - void suspend(IExecutionDMContext[] contexts, RequestMonitor rm); + /** + * Request that all specified contexts be suspended. Only contexts that are in a + * state that can be suspended will be affected, others will be ignored. + * @param context List of execution contexts that are to be suspended + */ + void suspend(IExecutionDMContext[] contexts, RequestMonitor rm); - /** - * Request that all specified context be stepped using stepType. Only contexts - * that are in a state that can be stepped will be affected, others will be ignored. - * @param context List of execution contexts that are to be stepped - * @param stepStype The type of step to be used. - */ - void step(IExecutionDMContext[] contexts, StepType stepType, RequestMonitor rm); + /** + * Request that all specified context be stepped using stepType. Only contexts + * that are in a state that can be stepped will be affected, others will be ignored. + * @param context List of execution contexts that are to be stepped + * @param stepStype The type of step to be used. + */ + void step(IExecutionDMContext[] contexts, StepType stepType, RequestMonitor rm); }
\ No newline at end of file diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMultiTerminate.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMultiTerminate.java index 6ba8479611c..75be687b87c 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMultiTerminate.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IMultiTerminate.java @@ -20,33 +20,33 @@ import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext; /** * This interface provides the ability to perform terminate on multiple contexts. - * + * * @since 2.6 */ public interface IMultiTerminate { - /** - * Checks whether it is possible to terminate at least one of the specified threads - * or processes. - * - * @param dmcs The contexts of the threads to terminate - * @param rm Request monitor returning whether there is at least one thread or process can be terminated. - */ - void canTerminateSome(IThreadDMContext[] dmcs, DataRequestMonitor<Boolean> rm); + /** + * Checks whether it is possible to terminate at least one of the specified threads + * or processes. + * + * @param dmcs The contexts of the threads to terminate + * @param rm Request monitor returning whether there is at least one thread or process can be terminated. + */ + void canTerminateSome(IThreadDMContext[] dmcs, DataRequestMonitor<Boolean> rm); - /** - * Checks whether it is possible to terminate all of the specified threads or processes. - * - * @param dmcs The contexts of the threads or processes to terminate - * @param rm Request monitor returning whether all of the threads can be terminated. - */ - void canTerminateAll(IThreadDMContext[] dmcs, DataRequestMonitor<Boolean> rm); + /** + * Checks whether it is possible to terminate all of the specified threads or processes. + * + * @param dmcs The contexts of the threads or processes to terminate + * @param rm Request monitor returning whether all of the threads can be terminated. + */ + void canTerminateAll(IThreadDMContext[] dmcs, DataRequestMonitor<Boolean> rm); - /** - * Request to terminate the specified threads or processes. Only threads and processes - * that can be terminated will be affected, others will be ignored. - * - * @param dmc The contexts of the threads or processes to terminate. - */ - void terminate(IThreadDMContext[] dmcs, RequestMonitor rm); + /** + * Request to terminate the specified threads or processes. Only threads and processes + * that can be terminated will be affected, others will be ignored. + * + * @param dmc The contexts of the threads or processes to terminate. + */ + void terminate(IThreadDMContext[] dmcs, RequestMonitor rm); }
\ No newline at end of file diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IProcesses.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IProcesses.java index 600f77659a9..d7861b24f19 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IProcesses.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IProcesses.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation * Ericsson - Updated for latest DSF version @@ -24,162 +24,163 @@ import org.eclipse.cdt.dsf.datamodel.IDMEvent; import org.eclipse.cdt.dsf.service.IDsfService; /** - * This interface provides access to the OS's process + * This interface provides access to the OS's process * information, manipulation methods, and debugging methods. - * This service provides a relatively simple interface for + * This service provides a relatively simple interface for * manipulating processes as compared with a full-blown - * remote target debugger. - * + * remote target debugger. + * * @since 1.1 */ public interface IProcesses extends IDsfService { - + /** * A thread as known by the OS. * This context is kept different than {@link IRunControl.IExecutionDMContext} * because the OS id of a thread may not be the same as the thread id used by * the debugger when doing run control operations. */ - public interface IThreadDMContext extends IDMContext {} - - /** + public interface IThreadDMContext extends IDMContext { + } + + /** * A process as known by the OS. * This context is kept different than {@link IRunControl.IContainerDMContext} * because the OS id of a process may not be the same as the process id used by * the debugger when doing run control operations. */ - public interface IProcessDMContext extends IThreadDMContext {} - - /** - * Interface for thread and process object data. This data provides a link - * to the lower level debugger services, in form of execution contexts. - */ - public interface IThreadDMData extends IDMData { - String getName(); - String getId(); - boolean isDebuggerAttached(); - } - - /** - * Event indicating that process data has changed. - */ - public interface ProcessChangedDMEvent extends IDMEvent<IProcessDMContext> {} - - /** - * Retrieves thread or process data for given context. - * @param dmc Context to retrieve data for. - * @param rm Request completion monitor. - */ - public void getExecutionData(IThreadDMContext dmc, DataRequestMonitor<IThreadDMData> rm); - - /** - * Retrieves the debugging context that characterizes the specified thread - * or process context. - * - * @param dmc The thread or process dmc for which we want the debugging context - * @param rm The request monitor that will contain the debugging context. - * null if no such context exists - */ - public void getDebuggingContext(IThreadDMContext dmc, DataRequestMonitor<IDMContext> rm); - - /** - * Retrieves the current list of processes running on target. - * @param dmc The processor or core for which to list all processes - * @param rm Request completion monitor, to be filled in with array of process contexts. - */ - void getRunningProcesses(IDMContext dmc, DataRequestMonitor<IProcessDMContext[]> rm); - - /** - * Checks whether it is possible to attach the debugger to a new process. - * @param dmc The processor or core on which we want to attach to a process. - * @param rm Return if it is possible to attach. - */ - void isDebuggerAttachSupported(IDMContext dmc, DataRequestMonitor<Boolean> rm); - - /** - * Attaches debugger to the given process. - * When attaching to a process, a debugging context can now be used to characterize the process. - * This method can optionally choose to return this IDMContext inside the DataRequestMonitor. - * This can be useful for backends that do not have the ability to obtain the different - * debugging IDMContexts through {@link #getProcessesBeingDebugged(IDMContext, DataRequestMonitor) - */ - void attachDebuggerToProcess(IProcessDMContext procCtx, DataRequestMonitor<IDMContext> rm); - - /** - * Checks whether it is possible to detach the debugger from the specified process. - * @param dmc The debugging context from which we want to detach. This context - * should have IProcessDMContext as an ancestor. - * @param rm Return if it is possible to detach. - */ - void canDetachDebuggerFromProcess(IDMContext dmc, DataRequestMonitor<Boolean> rm); - - /** - * Detaches debugger from the given process. - * @param dmc The debugging context from which we want to detach. This context - * should have IProcessDMContext as an ancestor. - */ - void detachDebuggerFromProcess(IDMContext dmc, RequestMonitor requestMonitor); - - /** - * Checks whether it is possible to run a new process. - * @param dmc The processor or core on which we want to run a new process. - * @param rm Return if it is possible to run a new process. - */ - void isRunNewProcessSupported(IDMContext dmc, DataRequestMonitor<Boolean> rm); - - /** - * Starts a new process. - * @param dmc The processor or core on which we want to run a new process. - * @param file Process image to use for the new process. - * @param attributes Attributes that give information on the process to be debugged - * @param rm Request completion monitor, to be filled in with the process context. - */ - void runNewProcess(IDMContext dmc, - String file, - Map<String, Object> attributes, - DataRequestMonitor<IProcessDMContext> rm); - - /** - * Checks whether it is possible to start a new process with the debugger attached - * @param dmc The processor or core on which we want to start and debug the new process. - * @param rm Return if it is possible to start a new process with the debugger attached. - */ - void isDebugNewProcessSupported(IDMContext dmc, DataRequestMonitor<Boolean> rm); - - /** - * Starts a new process with the debugger attached. - * @param dmc The processor or core on which we want to start and debug the new process. - * @param file Process image to use for the new process. - * @param attributes Attributes that give information on the process to be debugged - * @param rm Request completion monitor, to be filled in with the - * debugging context that can now be used to characterize the process - */ - void debugNewProcess(IDMContext dmc, - String file, - Map<String, Object> attributes, - DataRequestMonitor<IDMContext> rm); - - /** - * Retrieves the list of processes which are currently under debugger control. - * - * @param dmc The processor or core for which to list processes being debugged - * @param rm Request completion monitor which contains all debugging contexts representing - * the processes being debugged. Note that each of these contexts should also have - * IProcessDMContext as a parent. - */ - void getProcessesBeingDebugged(IDMContext dmc, DataRequestMonitor<IDMContext[]> rm); - - /** - * Checks whether the given process or thread can be terminated. - * @param thread Thread or process to terminate. - * @param rm Return token. - */ - void canTerminate(IThreadDMContext thread, DataRequestMonitor<Boolean> rm); - - /** - * Terminates the selected process or thread. - * @param thread Thread or process to terminate. - * @param rm Request completion monitor, indicates success or failure. - */ - void terminate(IThreadDMContext thread, RequestMonitor requestMonitor); + public interface IProcessDMContext extends IThreadDMContext { + } + + /** + * Interface for thread and process object data. This data provides a link + * to the lower level debugger services, in form of execution contexts. + */ + public interface IThreadDMData extends IDMData { + String getName(); + + String getId(); + + boolean isDebuggerAttached(); + } + + /** + * Event indicating that process data has changed. + */ + public interface ProcessChangedDMEvent extends IDMEvent<IProcessDMContext> { + } + + /** + * Retrieves thread or process data for given context. + * @param dmc Context to retrieve data for. + * @param rm Request completion monitor. + */ + public void getExecutionData(IThreadDMContext dmc, DataRequestMonitor<IThreadDMData> rm); + + /** + * Retrieves the debugging context that characterizes the specified thread + * or process context. + * + * @param dmc The thread or process dmc for which we want the debugging context + * @param rm The request monitor that will contain the debugging context. + * null if no such context exists + */ + public void getDebuggingContext(IThreadDMContext dmc, DataRequestMonitor<IDMContext> rm); + + /** + * Retrieves the current list of processes running on target. + * @param dmc The processor or core for which to list all processes + * @param rm Request completion monitor, to be filled in with array of process contexts. + */ + void getRunningProcesses(IDMContext dmc, DataRequestMonitor<IProcessDMContext[]> rm); + + /** + * Checks whether it is possible to attach the debugger to a new process. + * @param dmc The processor or core on which we want to attach to a process. + * @param rm Return if it is possible to attach. + */ + void isDebuggerAttachSupported(IDMContext dmc, DataRequestMonitor<Boolean> rm); + + /** + * Attaches debugger to the given process. + * When attaching to a process, a debugging context can now be used to characterize the process. + * This method can optionally choose to return this IDMContext inside the DataRequestMonitor. + * This can be useful for backends that do not have the ability to obtain the different + * debugging IDMContexts through {@link #getProcessesBeingDebugged(IDMContext, DataRequestMonitor) + */ + void attachDebuggerToProcess(IProcessDMContext procCtx, DataRequestMonitor<IDMContext> rm); + + /** + * Checks whether it is possible to detach the debugger from the specified process. + * @param dmc The debugging context from which we want to detach. This context + * should have IProcessDMContext as an ancestor. + * @param rm Return if it is possible to detach. + */ + void canDetachDebuggerFromProcess(IDMContext dmc, DataRequestMonitor<Boolean> rm); + + /** + * Detaches debugger from the given process. + * @param dmc The debugging context from which we want to detach. This context + * should have IProcessDMContext as an ancestor. + */ + void detachDebuggerFromProcess(IDMContext dmc, RequestMonitor requestMonitor); + + /** + * Checks whether it is possible to run a new process. + * @param dmc The processor or core on which we want to run a new process. + * @param rm Return if it is possible to run a new process. + */ + void isRunNewProcessSupported(IDMContext dmc, DataRequestMonitor<Boolean> rm); + + /** + * Starts a new process. + * @param dmc The processor or core on which we want to run a new process. + * @param file Process image to use for the new process. + * @param attributes Attributes that give information on the process to be debugged + * @param rm Request completion monitor, to be filled in with the process context. + */ + void runNewProcess(IDMContext dmc, String file, Map<String, Object> attributes, + DataRequestMonitor<IProcessDMContext> rm); + + /** + * Checks whether it is possible to start a new process with the debugger attached + * @param dmc The processor or core on which we want to start and debug the new process. + * @param rm Return if it is possible to start a new process with the debugger attached. + */ + void isDebugNewProcessSupported(IDMContext dmc, DataRequestMonitor<Boolean> rm); + + /** + * Starts a new process with the debugger attached. + * @param dmc The processor or core on which we want to start and debug the new process. + * @param file Process image to use for the new process. + * @param attributes Attributes that give information on the process to be debugged + * @param rm Request completion monitor, to be filled in with the + * debugging context that can now be used to characterize the process + */ + void debugNewProcess(IDMContext dmc, String file, Map<String, Object> attributes, + DataRequestMonitor<IDMContext> rm); + + /** + * Retrieves the list of processes which are currently under debugger control. + * + * @param dmc The processor or core for which to list processes being debugged + * @param rm Request completion monitor which contains all debugging contexts representing + * the processes being debugged. Note that each of these contexts should also have + * IProcessDMContext as a parent. + */ + void getProcessesBeingDebugged(IDMContext dmc, DataRequestMonitor<IDMContext[]> rm); + + /** + * Checks whether the given process or thread can be terminated. + * @param thread Thread or process to terminate. + * @param rm Return token. + */ + void canTerminate(IThreadDMContext thread, DataRequestMonitor<Boolean> rm); + + /** + * Terminates the selected process or thread. + * @param thread Thread or process to terminate. + * @param rm Request completion monitor, indicates success or failure. + */ + void terminate(IThreadDMContext thread, RequestMonitor requestMonitor); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IRegisters.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IRegisters.java index 2c7c46c7035..275816bbe66 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IRegisters.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IRegisters.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ @@ -21,193 +21,218 @@ import org.eclipse.cdt.dsf.datamodel.IDMEvent; /** * Service for accessing register data. - * + * * @since 1.0 */ public interface IRegisters extends IFormattedValues { - - /** - * Event indicating groups have changed. The type of context returned by this - * event is generic, because different implementations of the the register service - * could configure register groups using different contexts. Some implementations - * could configure different register groups for each execution context, other - * services may have a global list of groups. - */ - public interface IGroupsChangedDMEvent extends IDMEvent<IDMContext> {} - - /** Register group context */ - public interface IRegisterGroupDMContext extends IFormattedDataDMContext { - } - - /** Event indicating values for the group have changed. */ - public interface IGroupChangedDMEvent extends IDMEvent<IRegisterGroupDMContext> {} - - /** Event indicating registers in a group have changed. */ - public interface IRegistersChangedDMEvent extends IDMEvent<IRegisterGroupDMContext> {} - - /** - * Register groups only have a name and description. Sub groups and registers are - * retrieved through the service interface. - */ - public interface IRegisterGroupDMData extends IDMData { - public String getName(); - public String getDescription(); - } - - /** Register context */ - public interface IRegisterDMContext extends IFormattedDataDMContext { - } - - /** Event indicating register value changed. */ - public interface IRegisterChangedDMEvent extends IDMEvent<IRegisterDMContext> {} - - /** Register information */ - public interface IRegisterDMData extends IDMData { - String getName(); - String getDescription(); - boolean isReadable(); - boolean isReadOnce(); - boolean isWriteable(); - boolean isWriteOnce(); - boolean hasSideEffects(); - boolean isVolatile(); - boolean isFloat(); - } - - /** Bit field context */ - public interface IBitFieldDMContext extends IFormattedDataDMContext { - } - - /** Event indicating register value changed. */ - public interface IBitFieldChangedDMEvent extends IDMEvent<IBitFieldDMContext> {} - - /** - * Bitfield data, big groups and mnemonics are retrieved at the same - * time as rest of bit field data - */ - public interface IBitFieldDMData extends IDMData { - String getName(); - String getDescription(); - boolean isReadable(); - boolean isReadOnce(); - boolean isWriteable(); - boolean isWriteOnce(); - boolean hasSideEffects(); - boolean isZeroBasedNumbering(); - boolean isZeroBitLeftMost(); - IBitGroup[] getBitGroup(); - IMnemonic[] getMnemonics(); - IMnemonic getCurrentMnemonicValue(); - } - - /** Bit group definition */ - public interface IBitGroup { - int startBit(); - int bitCount(); - } - - /** Bit field mnemonic */ - public interface IMnemonic { - String getShortName(); - String getLongName(); - } - - /** - * Retrieves the list of register groups. - * @param ctx Context for the returned data. - * @param rm Request completion monitor. - */ - void getRegisterGroups(IDMContext ctx, DataRequestMonitor<IRegisterGroupDMContext[]> rm); - - /** - * Retrieves the list of registers for the given context. The given context could include - * a register group and an execution context or just an execution context, in which case all - * registers for all groups should be returned. - * @param ctx Context for the returned data. - * @param rm Request completion monitor. - */ - void getRegisters(IDMContext ctx, DataRequestMonitor<IRegisterDMContext[]> rm); - - /** - * Retrieves bit fields for given register - * @param ctx Context for the returned data. - * @param rm Request completion monitor. - */ - void getBitFields(IDMContext ctx, DataRequestMonitor<IBitFieldDMContext[]> rm); - - /** - * Retrieves a Register Group context. The given context could include a register - * group and an execution context or just an execution context. - * @param ctx Context for the returned data. - * @param name Name of group being requested - * @param rm Request completion monitor. - */ - void findRegisterGroup(IDMContext ctx, String name, DataRequestMonitor<IRegisterGroupDMContext> rm); - - /** - * Retrieves a Register context. The given context could include a register group and an execution - * context or just an execution context. - * @param ctx Context for the returned data. - * @param name Name of register being requested - * @param rm Request completion monitor. - */ - void findRegister(IDMContext ctx, String name, DataRequestMonitor<IRegisterDMContext> rm); - - /** - * Retrieves bit field context. The given context could include a register and an execution - * context or just an execution context. - * @param ctx Context for the returned data. - * @param name Name of bit field being requested - * @param rm Request completion monitor. - */ - void findBitField(IDMContext ctx, String name, DataRequestMonitor<IBitFieldDMContext> rm); - - /** - * Retrieves register group data for given context. - * @param dmc Context to retrieve data for. - * @param rm Request completion monitor. - */ - void getRegisterGroupData(IRegisterGroupDMContext dmc, DataRequestMonitor<IRegisterGroupDMData> rm); - - /** - * Retrieves register data for given context. - * @param dmc Context to retrieve data for. - * @param rm Request completion monitor. - */ - void getRegisterData(IRegisterDMContext dmc , DataRequestMonitor<IRegisterDMData> rm); - - /** - * Retrieves bit field data for given context. - * @param dmc Context to retrieve data for. - * @param rm Request completion monitor. - */ - void getBitFieldData(IBitFieldDMContext dmc , DataRequestMonitor<IBitFieldDMData> rm); - - - - /** - * Writes a register value for a given register to the target - * @param regCtx Context containing the register. - * @param regValue Value of the register to be written. - * @param formatId Format of the value to be written. - * @param rm Request completion monitor. - */ - void writeRegister(IRegisterDMContext regCtx, String regValue, String formatId, RequestMonitor rm); - - /** - * Writes a bit field value for a given bit field to the target - * @param bitFieldCtx Context containing the bit field. - * @param bitFieldValue Value of the bit field to be written. - * @param formatId Format of the value to be written. - * @param rm Request completion monitor. - */ - void writeBitField(IBitFieldDMContext bitFieldCtx, String bitFieldValue, String formatId, RequestMonitor rm); - - /** - * Writes a bit field value for a given bit field to the target - * @param bitFieldCtx Context containing the bit field. - * @param mnemonic Mnemonic which represents the value to be written. - * @param rm Request completion monitor. - */ - void writeBitField(IBitFieldDMContext bitFieldCtx, IMnemonic mnemonic, RequestMonitor rm); + + /** + * Event indicating groups have changed. The type of context returned by this + * event is generic, because different implementations of the the register service + * could configure register groups using different contexts. Some implementations + * could configure different register groups for each execution context, other + * services may have a global list of groups. + */ + public interface IGroupsChangedDMEvent extends IDMEvent<IDMContext> { + } + + /** Register group context */ + public interface IRegisterGroupDMContext extends IFormattedDataDMContext { + } + + /** Event indicating values for the group have changed. */ + public interface IGroupChangedDMEvent extends IDMEvent<IRegisterGroupDMContext> { + } + + /** Event indicating registers in a group have changed. */ + public interface IRegistersChangedDMEvent extends IDMEvent<IRegisterGroupDMContext> { + } + + /** + * Register groups only have a name and description. Sub groups and registers are + * retrieved through the service interface. + */ + public interface IRegisterGroupDMData extends IDMData { + public String getName(); + + public String getDescription(); + } + + /** Register context */ + public interface IRegisterDMContext extends IFormattedDataDMContext { + } + + /** Event indicating register value changed. */ + public interface IRegisterChangedDMEvent extends IDMEvent<IRegisterDMContext> { + } + + /** Register information */ + public interface IRegisterDMData extends IDMData { + String getName(); + + String getDescription(); + + boolean isReadable(); + + boolean isReadOnce(); + + boolean isWriteable(); + + boolean isWriteOnce(); + + boolean hasSideEffects(); + + boolean isVolatile(); + + boolean isFloat(); + } + + /** Bit field context */ + public interface IBitFieldDMContext extends IFormattedDataDMContext { + } + + /** Event indicating register value changed. */ + public interface IBitFieldChangedDMEvent extends IDMEvent<IBitFieldDMContext> { + } + + /** + * Bitfield data, big groups and mnemonics are retrieved at the same + * time as rest of bit field data + */ + public interface IBitFieldDMData extends IDMData { + String getName(); + + String getDescription(); + + boolean isReadable(); + + boolean isReadOnce(); + + boolean isWriteable(); + + boolean isWriteOnce(); + + boolean hasSideEffects(); + + boolean isZeroBasedNumbering(); + + boolean isZeroBitLeftMost(); + + IBitGroup[] getBitGroup(); + + IMnemonic[] getMnemonics(); + + IMnemonic getCurrentMnemonicValue(); + } + + /** Bit group definition */ + public interface IBitGroup { + int startBit(); + + int bitCount(); + } + + /** Bit field mnemonic */ + public interface IMnemonic { + String getShortName(); + + String getLongName(); + } + + /** + * Retrieves the list of register groups. + * @param ctx Context for the returned data. + * @param rm Request completion monitor. + */ + void getRegisterGroups(IDMContext ctx, DataRequestMonitor<IRegisterGroupDMContext[]> rm); + + /** + * Retrieves the list of registers for the given context. The given context could include + * a register group and an execution context or just an execution context, in which case all + * registers for all groups should be returned. + * @param ctx Context for the returned data. + * @param rm Request completion monitor. + */ + void getRegisters(IDMContext ctx, DataRequestMonitor<IRegisterDMContext[]> rm); + + /** + * Retrieves bit fields for given register + * @param ctx Context for the returned data. + * @param rm Request completion monitor. + */ + void getBitFields(IDMContext ctx, DataRequestMonitor<IBitFieldDMContext[]> rm); + + /** + * Retrieves a Register Group context. The given context could include a register + * group and an execution context or just an execution context. + * @param ctx Context for the returned data. + * @param name Name of group being requested + * @param rm Request completion monitor. + */ + void findRegisterGroup(IDMContext ctx, String name, DataRequestMonitor<IRegisterGroupDMContext> rm); + + /** + * Retrieves a Register context. The given context could include a register group and an execution + * context or just an execution context. + * @param ctx Context for the returned data. + * @param name Name of register being requested + * @param rm Request completion monitor. + */ + void findRegister(IDMContext ctx, String name, DataRequestMonitor<IRegisterDMContext> rm); + + /** + * Retrieves bit field context. The given context could include a register and an execution + * context or just an execution context. + * @param ctx Context for the returned data. + * @param name Name of bit field being requested + * @param rm Request completion monitor. + */ + void findBitField(IDMContext ctx, String name, DataRequestMonitor<IBitFieldDMContext> rm); + + /** + * Retrieves register group data for given context. + * @param dmc Context to retrieve data for. + * @param rm Request completion monitor. + */ + void getRegisterGroupData(IRegisterGroupDMContext dmc, DataRequestMonitor<IRegisterGroupDMData> rm); + + /** + * Retrieves register data for given context. + * @param dmc Context to retrieve data for. + * @param rm Request completion monitor. + */ + void getRegisterData(IRegisterDMContext dmc, DataRequestMonitor<IRegisterDMData> rm); + + /** + * Retrieves bit field data for given context. + * @param dmc Context to retrieve data for. + * @param rm Request completion monitor. + */ + void getBitFieldData(IBitFieldDMContext dmc, DataRequestMonitor<IBitFieldDMData> rm); + + /** + * Writes a register value for a given register to the target + * @param regCtx Context containing the register. + * @param regValue Value of the register to be written. + * @param formatId Format of the value to be written. + * @param rm Request completion monitor. + */ + void writeRegister(IRegisterDMContext regCtx, String regValue, String formatId, RequestMonitor rm); + + /** + * Writes a bit field value for a given bit field to the target + * @param bitFieldCtx Context containing the bit field. + * @param bitFieldValue Value of the bit field to be written. + * @param formatId Format of the value to be written. + * @param rm Request completion monitor. + */ + void writeBitField(IBitFieldDMContext bitFieldCtx, String bitFieldValue, String formatId, RequestMonitor rm); + + /** + * Writes a bit field value for a given bit field to the target + * @param bitFieldCtx Context containing the bit field. + * @param mnemonic Mnemonic which represents the value to be written. + * @param rm Request completion monitor. + */ + void writeBitField(IBitFieldDMContext bitFieldCtx, IMnemonic mnemonic, RequestMonitor rm); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IRegisters2.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IRegisters2.java index 35f634e8a8f..5e8732d8980 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IRegisters2.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IRegisters2.java @@ -25,14 +25,14 @@ import org.eclipse.cdt.dsf.datamodel.IDMContext; public interface IRegisters2 extends IRegisters { /** * Returns a boolean indicating if it is allowed to add a new register group with the given selected context - * + * * @param rm - monitor encapsulating the response */ public void canAddRegisterGroup(IDMContext ctx, DataRequestMonitor<Boolean> rm); /** * Add a Register group referencing the given registers - * + * * @param ctx - A context containing a parent group context e.g. IContainerDMContext * @param name - register group name * @param registers - registers part of this new group @@ -42,34 +42,32 @@ public interface IRegisters2 extends IRegisters { /** * Returns a boolean indicating if it is allowed to edit the given group - * + * * @param rm - monitor encapsulating the response */ - public void canEditRegisterGroup(IRegisterGroupDMContext group, - DataRequestMonitor<Boolean> rm); + public void canEditRegisterGroup(IRegisterGroupDMContext group, DataRequestMonitor<Boolean> rm); /** * Edit the given register group and update its name and associated registers - * + * * @param group - group to be edited * @param groupName - new group name or null if name is not to be changed * @param registers - new list of registers for this group or null if the list of registers is not be changed * @param rm - request monitor */ - public void editRegisterGroup(IRegisterGroupDMContext group, String groupName, - IRegisterDMContext[] registers, RequestMonitor rm); + public void editRegisterGroup(IRegisterGroupDMContext group, String groupName, IRegisterDMContext[] registers, + RequestMonitor rm); /** * Returns a boolean indicating if it is allowed to remove the given registers groups * @param groups - list of register group contexts to be removed * @param rm */ - public void canRemoveRegisterGroups(IRegisterGroupDMContext[] groups, - DataRequestMonitor<Boolean> rm); + public void canRemoveRegisterGroups(IRegisterGroupDMContext[] groups, DataRequestMonitor<Boolean> rm); /** * Remove the given register groups - * + * * @param groups - groups that shall be removed * @param rm - request monitor */ @@ -85,7 +83,7 @@ public interface IRegisters2 extends IRegisters { /** * Remove all the user defined register groups and restore the default ones to their * original state. - * + * * @param rm - request monitor */ public void restoreDefaultGroups(IDMContext selectionContext, RequestMonitor rm); diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IRunControl.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IRunControl.java index 114b4291c26..b8f08701dfb 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IRunControl.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IRunControl.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation * Ericsson - Modified for additional functionality @@ -22,151 +22,159 @@ import org.eclipse.cdt.dsf.datamodel.IDMEvent; import org.eclipse.cdt.dsf.service.IDsfService; /** - * This interface provides access to controlling and monitoring the execution - * state of a process being debugged. This interface does not actually + * This interface provides access to controlling and monitoring the execution + * state of a process being debugged. This interface does not actually * provide methods for creating or destroying execution contexts, it doesn't * even have methods for getting labels. That's because it is expected that - * higher level services, ones that deal with processes, kernels, or target - * features will provide that functionality. - * + * higher level services, ones that deal with processes, kernels, or target + * features will provide that functionality. + * * @since 1.0 */ -public interface IRunControl extends IDsfService -{ - /** - * Execution context is the object on which run control operations can be - * performed. A lot of higher-level services reference this context to build - * functionality on top of it, e.g. stack, expression evaluation, registers, etc. - */ - public interface IExecutionDMContext extends IDMContext {} - - /** - * Context representing a process, kernel, or some other logical container - * for execution contexts, which by itself can perform run-control - * operations. - */ - - public interface IContainerDMContext extends IExecutionDMContext {} - - /** Flag indicating reason context state change. */ - public enum StateChangeReason { - UNKNOWN, USER_REQUEST, STEP, BREAKPOINT, EXCEPTION, CONTAINER, WATCHPOINT, SIGNAL, SHAREDLIB, ERROR, EVALUATION, - - /** @since 2.1 */ - EVENT_BREAKPOINT }; - - /** - * Indicates that the given thread has suspended. - */ - public interface ISuspendedDMEvent extends IDMEvent<IExecutionDMContext> { - StateChangeReason getReason(); - } - - /** - * Indicates that the given thread has resumed. - */ - public interface IResumedDMEvent extends IDMEvent<IExecutionDMContext> { - StateChangeReason getReason(); - } - - /** - * Indicates that the given container has suspended. - */ - public interface IContainerSuspendedDMEvent extends ISuspendedDMEvent { - /** - * Returns the contexts which triggered the resume, which could be - * an empty array if not known. - */ - IExecutionDMContext[] getTriggeringContexts(); - } - - /** - * Indicates that the given container has resumed. - */ - public interface IContainerResumedDMEvent extends IResumedDMEvent { - /** - * Returns the contexts which triggered the resume, which could be an - * empty array if not known. - */ - IExecutionDMContext[] getTriggeringContexts(); - } - - /** - * Indicates that a new execution context was created but may not have - * started execution yet. - * @since 2.8 - */ - public interface ICreatedDMEvent extends IDMEvent<IExecutionDMContext> {} - - /** - * Indicates that a new execution context was started. - */ - public interface IStartedDMEvent extends IDMEvent<IExecutionDMContext> {} - - /** - * Indicates that an execution context has exited. - */ - public interface IExitedDMEvent extends IDMEvent<IExecutionDMContext> {} - - /** - * Display information for an execution context. - */ - public interface IExecutionDMData extends IDMData { - - /** - * Reason for the last change in execution state. Could be - * <code>null</code> if the service does not support tracking this - * information. - */ - StateChangeReason getStateChangeReason(); - } - - /** +public interface IRunControl extends IDsfService { + /** + * Execution context is the object on which run control operations can be + * performed. A lot of higher-level services reference this context to build + * functionality on top of it, e.g. stack, expression evaluation, registers, etc. + */ + public interface IExecutionDMContext extends IDMContext { + } + + /** + * Context representing a process, kernel, or some other logical container + * for execution contexts, which by itself can perform run-control + * operations. + */ + + public interface IContainerDMContext extends IExecutionDMContext { + } + + /** Flag indicating reason context state change. */ + public enum StateChangeReason { + UNKNOWN, USER_REQUEST, STEP, BREAKPOINT, EXCEPTION, CONTAINER, WATCHPOINT, SIGNAL, SHAREDLIB, ERROR, EVALUATION, + + /** @since 2.1 */ + EVENT_BREAKPOINT + }; + + /** + * Indicates that the given thread has suspended. + */ + public interface ISuspendedDMEvent extends IDMEvent<IExecutionDMContext> { + StateChangeReason getReason(); + } + + /** + * Indicates that the given thread has resumed. + */ + public interface IResumedDMEvent extends IDMEvent<IExecutionDMContext> { + StateChangeReason getReason(); + } + + /** + * Indicates that the given container has suspended. + */ + public interface IContainerSuspendedDMEvent extends ISuspendedDMEvent { + /** + * Returns the contexts which triggered the resume, which could be + * an empty array if not known. + */ + IExecutionDMContext[] getTriggeringContexts(); + } + + /** + * Indicates that the given container has resumed. + */ + public interface IContainerResumedDMEvent extends IResumedDMEvent { + /** + * Returns the contexts which triggered the resume, which could be an + * empty array if not known. + */ + IExecutionDMContext[] getTriggeringContexts(); + } + + /** + * Indicates that a new execution context was created but may not have + * started execution yet. + * @since 2.8 + */ + public interface ICreatedDMEvent extends IDMEvent<IExecutionDMContext> { + } + + /** + * Indicates that a new execution context was started. + */ + public interface IStartedDMEvent extends IDMEvent<IExecutionDMContext> { + } + + /** + * Indicates that an execution context has exited. + */ + public interface IExitedDMEvent extends IDMEvent<IExecutionDMContext> { + } + + /** + * Display information for an execution context. + */ + public interface IExecutionDMData extends IDMData { + + /** + * Reason for the last change in execution state. Could be + * <code>null</code> if the service does not support tracking this + * information. + */ + StateChangeReason getStateChangeReason(); + } + + /** * @since 2.1 */ - public interface IExecutionDMData2 extends IExecutionDMData { - /** - * Optional method to return more detail about the suspended event, e.g. - * "Divide by zero exception" - * @return more detail about the suspended event, or null - */ - String getDetails(); - } - - /** - * Retrieves execution data for given context. - * @param dmc Context to retrieve data for. - * @param rm Request completion monitor. - */ - public void getExecutionData(IExecutionDMContext dmc, DataRequestMonitor<IExecutionDMData> rm); - - /** - * Returns execution contexts belonging to the given container context. - */ - public void getExecutionContexts(IContainerDMContext c, DataRequestMonitor<IExecutionDMContext[]> rm); - - /* - * Run control commands. They all require the IExecutionContext object on - * which they perform the operations. - */ - void canResume(IExecutionDMContext context, DataRequestMonitor<Boolean> rm); - void canSuspend(IExecutionDMContext context, DataRequestMonitor<Boolean> rm); - boolean isSuspended(IExecutionDMContext context); - void resume(IExecutionDMContext context, RequestMonitor requestMonitor); - void suspend(IExecutionDMContext context, RequestMonitor requestMonitor); - - public enum StepType { - STEP_OVER, - STEP_INTO, - STEP_RETURN, - INSTRUCTION_STEP_OVER, - INSTRUCTION_STEP_INTO, - /** - * @since 2.0 - */ - INSTRUCTION_STEP_RETURN }; - - boolean isStepping(IExecutionDMContext context); - void canStep(IExecutionDMContext context, StepType stepType, DataRequestMonitor<Boolean> rm); - void step(IExecutionDMContext context, StepType stepType, RequestMonitor requestMonitor); + public interface IExecutionDMData2 extends IExecutionDMData { + /** + * Optional method to return more detail about the suspended event, e.g. + * "Divide by zero exception" + * @return more detail about the suspended event, or null + */ + String getDetails(); + } + + /** + * Retrieves execution data for given context. + * @param dmc Context to retrieve data for. + * @param rm Request completion monitor. + */ + public void getExecutionData(IExecutionDMContext dmc, DataRequestMonitor<IExecutionDMData> rm); + + /** + * Returns execution contexts belonging to the given container context. + */ + public void getExecutionContexts(IContainerDMContext c, DataRequestMonitor<IExecutionDMContext[]> rm); + + /* + * Run control commands. They all require the IExecutionContext object on + * which they perform the operations. + */ + void canResume(IExecutionDMContext context, DataRequestMonitor<Boolean> rm); + + void canSuspend(IExecutionDMContext context, DataRequestMonitor<Boolean> rm); + + boolean isSuspended(IExecutionDMContext context); + + void resume(IExecutionDMContext context, RequestMonitor requestMonitor); + + void suspend(IExecutionDMContext context, RequestMonitor requestMonitor); + + public enum StepType { + STEP_OVER, STEP_INTO, STEP_RETURN, INSTRUCTION_STEP_OVER, INSTRUCTION_STEP_INTO, + /** + * @since 2.0 + */ + INSTRUCTION_STEP_RETURN + }; + + boolean isStepping(IExecutionDMContext context); + + void canStep(IExecutionDMContext context, StepType stepType, DataRequestMonitor<Boolean> rm); + + void step(IExecutionDMContext context, StepType stepType, RequestMonitor requestMonitor); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IRunControl2.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IRunControl2.java index 66702f11e40..bf4ce39180f 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IRunControl2.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IRunControl2.java @@ -19,7 +19,7 @@ import org.eclipse.cdt.dsf.concurrent.RequestMonitor; /** * This interface extends IRunControl to let a service support the - * "Run to Line," "Move to Line," and "Resume at Line" commands. + * "Run to Line," "Move to Line," and "Resume at Line" commands. * @since 2.1 */ public interface IRunControl2 extends IRunControl { @@ -27,44 +27,45 @@ public interface IRunControl2 extends IRunControl { /** * Returns whether the service can run the specified context to * a source file and line number. - * + * * @param context the execution DM context * @param sourceFile the source file path, mapped to a debugger path if possible. * @param lineNumber the line number offset (one-based) into the source file * @param rm the DataRequestMonitor that will return the result */ - void canRunToLine(IExecutionDMContext context, String sourceFile, int lineNumber, DataRequestMonitor<Boolean> rm ); + void canRunToLine(IExecutionDMContext context, String sourceFile, int lineNumber, DataRequestMonitor<Boolean> rm); /** * Request to run the program up to the specified location. * If skipBreakpoints is false, any other breakpoint will stop this * command; while if skipBreakpoints is true, the operation will ignore * other breakpoints and continue until the specified location. - * + * * @param context the execution DM context * @param sourceFile the source file path, mapped to a debugger path if possible. * @param lineNumber the line number offset into (one-based) the source file * @param skipBreakpoints skip breakpoints while performing this operation * @param rm the Request Monitor */ - void runToLine(IExecutionDMContext context, String sourceFile, int lineNumber, boolean skipBreakpoints, RequestMonitor rm); + void runToLine(IExecutionDMContext context, String sourceFile, int lineNumber, boolean skipBreakpoints, + RequestMonitor rm); /** * Returns whether the service can run the specified context to * a specified address. - * + * * @param context the execution DM context * @param address the address specifier * @param rm the DataRequestMonitor that will return the result */ - void canRunToAddress(IExecutionDMContext context, IAddress address, DataRequestMonitor<Boolean> rm ); + void canRunToAddress(IExecutionDMContext context, IAddress address, DataRequestMonitor<Boolean> rm); /** * Request to run the program up to the specified address. * If skipBreakpoints is false, any other breakpoint will stop this * command; while if skipBreakpoints is true, the operation will ignore * other breakpoints and continue until the specified location. - * + * * @param context the execution DM context * @param address the address specifier * @param skipBreakpoints the skip breakpoints @@ -75,47 +76,49 @@ public interface IRunControl2 extends IRunControl { /** * Determines if the service can move the program counter to the specified * source location. - * + * * @param context the execution DM context * @param sourceFile the source file path, mapped to a debugger path if possible. * @param lineNumber the line number offset (one-based) into the source file * @param resume resume execution after moving the PC * @param rm the DataRequestMonitor that will return the result */ - void canMoveToLine(IExecutionDMContext context, String sourceFile, int lineNumber, boolean resume, DataRequestMonitor<Boolean> rm ); + void canMoveToLine(IExecutionDMContext context, String sourceFile, int lineNumber, boolean resume, + DataRequestMonitor<Boolean> rm); /** * Moves the program counter for the specified context to the specified * source location. - * + * * @param context the execution DM context * @param sourceFile the source file path, mapped to a debugger path if possible. * @param lineNumber the line number offset (one-based) into the source file * @param resume resume execution after moving the PC * @param rm the Request Monitor */ - void moveToLine(IExecutionDMContext context, String sourceFile, int lineNumber, boolean resume, RequestMonitor rm ); + void moveToLine(IExecutionDMContext context, String sourceFile, int lineNumber, boolean resume, RequestMonitor rm); /** * Determines if the service can move the program counter to the specified * address. - * + * * @param context the execution DM context * @param address the address specifier * @param resume resume execution after moving the PC * @param rm the DataRequestMonitor that will return the result */ - void canMoveToAddress(IExecutionDMContext context, IAddress address, boolean resume, DataRequestMonitor<Boolean> rm ); + void canMoveToAddress(IExecutionDMContext context, IAddress address, boolean resume, + DataRequestMonitor<Boolean> rm); /** * Moves the program counter for the specified context to the specified * address. - * + * * @param context the execution DM context * @param address the address specifier * @param resume resume execution after moving the PC * @param rm the Request Monitor */ - void moveToAddress(IExecutionDMContext context, IAddress address, boolean resume, RequestMonitor rm ); + void moveToAddress(IExecutionDMContext context, IAddress address, boolean resume, RequestMonitor rm); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IRunControl3.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IRunControl3.java index 87bf4df71d0..e89eec56ee7 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IRunControl3.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IRunControl3.java @@ -19,37 +19,37 @@ import org.eclipse.cdt.dsf.concurrent.RequestMonitor; /** * This interface extends IRunControl2 to let a service support the - * "Step into selection" command. + * "Step into selection" command. * @since 2.4 */ public interface IRunControl3 extends IRunControl2 { /** * Returns whether the service is in the state to execute 'Step into selection' * for the specified context - * + * * @param context the execution DM context * @param sourceFile the source file path, mapped to a debugger path if possible, invalid if selectedFunction is Null * @param lineNumber the line number of the source file where the user selected the target function, invalid if selectedFunction is Null * @param selectedFunction The target function to step into <br>NOTE: a null value shall disregard linenumber and sourceFile * @param rm the DataRequestMonitor that will return the result */ - void canStepIntoSelection(IExecutionDMContext context, String sourceFile, int lineNumber, - IFunctionDeclaration selectedFunction, DataRequestMonitor<Boolean> rm); - + void canStepIntoSelection(IExecutionDMContext context, String sourceFile, int lineNumber, + IFunctionDeclaration selectedFunction, DataRequestMonitor<Boolean> rm); + /** * Request to run the program forward into the specified function * if the current stop location is not at the specified lineNumber and * skipBreakpoints is false, any other breakpoint found before the specified line number will stop this * command; while if skipBreakpoints is true, the operation will ignore * other breakpoints and continue until the specified location. - * + * * @param context the execution DM context * @param sourceFile the source file path, mapped to a debugger path if possible. - * @param lineNumber the line number of the source file where the user selected the target function + * @param lineNumber the line number of the source file where the user selected the target function * @param skipBreakpoints skip breakpoints while performing this operation * @param selectedFunction the target function to step into * @param rm the DataRequestMonitor that will return the result */ - void stepIntoSelection (IExecutionDMContext context, String sourceFile, int lineNumber, - boolean skipBreakpoints, IFunctionDeclaration selectedFunction, RequestMonitor rm); + void stepIntoSelection(IExecutionDMContext context, String sourceFile, int lineNumber, boolean skipBreakpoints, + IFunctionDeclaration selectedFunction, RequestMonitor rm); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/ISignals.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/ISignals.java index 51a89ff5725..ae990f81aac 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/ISignals.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/ISignals.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ @@ -18,13 +18,14 @@ import org.eclipse.cdt.dsf.service.IDsfService; /** * Place holder interface for a signals implementation. - * + * * @since 1.0 */ public interface ISignals extends IDsfService { - /** - * Marker interface for a context for which signals can be set. - */ - public interface ISignalsDMContext extends IDMContext {}; + /** + * Marker interface for a context for which signals can be set. + */ + public interface ISignalsDMContext extends IDMContext { + }; } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/ISourceLookup.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/ISourceLookup.java index dba93b7e875..d2adf69f905 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/ISourceLookup.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/ISourceLookup.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ @@ -23,22 +23,24 @@ import org.eclipse.cdt.dsf.service.IDsfService; * primarily by other services that need to access source-path mappings, such * as the breakpoints service. For UI components, the platform source lookup * interfaces could be sufficient. - * + * * @since 1.0 */ public interface ISourceLookup extends IDsfService { - public interface ISourceLookupDMContext extends IDMContext {} - - public interface ISourceLookupChangedDMEvent extends IDMEvent<ISourceLookupDMContext> {} - - /** - * Retrieves the host source object for given debugger path string. - */ - void getSource(ISourceLookupDMContext ctx, String debuggerPath, DataRequestMonitor<Object> rm); - - /** - * Retrieves the debugger path string for given host source object. - */ - void getDebuggerPath(ISourceLookupDMContext ctx, Object source, DataRequestMonitor<String> rm); + public interface ISourceLookupDMContext extends IDMContext { + } + + public interface ISourceLookupChangedDMEvent extends IDMEvent<ISourceLookupDMContext> { + } + + /** + * Retrieves the host source object for given debugger path string. + */ + void getSource(ISourceLookupDMContext ctx, String debuggerPath, DataRequestMonitor<Object> rm); + + /** + * Retrieves the debugger path string for given host source object. + */ + void getDebuggerPath(ISourceLookupDMContext ctx, Object source, DataRequestMonitor<String> rm); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IStack.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IStack.java index 9793faa35b2..ddca88537f0 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IStack.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IStack.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ @@ -20,126 +20,134 @@ import org.eclipse.cdt.dsf.datamodel.IDMData; import org.eclipse.cdt.dsf.service.IDsfService; /** - * Stack service provides access to stack information for a + * Stack service provides access to stack information for a * given execution context. - * + * * @since 1.0 */ public interface IStack extends IDsfService { - /** - * Context for a specific stack frame. Besides allowing access to stack - * frame data, this context is used by other services that require a stack - * frame for evaluation. - */ - public interface IFrameDMContext extends IDMContext { - int getLevel(); - } - - /** - * Stack frame information. - */ - public interface IFrameDMData extends IDMData { - IAddress getAddress(); - String getFile(); - String getFunction(); - int getLine(); - int getColumn(); - /** - * @since 2.0 - */ + /** + * Context for a specific stack frame. Besides allowing access to stack + * frame data, this context is used by other services that require a stack + * frame for evaluation. + */ + public interface IFrameDMContext extends IDMContext { + int getLevel(); + } + + /** + * Stack frame information. + */ + public interface IFrameDMData extends IDMData { + IAddress getAddress(); + + String getFile(); + + String getFunction(); + + int getLine(); + + int getColumn(); + + /** + * @since 2.0 + */ String getModule(); - } - - /** - * Variable context. This context only provides access to limited - * expression information. For displaying complete information, - * Expressions service should be used. - */ - public interface IVariableDMContext extends IDMContext {} - - /** - * Stack frame variable information. - */ - public interface IVariableDMData extends IDMData { - String getName(); - String getValue(); - } - - /** - * Retrieves stack frame data for given context. - * @param frameDmc Context to retrieve data for. - * @param rm Request completion monitor. - */ - public void getFrameData(final IFrameDMContext frameDmc, DataRequestMonitor<IFrameDMData> rm); - - /** - * Retrieves stack frame variable data for given context. - * @param variableDmc Context to retrieve data for. - * @param rm Request completion monitor. - */ - public void getVariableData(IVariableDMContext variableDmc, DataRequestMonitor<IVariableDMData> rm); - - /** - * Retrieves list of stack frames for the given execution context. Request - * will fail if the stack frame data is not available. - */ - void getFrames(IDMContext execContext, DataRequestMonitor<IFrameDMContext[]> rm); - - /** + } + + /** + * Variable context. This context only provides access to limited + * expression information. For displaying complete information, + * Expressions service should be used. + */ + public interface IVariableDMContext extends IDMContext { + } + + /** + * Stack frame variable information. + */ + public interface IVariableDMData extends IDMData { + String getName(); + + String getValue(); + } + + /** + * Retrieves stack frame data for given context. + * @param frameDmc Context to retrieve data for. + * @param rm Request completion monitor. + */ + public void getFrameData(final IFrameDMContext frameDmc, DataRequestMonitor<IFrameDMData> rm); + + /** + * Retrieves stack frame variable data for given context. + * @param variableDmc Context to retrieve data for. + * @param rm Request completion monitor. + */ + public void getVariableData(IVariableDMContext variableDmc, DataRequestMonitor<IVariableDMData> rm); + + /** + * Retrieves list of stack frames for the given execution context. Request + * will fail if the stack frame data is not available. + */ + void getFrames(IDMContext execContext, DataRequestMonitor<IFrameDMContext[]> rm); + + /** * When passed in the endIndex of getFrames(...) it indicates that all stack frames are to be retrieved. * @since 2.0 */ - public final static int ALL_FRAMES = -1; - + public final static int ALL_FRAMES = -1; + /** * Retrieves list of stack frames for the given execution context. Request - * will fail if the stack frame data is not available. - * <p>The range of stack frames can be limited by the <code>startIndex</code> and <code>endIndex</code> arguments. + * will fail if the stack frame data is not available. + * <p>The range of stack frames can be limited by the <code>startIndex</code> and <code>endIndex</code> arguments. * It is no error to specify an <code>endIndex</code> exceeding the number of available stack frames. * A negative value for <code>endIndex</code> means to retrieve all stack frames. <code>startIndex</code> must be a non-negative value. * </p> - * + * * @param execContext the execution context to retrieve stack frames for * @param startIndex the index of the first frame to retrieve * @param endIndex the index of the last frame to retrieve (inclusive) or {@link #ALL_FRAMES} * @param rm the request monitor - * + * * @see #getFrames(IDMContext, DataRequestMonitor) * @since 2.0 */ - public void getFrames(IDMContext execContext, int startIndex, int endIndex, DataRequestMonitor<IFrameDMContext[]> rm); - - /** - * Retrieves the top stack frame for the given execution context. - * Retrieving just the top frame DMC and corresponding data can be much - * more efficient than just retrieving the whole stack, before the data - * is often included in the stopped event. Also for some UI functionality, - * such as stepping, only top stack frame is often needed. - * @param execContext - * @param rm - */ - void getTopFrame(IDMContext execContext, DataRequestMonitor<IFrameDMContext> rm); - - /** - * Retrieves variables which were arguments to the stack frame's function. - */ - void getArguments(IFrameDMContext frameCtx, DataRequestMonitor<IVariableDMContext[]> rm); - - /** - * Retrieves variables local to the stack frame, including arguments. - */ - void getLocals(IFrameDMContext frameCtx, DataRequestMonitor<IVariableDMContext[]> rm); - - /** - * Retrieves the number of stack frames available for the given context. The depth - * returned could, but is not required to, be limited to the maxDepth parameter. - * - * @param dmc Context to retrieve data for. - * @param maxDepth The maximum depth of stack that is requested. If 0, not limit should - * be used to calculate the stack depth, and the actual stack depth should be returned. - * @param rm Request monitor indicating the current stack depth, potentially limited - * to maxDepth. - */ - void getStackDepth(IDMContext dmc, int maxDepth, DataRequestMonitor<Integer> rm); + public void getFrames(IDMContext execContext, int startIndex, int endIndex, + DataRequestMonitor<IFrameDMContext[]> rm); + + /** + * Retrieves the top stack frame for the given execution context. + * Retrieving just the top frame DMC and corresponding data can be much + * more efficient than just retrieving the whole stack, before the data + * is often included in the stopped event. Also for some UI functionality, + * such as stepping, only top stack frame is often needed. + * @param execContext + * @param rm + */ + void getTopFrame(IDMContext execContext, DataRequestMonitor<IFrameDMContext> rm); + + /** + * Retrieves variables which were arguments to the stack frame's function. + */ + void getArguments(IFrameDMContext frameCtx, DataRequestMonitor<IVariableDMContext[]> rm); + + /** + * Retrieves variables local to the stack frame, including arguments. + */ + void getLocals(IFrameDMContext frameCtx, DataRequestMonitor<IVariableDMContext[]> rm); + + /** + * Retrieves the number of stack frames available for the given context. The depth + * returned could, but is not required to, be limited to the maxDepth parameter. + * + * @param dmc Context to retrieve data for. + * @param maxDepth The maximum depth of stack that is requested. If 0, not limit should + * be used to calculate the stack depth, and the actual stack depth should be returned. + * @param rm Request monitor indicating the current stack depth, potentially limited + * to maxDepth. + */ + void getStackDepth(IDMContext dmc, int maxDepth, DataRequestMonitor<Integer> rm); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/ISymbols.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/ISymbols.java index 2956af58dae..b83008847a5 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/ISymbols.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/ISymbols.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ @@ -23,37 +23,41 @@ import org.eclipse.cdt.dsf.service.IDsfService; * Service for accessing debugger symbols. This service builds on the Modules * service, but not all debuggers provide access for parsing symbols so this * service is separated. - * + * * @see IModules * @since 1.0 */ public interface ISymbols extends IDsfService { - public interface ISymbolObjectDMContext extends IDMContext {} - - /** - * Data about a debug symbol. - */ - public interface ISymbolObjectDMData extends IDMData { - String getName(); - String getTypeName(); - String getFilepath(); - } + public interface ISymbolObjectDMContext extends IDMContext { + } + + /** + * Data about a debug symbol. + */ + public interface ISymbolObjectDMData extends IDMData { + String getName(); + + String getTypeName(); + + String getFilepath(); + } + + /** + * Indicates that the list of symbol objects is changed. Parsing debug + * symbols can be a long running operation (order of 10's of seconds or + * minutes), so it is useful for the service to provide access to the data + * even while it's still parsing. This event may be issued periodically + * by the service to indicate that a section of debug symbols has been + * parsed. + */ + public interface ISymbolDataChangedDMEvent extends IDMEvent<IModules.ISymbolDMContext> { + } - /** - * Indicates that the list of symbol objects is changed. Parsing debug - * symbols can be a long running operation (order of 10's of seconds or - * minutes), so it is useful for the service to provide access to the data - * even while it's still parsing. This event may be issued periodically - * by the service to indicate that a section of debug symbols has been - * parsed. - */ - public interface ISymbolDataChangedDMEvent extends IDMEvent<IModules.ISymbolDMContext> {} - - /** - * Retrieves the list of symbols. - * @param symCtx Symbols context to retrieve symbols for. - * @param rm Request completion monitor. The return value is an iterator (rather than - * array) since there could be a very large number of symbols returned. - */ - public void getSymbols(IModules.ISymbolDMContext symCtx, DataRequestMonitor<Iterable<ISymbolObjectDMContext>> rm); + /** + * Retrieves the list of symbols. + * @param symCtx Symbols context to retrieve symbols for. + * @param rm Request completion monitor. The return value is an iterator (rather than + * array) since there could be a very large number of symbols returned. + */ + public void getSymbols(IModules.ISymbolDMContext symCtx, DataRequestMonitor<Iterable<ISymbolObjectDMContext>> rm); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/BufferedCommandControl.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/BufferedCommandControl.java index 9944f447a17..b270e02c6ca 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/BufferedCommandControl.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/BufferedCommandControl.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ @@ -22,146 +22,144 @@ import org.eclipse.cdt.dsf.concurrent.DsfRunnable; import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor; /** - * A command control which delays the <strong>results</strong> of commands - * sent to a command control, as well as events from the command control. - * The delay is specified in the constructor using a number of executor + * A command control which delays the <strong>results</strong> of commands + * sent to a command control, as well as events from the command control. + * The delay is specified in the constructor using a number of executor * dispatch cycles. - * + * * @since 2.1 */ public class BufferedCommandControl implements ICommandControl { - private DsfExecutor fExecutor; - private ICommandControl fControlDelegate; - private int fDepth; - - private ICommandListener fCommandListener = new ICommandListener() { - @Override - public void commandQueued(ICommandToken token) { - for (ICommandListener processor : fCommandProcessors) { - processor.commandQueued(token); - } - }; - - @Override - public void commandRemoved(ICommandToken token) { - for (ICommandListener processor : fCommandProcessors) { - processor.commandRemoved(token); - } - }; - - @Override - public void commandSent(final ICommandToken token) { - for (ICommandListener processor : fCommandProcessors) { - processor.commandSent(token); - } - }; - - @Override - public void commandDone(final ICommandToken token, final ICommandResult result) { - buffer(fDepth, new DsfRunnable() { - @Override - public void run() { - for (ICommandListener processor : fCommandProcessors) { - processor.commandDone(token, result); - } - }; - }); - }; - }; - - private IEventListener fEventListener = new IEventListener() { - @Override - public void eventReceived(final Object output) { - buffer(fDepth, new DsfRunnable() { - @Override - public void run() { - for (IEventListener processor : fEventProcessors) { - processor.eventReceived(output); - } - }; - }); - } - }; - - private final List<ICommandListener> fCommandProcessors = new ArrayList<ICommandListener>(); - private final List<IEventListener> fEventProcessors = new ArrayList<IEventListener>(); - - public BufferedCommandControl(ICommandControl controlDelegate, DsfExecutor executor, int depth) { - fControlDelegate = controlDelegate; - fExecutor = executor; - fDepth = depth; - assert fDepth > 0; - } - - @Override - public void addCommandListener(ICommandListener listener) { - if (fCommandProcessors.isEmpty()) { - fControlDelegate.addCommandListener(fCommandListener); - } - fCommandProcessors.add(listener); - } - - - @Override - public void removeCommandListener(ICommandListener listener) { - fCommandProcessors.remove(listener); - if (fCommandProcessors.isEmpty()) { - fControlDelegate.removeCommandListener(fCommandListener); - } - } - - @Override - public void addEventListener(IEventListener listener) { - if (fEventProcessors.isEmpty()) { - fControlDelegate.addEventListener(fEventListener); - } - fEventProcessors.add(listener); - } - - @Override - public void removeEventListener(IEventListener listener) { - fEventProcessors.remove(listener); - if (fEventProcessors.isEmpty()) { - fControlDelegate.removeEventListener(fEventListener); - } - } - - @Override - public <V extends ICommandResult> ICommandToken queueCommand(final ICommand<V> command, final DataRequestMonitor<V> rm) { - return fControlDelegate.queueCommand( - command, - new DataRequestMonitor<V>(ImmediateExecutor.getInstance(), rm) { - @Override - protected void handleCompleted() { - buffer(fDepth, new DsfRunnable() { - @Override - public void run() { - rm.setData(getData()); - rm.setStatus(getStatus()); - rm.done(); - } - }); - } - }); - } - - @Override - public void removeCommand(ICommandToken token) { - fControlDelegate.removeCommand(token); - } - - private void buffer(final int depth, final DsfRunnable runnable) { - if (depth == 0) { - runnable.run(); - } else { - fExecutor.execute(new DsfRunnable() { - @Override - public void run() { - buffer(depth - 1, runnable); - } - }); - } - } + private DsfExecutor fExecutor; + private ICommandControl fControlDelegate; + private int fDepth; + + private ICommandListener fCommandListener = new ICommandListener() { + @Override + public void commandQueued(ICommandToken token) { + for (ICommandListener processor : fCommandProcessors) { + processor.commandQueued(token); + } + }; + + @Override + public void commandRemoved(ICommandToken token) { + for (ICommandListener processor : fCommandProcessors) { + processor.commandRemoved(token); + } + }; + + @Override + public void commandSent(final ICommandToken token) { + for (ICommandListener processor : fCommandProcessors) { + processor.commandSent(token); + } + }; + + @Override + public void commandDone(final ICommandToken token, final ICommandResult result) { + buffer(fDepth, new DsfRunnable() { + @Override + public void run() { + for (ICommandListener processor : fCommandProcessors) { + processor.commandDone(token, result); + } + }; + }); + }; + }; + + private IEventListener fEventListener = new IEventListener() { + @Override + public void eventReceived(final Object output) { + buffer(fDepth, new DsfRunnable() { + @Override + public void run() { + for (IEventListener processor : fEventProcessors) { + processor.eventReceived(output); + } + }; + }); + } + }; + + private final List<ICommandListener> fCommandProcessors = new ArrayList<ICommandListener>(); + private final List<IEventListener> fEventProcessors = new ArrayList<IEventListener>(); + + public BufferedCommandControl(ICommandControl controlDelegate, DsfExecutor executor, int depth) { + fControlDelegate = controlDelegate; + fExecutor = executor; + fDepth = depth; + assert fDepth > 0; + } + + @Override + public void addCommandListener(ICommandListener listener) { + if (fCommandProcessors.isEmpty()) { + fControlDelegate.addCommandListener(fCommandListener); + } + fCommandProcessors.add(listener); + } + + @Override + public void removeCommandListener(ICommandListener listener) { + fCommandProcessors.remove(listener); + if (fCommandProcessors.isEmpty()) { + fControlDelegate.removeCommandListener(fCommandListener); + } + } + + @Override + public void addEventListener(IEventListener listener) { + if (fEventProcessors.isEmpty()) { + fControlDelegate.addEventListener(fEventListener); + } + fEventProcessors.add(listener); + } + + @Override + public void removeEventListener(IEventListener listener) { + fEventProcessors.remove(listener); + if (fEventProcessors.isEmpty()) { + fControlDelegate.removeEventListener(fEventListener); + } + } + + @Override + public <V extends ICommandResult> ICommandToken queueCommand(final ICommand<V> command, + final DataRequestMonitor<V> rm) { + return fControlDelegate.queueCommand(command, new DataRequestMonitor<V>(ImmediateExecutor.getInstance(), rm) { + @Override + protected void handleCompleted() { + buffer(fDepth, new DsfRunnable() { + @Override + public void run() { + rm.setData(getData()); + rm.setStatus(getStatus()); + rm.done(); + } + }); + } + }); + } + + @Override + public void removeCommand(ICommandToken token) { + fControlDelegate.removeCommand(token); + } + + private void buffer(final int depth, final DsfRunnable runnable) { + if (depth == 0) { + runnable.run(); + } else { + fExecutor.execute(new DsfRunnable() { + @Override + public void run() { + buffer(depth - 1, runnable); + } + }); + } + } } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/CommandCache.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/CommandCache.java index 2adb81b11c8..024006f48c6 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/CommandCache.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/CommandCache.java @@ -7,12 +7,12 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation - * Ericsson - Modified for caching commands corresponding to multiple execution contexts + * Ericsson - Modified for caching commands corresponding to multiple execution contexts *******************************************************************************/ - + package org.eclipse.cdt.dsf.debug.service.command; import java.util.ArrayList; @@ -42,610 +42,636 @@ import org.eclipse.core.runtime.Status; * sent to their intended target through the supplied {@link ICommandControl}, * and their results are cached so as to quickly service future identical * commands. - * + * * The cache has to be reset by the client that owns and uses the cache. A reset * should be done when an event occurs that alters the state of a context such * that commands on that context may no longer yield the same outcome as they * did before the event. A reset can be done on the entire cache or on a per * context basis. - * + * * @since 1.0 */ - -public class CommandCache implements ICommandListener -{ - static enum CommandStyle { COALESCED, NONCOALESCED } - - /** - * Holds cache information for a given command. - * @param <V> Type matches the result type associated with the command. - */ - class CommandInfo { - - /* - * Control variables. - */ - - /** List of the request monitors associated with this command */ - private final List<DataRequestMonitor<ICommandResult>> fCurrentRequestMonitors ; - - /** Original command. Need for reference from Queue completion notification */ - private final ICommand<ICommandResult> fCommand; - - /** Style of this command ( internal coalesced or not) */ - private final CommandStyle fCmdStyle; - - /** Command being processed for this command */ - private CommandInfo fCoalescedCmd; - - private ICommandToken fToken; - - public CommandInfo(CommandStyle cmdstyle, ICommand<ICommandResult> cmd, DataRequestMonitor<ICommandResult> rm ) { - fCmdStyle = cmdstyle; - fCommand = cmd; - fCurrentRequestMonitors = new LinkedList<DataRequestMonitor<ICommandResult>>(); - fCurrentRequestMonitors.add(rm); - fCoalescedCmd = null; - } - - public CommandStyle getCommandstyle() { return fCmdStyle; } - public List<DataRequestMonitor<ICommandResult>> getRequestMonitorList() { return fCurrentRequestMonitors; } - public ICommand<ICommandResult> getCommand() { return fCommand; } - public CommandInfo getCoalescedCmd() { return fCoalescedCmd; } - public void setCoalescedCmd( CommandInfo cmd ) { fCoalescedCmd = cmd; } - - @Override - public boolean equals(Object other) { - if (!(other instanceof CommandInfo)) return false; - CommandInfo otherCmd = (CommandInfo)other; - - return otherCmd.fCommand.equals(fCommand); - } - - @Override - public int hashCode() { - return fCommand.hashCode(); - } - } - - class CommandResultInfo { - private final ICommandResult fData; - private final IStatus fStatus; - - public CommandResultInfo(ICommandResult data, IStatus status) { - fData = data; - fStatus = status; - } - - public ICommandResult getData() { return fData; } - public IStatus getStatus() { return fStatus; } - } - - private DsfSession fSession; - - /** - * The command control to be used to send commands to the backend. - * In certain cases, a {@link BufferedCommandControl} should be used - * to artificially delay the processing of command results; these - * artificial delays are important to keep events and command results - * ordered as received by the backend. - */ - private ICommandControl fCommandControl; - - /* - * This class contains 5 significant lists. - * - * Cached Results : - * - * Contains a mapping of commands and their completed results. Until the cached - * results are cleared by the owner of the cache. - * - * Pending Commands Not Queued : - * - * The Control object has not yet indicated that it has recognized the command - * yet. The user is not allowed to interrogate these objects until the Control - * object indicates they have been queued ( commandQueued notification ). - * - * Pending Commands Unsent : - * - * This is the list of commands which have been issued to the Control object but - * have not been actually issued to the backend. These commands represent coalesce - * options. They may be compared against the Queued list being maintained by the - * Control object until told otherwise - commandSent notification ). - * - * Pending Commands Sent : - * - * This is a list of commands which have been issued to the Control object and - * have also been sent to the backend. It is not possible use these objects for - * coalescents. - * - * Coalesced Pending Q : - * - * These represent original commands for which a new coalesced command has been - * created. When the coalesced commands completes the results will be decomposed - * when back into individual results from this command. - */ - private Set<IDMContext> fAvailableContexts = new HashSet<IDMContext>(); - - private Map<IDMContext, HashMap<CommandInfo, CommandResultInfo>> fCachedContexts = new HashMap<IDMContext, HashMap<CommandInfo, CommandResultInfo>>(); - - private ArrayList<CommandInfo> fPendingQCommandsSent = new ArrayList<CommandInfo>(); - - private ArrayList<CommandInfo> fPendingQCommandsNotYetSent = new ArrayList<CommandInfo>(); - - private ArrayList<CommandInfo> fPendingQWaitingForCoalescedCompletion = new ArrayList<CommandInfo>(); - - private static boolean DEBUG = false; + +public class CommandCache implements ICommandListener { + static enum CommandStyle { + COALESCED, NONCOALESCED + } + + /** + * Holds cache information for a given command. + * @param <V> Type matches the result type associated with the command. + */ + class CommandInfo { + + /* + * Control variables. + */ + + /** List of the request monitors associated with this command */ + private final List<DataRequestMonitor<ICommandResult>> fCurrentRequestMonitors; + + /** Original command. Need for reference from Queue completion notification */ + private final ICommand<ICommandResult> fCommand; + + /** Style of this command ( internal coalesced or not) */ + private final CommandStyle fCmdStyle; + + /** Command being processed for this command */ + private CommandInfo fCoalescedCmd; + + private ICommandToken fToken; + + public CommandInfo(CommandStyle cmdstyle, ICommand<ICommandResult> cmd, DataRequestMonitor<ICommandResult> rm) { + fCmdStyle = cmdstyle; + fCommand = cmd; + fCurrentRequestMonitors = new LinkedList<DataRequestMonitor<ICommandResult>>(); + fCurrentRequestMonitors.add(rm); + fCoalescedCmd = null; + } + + public CommandStyle getCommandstyle() { + return fCmdStyle; + } + + public List<DataRequestMonitor<ICommandResult>> getRequestMonitorList() { + return fCurrentRequestMonitors; + } + + public ICommand<ICommandResult> getCommand() { + return fCommand; + } + + public CommandInfo getCoalescedCmd() { + return fCoalescedCmd; + } + + public void setCoalescedCmd(CommandInfo cmd) { + fCoalescedCmd = cmd; + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof CommandInfo)) + return false; + CommandInfo otherCmd = (CommandInfo) other; + + return otherCmd.fCommand.equals(fCommand); + } + + @Override + public int hashCode() { + return fCommand.hashCode(); + } + } + + class CommandResultInfo { + private final ICommandResult fData; + private final IStatus fStatus; + + public CommandResultInfo(ICommandResult data, IStatus status) { + fData = data; + fStatus = status; + } + + public ICommandResult getData() { + return fData; + } + + public IStatus getStatus() { + return fStatus; + } + } + + private DsfSession fSession; + + /** + * The command control to be used to send commands to the backend. + * In certain cases, a {@link BufferedCommandControl} should be used + * to artificially delay the processing of command results; these + * artificial delays are important to keep events and command results + * ordered as received by the backend. + */ + private ICommandControl fCommandControl; + + /* + * This class contains 5 significant lists. + * + * Cached Results : + * + * Contains a mapping of commands and their completed results. Until the cached + * results are cleared by the owner of the cache. + * + * Pending Commands Not Queued : + * + * The Control object has not yet indicated that it has recognized the command + * yet. The user is not allowed to interrogate these objects until the Control + * object indicates they have been queued ( commandQueued notification ). + * + * Pending Commands Unsent : + * + * This is the list of commands which have been issued to the Control object but + * have not been actually issued to the backend. These commands represent coalesce + * options. They may be compared against the Queued list being maintained by the + * Control object until told otherwise - commandSent notification ). + * + * Pending Commands Sent : + * + * This is a list of commands which have been issued to the Control object and + * have also been sent to the backend. It is not possible use these objects for + * coalescents. + * + * Coalesced Pending Q : + * + * These represent original commands for which a new coalesced command has been + * created. When the coalesced commands completes the results will be decomposed + * when back into individual results from this command. + */ + private Set<IDMContext> fAvailableContexts = new HashSet<IDMContext>(); + + private Map<IDMContext, HashMap<CommandInfo, CommandResultInfo>> fCachedContexts = new HashMap<IDMContext, HashMap<CommandInfo, CommandResultInfo>>(); + + private ArrayList<CommandInfo> fPendingQCommandsSent = new ArrayList<CommandInfo>(); + + private ArrayList<CommandInfo> fPendingQCommandsNotYetSent = new ArrayList<CommandInfo>(); + + private ArrayList<CommandInfo> fPendingQWaitingForCoalescedCompletion = new ArrayList<CommandInfo>(); + + private static boolean DEBUG = false; private static final String CACHE_TRACE_IDENTIFIER = " [CHE]"; //$NON-NLS-1$ private static String BLANK_CACHE_TRACE_IDENTIFIER = ""; //$NON-NLS-1$ static { - DEBUG = Boolean.parseBoolean(Platform.getDebugOption("org.eclipse.cdt.dsf/debugCache")); //$NON-NLS-1$ - for (int i=0; i<CACHE_TRACE_IDENTIFIER.length(); i++) { + DEBUG = Boolean.parseBoolean(Platform.getDebugOption("org.eclipse.cdt.dsf/debugCache")); //$NON-NLS-1$ + for (int i = 0; i < CACHE_TRACE_IDENTIFIER.length(); i++) { BLANK_CACHE_TRACE_IDENTIFIER += " "; //$NON-NLS-1$ } - } + } private void debug(String message) { debug(message, ""); //$NON-NLS-1$ - } - - private void debug(String message, String prefix) { - if (DEBUG) { - // The message can span more than one line - String[] multiLine = message.split("\n"); //$NON-NLS-1$ - + } + + private void debug(String message, String prefix) { + if (DEBUG) { + // The message can span more than one line + String[] multiLine = message.split("\n"); //$NON-NLS-1$ + // Create a blank prefix for proper alignment - String blankPrefix = ""; //$NON-NLS-1$ - for (int i=0; i<prefix.length(); i++) { - blankPrefix += " "; //$NON-NLS-1$ - } - - for (int i = 0; i < multiLine.length; i++) { - String traceIdentifier; - if (i == 0) { - // For the first line we prepend the cache identifier string - traceIdentifier = CACHE_TRACE_IDENTIFIER + prefix; - - } else { - // For all other lines we prepend a blank prefix for proper alignment - traceIdentifier = BLANK_CACHE_TRACE_IDENTIFIER + blankPrefix; - } - - message = DsfPlugin.getDebugTime() + traceIdentifier + - " " + multiLine[i]; //$NON-NLS-1$ - - // Make sure our lines are not too long - while (message.length() > 100) { - String partial = message.substring(0, 100) + "\\"; //$NON-NLS-1$ - message = message.substring(100); - System.out.println(partial); - } - System.out.println(message); - } - } - } - - public CommandCache(DsfSession session, ICommandControl control) { - fSession = session; - fCommandControl = control; + String blankPrefix = ""; //$NON-NLS-1$ + for (int i = 0; i < prefix.length(); i++) { + blankPrefix += " "; //$NON-NLS-1$ + } + + for (int i = 0; i < multiLine.length; i++) { + String traceIdentifier; + if (i == 0) { + // For the first line we prepend the cache identifier string + traceIdentifier = CACHE_TRACE_IDENTIFIER + prefix; + + } else { + // For all other lines we prepend a blank prefix for proper alignment + traceIdentifier = BLANK_CACHE_TRACE_IDENTIFIER + blankPrefix; + } + + message = DsfPlugin.getDebugTime() + traceIdentifier + " " + multiLine[i]; //$NON-NLS-1$ + + // Make sure our lines are not too long + while (message.length() > 100) { + String partial = message.substring(0, 100) + "\\"; //$NON-NLS-1$ + message = message.substring(100); + System.out.println(partial); + } + System.out.println(message); + } + } + } + + public CommandCache(DsfSession session, ICommandControl control) { + fSession = session; + fCommandControl = control; /* * We listen for the notifications that the commands have been sent to * their intended target via the ICommandControl service. */ - fCommandControl.addCommandListener(this); - } - - /* - * Constructs a coalesced command if possible. - */ - private CommandInfo getCoalescedCommand(CommandInfo cmd) { - - for ( CommandInfo currentUnsentEntry : new ArrayList<CommandInfo>(fPendingQCommandsNotYetSent) ) { - /* - * Get the current unsent entry to determine if we can coalesced with it. - */ - ICommand<?> unsentCommand = currentUnsentEntry.getCommand(); - - /* - * Check if we can so construct a new COALESCED command from scratch. - */ - - // For sanity's sake, cast the generic ?'s to concrete types in the cache implementation. - @SuppressWarnings("unchecked") - ICommand<ICommandResult> coalescedCmd = - (ICommand<ICommandResult>)unsentCommand.coalesceWith( cmd.getCommand() ); - - if ( coalescedCmd != null ) { - CommandInfo coalescedCmdInfo = new CommandInfo( CommandStyle.COALESCED, coalescedCmd, null) ; - - if ( currentUnsentEntry.getCommandstyle() == CommandStyle.COALESCED ) { - /* - * We matched a command which is itself already a COALESCED command. So - * we need to run through the reference list and point all the current - * command which are referencing the command we just subsumed and change - * them to point to the new super command. - */ - - for ( CommandInfo waitingEntry : new ArrayList<CommandInfo>(fPendingQWaitingForCoalescedCompletion) ) { - - if ( waitingEntry.getCoalescedCmd() == currentUnsentEntry ) { - /* - * This referenced the old command change it to point to the new one. - */ - waitingEntry.setCoalescedCmd(coalescedCmdInfo); - } - } - } else { - /* - * This currently unsent entry needs to go into the coalescing list. To - * be completed when the coalesced command comes back with a result. - */ - fPendingQWaitingForCoalescedCompletion.add(currentUnsentEntry); - currentUnsentEntry.setCoalescedCmd(coalescedCmdInfo); - } - - /* - * Either way we want to take the command back from the Control object so it - * does not continue to process it. - */ - fPendingQCommandsNotYetSent.remove(currentUnsentEntry); - fCommandControl.removeCommand(currentUnsentEntry.fToken); - - return( coalescedCmdInfo ); - } - } - - return null; - } - - /** - * Executes given ICommand, or retrieves the cached result if known. - * @param command Command to execute. - * @param rm Return token, contains the retrieved MIInfo object as - * well as its cache status. - */ - public <V extends ICommandResult> void execute(ICommand<V> command, DataRequestMonitor<V> rm) { - assert fSession.getExecutor().isInExecutorThread(); - - // Cast the generic ?'s to concrete types in the cache implementation. - @SuppressWarnings("unchecked") - final ICommand<ICommandResult> genericCommand = (ICommand<ICommandResult>)command; - @SuppressWarnings("unchecked") - final DataRequestMonitor<ICommandResult> genericDone = (DataRequestMonitor<ICommandResult>) rm; - - CommandInfo cachedCmd = new CommandInfo( CommandStyle.NONCOALESCED, genericCommand, genericDone) ; - - final IDMContext context = genericCommand.getContext(); - - /* - * If command is already cached, just return the cached data. - */ - if(fCachedContexts.get(context) != null && fCachedContexts.get(context).containsKey(cachedCmd)){ - CommandResultInfo result = fCachedContexts.get(context).get(cachedCmd); - debug(command.toString().trim()); - if (result.getStatus().getSeverity() <= IStatus.INFO) { - @SuppressWarnings("unchecked") - V v = (V)result.getData(); - rm.setData(v); - debug(v.toString()); - } else { - rm.setStatus(result.getStatus()); - debug(result.getStatus().toString()); - } - rm.done(); - return; - } - - /* - * Return an error if the target is available anymore. - */ - if (!isTargetAvailable(command.getContext())) { - debug(command.toString().trim(), "[N/A]"); //$NON-NLS-1$ - - rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Target not available.", null)); //$NON-NLS-1$ - rm.done(); - return; - } - - /* - * If we are already waiting for this command to complete, - * add this request monitor to list of waiting monitors. - */ - for ( CommandInfo sentCommand : fPendingQCommandsSent ) { - if ( sentCommand.equals( cachedCmd )) { - sentCommand.getRequestMonitorList().add(genericDone); - debug(command.toString().trim(), "[SNT]"); //$NON-NLS-1$ - return; - } - } - for ( CommandInfo notYetSentCommand : fPendingQCommandsNotYetSent ) { - if ( notYetSentCommand.equals( cachedCmd )) { - notYetSentCommand.getRequestMonitorList().add(genericDone); - debug(command.toString().trim(), "[SND]"); //$NON-NLS-1$ - return; - } - } - - - /* - * We see if this command can be combined into a coalesced one. The - * coalesce routine will take care of the already enqueued one which - * this command is being coalesced with. - */ - - CommandInfo coalescedCmd = getCoalescedCommand(cachedCmd); - - if ( coalescedCmd != null ) { - /* - * The original command we were handed needs to go into the waiting QUEUE. - * We also need to point it it to the coalesced command. - */ - fPendingQWaitingForCoalescedCompletion.add(cachedCmd); - cachedCmd.setCoalescedCmd(coalescedCmd); - cachedCmd = coalescedCmd; - } - - /* - * Now we have a command to send ( coalesced or not ). Put it in the cannot touch - * it list and give it to the Control object. Our state handlers will move it into - * the proper list as the Control object deals with it. - */ - final CommandInfo finalCachedCmd = cachedCmd; - fPendingQCommandsNotYetSent.add(finalCachedCmd); - - finalCachedCmd.fToken = fCommandControl.queueCommand( - finalCachedCmd.getCommand(), - new DataRequestMonitor<ICommandResult>(ImmediateExecutor.getInstance(), null) { - @Override - public synchronized void done() { - // protect against the cache being called in non-session thread, but at - // the same time avoid adding extra dispatch cycles to command processing. - if (fSession.getExecutor().isInExecutorThread()) {; - super.done(); - } else { - fSession.getExecutor().execute(new DsfRunnable() { - @Override - public void run() { - superDone(); - } - }); - } - } - private void superDone() { - super.done(); - } - @Override - public void handleCompleted() { - - /* - * Match this up with a command set we know about. - */ - if ( ! fPendingQCommandsSent.remove(finalCachedCmd) ) { - /* - * This can happen if the call to queueCommand() completes without - * actually having to send the command. In that case, we should find - * our command in the fPendingQCommandsNotYetSent queue. - * For example, upon termination some queueCommand() implementation - * may complete immediately with an error status. Bug 309309 - */ - if ( ! fPendingQCommandsNotYetSent.remove(finalCachedCmd) ) { - assert false : "Missing command"; //$NON-NLS-1$ - return; - } - } - - ICommandResult result = getData(); - IStatus status = getStatus(); - - if ( finalCachedCmd.getCommandstyle() == CommandStyle.COALESCED ) { - /* - * We matched a command which is itself already a COALESCED command. So - * we need to go through the list of unsent commands which were not sent - * because the coalesced command represented it. For each match we find - * we create a new result from the coalesced command for it. - */ - - for ( CommandInfo waitingEntry : new ArrayList<CommandInfo>(fPendingQWaitingForCoalescedCompletion) ) { - - if ( waitingEntry.getCoalescedCmd() == finalCachedCmd ) { - - /* - * Remove this entry from the list since we can complete it. - */ - fPendingQWaitingForCoalescedCompletion.remove(waitingEntry); - - // Cast the calculated result back to the requested type. - @SuppressWarnings("unchecked") - V subResult = (V)result.getSubsetResult(waitingEntry.getCommand()); - CommandResultInfo subResultInfo = new CommandResultInfo(subResult, status); - - if(fCachedContexts.get(context) != null){ - fCachedContexts.get(context).put(waitingEntry, subResultInfo); - } else { - HashMap<CommandInfo, CommandResultInfo> map = new HashMap<CommandInfo, CommandResultInfo>(); - map.put(waitingEntry, subResultInfo); - fCachedContexts.put(context, map); - } - - if (!isSuccess()) { - - /* - * We had some form of error with the original command. So notify the - * original requesters of the issues. - */ - for (DataRequestMonitor<?> pendingRM : waitingEntry.getRequestMonitorList()) { - pendingRM.setStatus(status); - pendingRM.done(); - } - } else { - assert subResult != null; - - /* - * Notify the original requesters of the positive results. - */ - for (DataRequestMonitor<? extends ICommandResult> pendingRM : waitingEntry.getRequestMonitorList()) { - // Cast the pending return token to match the requested type. - @SuppressWarnings("unchecked") - DataRequestMonitor<V> vPendingRM = (DataRequestMonitor<V>) pendingRM; - - vPendingRM.setData(subResult); - vPendingRM.done(); - } - } - } - } - } else { - // Save the command result in cache, but only if the command's context - // is still available. Otherwise an error may get cached incorrectly. - if (isTargetAvailable(context)) { - CommandResultInfo resultInfo = new CommandResultInfo(result, status); - - if (fCachedContexts.get(context) != null){ - fCachedContexts.get(context).put(finalCachedCmd, resultInfo); - } else { - HashMap<CommandInfo, CommandResultInfo> map = new HashMap<CommandInfo, CommandResultInfo>(); - map.put(finalCachedCmd, resultInfo); - fCachedContexts.put(context, map); - } - } - // This is an original request which completed. Indicate success or - // failure to the original requesters. - if (!isSuccess()) { - /* - * We had some form of error with the original command. So notify the - * original requesters of the issues. - */ - for (DataRequestMonitor<?> pendingRM : finalCachedCmd.getRequestMonitorList()) { - pendingRM.setStatus(status); - pendingRM.done(); - } - } else { - // Cast the calculated result back to the requested type. - @SuppressWarnings("unchecked") - V vResult = (V)result; - - for (DataRequestMonitor<? extends ICommandResult> pendingRM : finalCachedCmd.getRequestMonitorList()) { - // Cast the pending return token to match the requested type. - @SuppressWarnings("unchecked") - DataRequestMonitor<V> vPendingRM = (DataRequestMonitor<V>) pendingRM; - - vPendingRM.setData(vResult); - vPendingRM.done(); - } - } - } - } - }); - } - - /** - * TODO - */ - public void setContextAvailable(IDMContext context, boolean isAvailable) { - if (isAvailable) { - fAvailableContexts.add(context); - } else { - fAvailableContexts.remove(context); - for (Iterator<IDMContext> itr = fAvailableContexts.iterator(); itr.hasNext();) { - if (DMContexts.isAncestorOf(context, itr.next())) { - itr.remove(); - } - } - } - } - - /** - * TODO - * @see #setContextAvailable(IDMContext, boolean) - */ - public boolean isTargetAvailable(IDMContext context) { - for (IDMContext availableContext : fAvailableContexts) { - if (context.equals(availableContext) || DMContexts.isAncestorOf(context, availableContext)) { - return true; - } - } - return false; - } + fCommandControl.addCommandListener(this); + } + + /* + * Constructs a coalesced command if possible. + */ + private CommandInfo getCoalescedCommand(CommandInfo cmd) { + + for (CommandInfo currentUnsentEntry : new ArrayList<CommandInfo>(fPendingQCommandsNotYetSent)) { + /* + * Get the current unsent entry to determine if we can coalesced with it. + */ + ICommand<?> unsentCommand = currentUnsentEntry.getCommand(); + + /* + * Check if we can so construct a new COALESCED command from scratch. + */ + + // For sanity's sake, cast the generic ?'s to concrete types in the cache implementation. + @SuppressWarnings("unchecked") + ICommand<ICommandResult> coalescedCmd = (ICommand<ICommandResult>) unsentCommand + .coalesceWith(cmd.getCommand()); + + if (coalescedCmd != null) { + CommandInfo coalescedCmdInfo = new CommandInfo(CommandStyle.COALESCED, coalescedCmd, null); + + if (currentUnsentEntry.getCommandstyle() == CommandStyle.COALESCED) { + /* + * We matched a command which is itself already a COALESCED command. So + * we need to run through the reference list and point all the current + * command which are referencing the command we just subsumed and change + * them to point to the new super command. + */ + + for (CommandInfo waitingEntry : new ArrayList<CommandInfo>( + fPendingQWaitingForCoalescedCompletion)) { + + if (waitingEntry.getCoalescedCmd() == currentUnsentEntry) { + /* + * This referenced the old command change it to point to the new one. + */ + waitingEntry.setCoalescedCmd(coalescedCmdInfo); + } + } + } else { + /* + * This currently unsent entry needs to go into the coalescing list. To + * be completed when the coalesced command comes back with a result. + */ + fPendingQWaitingForCoalescedCompletion.add(currentUnsentEntry); + currentUnsentEntry.setCoalescedCmd(coalescedCmdInfo); + } + + /* + * Either way we want to take the command back from the Control object so it + * does not continue to process it. + */ + fPendingQCommandsNotYetSent.remove(currentUnsentEntry); + fCommandControl.removeCommand(currentUnsentEntry.fToken); + + return (coalescedCmdInfo); + } + } + + return null; + } + + /** + * Executes given ICommand, or retrieves the cached result if known. + * @param command Command to execute. + * @param rm Return token, contains the retrieved MIInfo object as + * well as its cache status. + */ + public <V extends ICommandResult> void execute(ICommand<V> command, DataRequestMonitor<V> rm) { + assert fSession.getExecutor().isInExecutorThread(); + + // Cast the generic ?'s to concrete types in the cache implementation. + @SuppressWarnings("unchecked") + final ICommand<ICommandResult> genericCommand = (ICommand<ICommandResult>) command; + @SuppressWarnings("unchecked") + final DataRequestMonitor<ICommandResult> genericDone = (DataRequestMonitor<ICommandResult>) rm; + + CommandInfo cachedCmd = new CommandInfo(CommandStyle.NONCOALESCED, genericCommand, genericDone); + + final IDMContext context = genericCommand.getContext(); + + /* + * If command is already cached, just return the cached data. + */ + if (fCachedContexts.get(context) != null && fCachedContexts.get(context).containsKey(cachedCmd)) { + CommandResultInfo result = fCachedContexts.get(context).get(cachedCmd); + debug(command.toString().trim()); + if (result.getStatus().getSeverity() <= IStatus.INFO) { + @SuppressWarnings("unchecked") + V v = (V) result.getData(); + rm.setData(v); + debug(v.toString()); + } else { + rm.setStatus(result.getStatus()); + debug(result.getStatus().toString()); + } + rm.done(); + return; + } + + /* + * Return an error if the target is available anymore. + */ + if (!isTargetAvailable(command.getContext())) { + debug(command.toString().trim(), "[N/A]"); //$NON-NLS-1$ + + rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, + "Target not available.", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + /* + * If we are already waiting for this command to complete, + * add this request monitor to list of waiting monitors. + */ + for (CommandInfo sentCommand : fPendingQCommandsSent) { + if (sentCommand.equals(cachedCmd)) { + sentCommand.getRequestMonitorList().add(genericDone); + debug(command.toString().trim(), "[SNT]"); //$NON-NLS-1$ + return; + } + } + for (CommandInfo notYetSentCommand : fPendingQCommandsNotYetSent) { + if (notYetSentCommand.equals(cachedCmd)) { + notYetSentCommand.getRequestMonitorList().add(genericDone); + debug(command.toString().trim(), "[SND]"); //$NON-NLS-1$ + return; + } + } + + /* + * We see if this command can be combined into a coalesced one. The + * coalesce routine will take care of the already enqueued one which + * this command is being coalesced with. + */ + + CommandInfo coalescedCmd = getCoalescedCommand(cachedCmd); + + if (coalescedCmd != null) { + /* + * The original command we were handed needs to go into the waiting QUEUE. + * We also need to point it it to the coalesced command. + */ + fPendingQWaitingForCoalescedCompletion.add(cachedCmd); + cachedCmd.setCoalescedCmd(coalescedCmd); + cachedCmd = coalescedCmd; + } + + /* + * Now we have a command to send ( coalesced or not ). Put it in the cannot touch + * it list and give it to the Control object. Our state handlers will move it into + * the proper list as the Control object deals with it. + */ + final CommandInfo finalCachedCmd = cachedCmd; + fPendingQCommandsNotYetSent.add(finalCachedCmd); + + finalCachedCmd.fToken = fCommandControl.queueCommand(finalCachedCmd.getCommand(), + new DataRequestMonitor<ICommandResult>(ImmediateExecutor.getInstance(), null) { + @Override + public synchronized void done() { + // protect against the cache being called in non-session thread, but at + // the same time avoid adding extra dispatch cycles to command processing. + if (fSession.getExecutor().isInExecutorThread()) { + ; + super.done(); + } else { + fSession.getExecutor().execute(new DsfRunnable() { + @Override + public void run() { + superDone(); + } + }); + } + } + + private void superDone() { + super.done(); + } + + @Override + public void handleCompleted() { + + /* + * Match this up with a command set we know about. + */ + if (!fPendingQCommandsSent.remove(finalCachedCmd)) { + /* + * This can happen if the call to queueCommand() completes without + * actually having to send the command. In that case, we should find + * our command in the fPendingQCommandsNotYetSent queue. + * For example, upon termination some queueCommand() implementation + * may complete immediately with an error status. Bug 309309 + */ + if (!fPendingQCommandsNotYetSent.remove(finalCachedCmd)) { + assert false : "Missing command"; //$NON-NLS-1$ + return; + } + } + + ICommandResult result = getData(); + IStatus status = getStatus(); + + if (finalCachedCmd.getCommandstyle() == CommandStyle.COALESCED) { + /* + * We matched a command which is itself already a COALESCED command. So + * we need to go through the list of unsent commands which were not sent + * because the coalesced command represented it. For each match we find + * we create a new result from the coalesced command for it. + */ + + for (CommandInfo waitingEntry : new ArrayList<CommandInfo>( + fPendingQWaitingForCoalescedCompletion)) { + + if (waitingEntry.getCoalescedCmd() == finalCachedCmd) { + + /* + * Remove this entry from the list since we can complete it. + */ + fPendingQWaitingForCoalescedCompletion.remove(waitingEntry); + + // Cast the calculated result back to the requested type. + @SuppressWarnings("unchecked") + V subResult = (V) result.getSubsetResult(waitingEntry.getCommand()); + CommandResultInfo subResultInfo = new CommandResultInfo(subResult, status); + + if (fCachedContexts.get(context) != null) { + fCachedContexts.get(context).put(waitingEntry, subResultInfo); + } else { + HashMap<CommandInfo, CommandResultInfo> map = new HashMap<CommandInfo, CommandResultInfo>(); + map.put(waitingEntry, subResultInfo); + fCachedContexts.put(context, map); + } + + if (!isSuccess()) { + + /* + * We had some form of error with the original command. So notify the + * original requesters of the issues. + */ + for (DataRequestMonitor<?> pendingRM : waitingEntry.getRequestMonitorList()) { + pendingRM.setStatus(status); + pendingRM.done(); + } + } else { + assert subResult != null; + + /* + * Notify the original requesters of the positive results. + */ + for (DataRequestMonitor<? extends ICommandResult> pendingRM : waitingEntry + .getRequestMonitorList()) { + // Cast the pending return token to match the requested type. + @SuppressWarnings("unchecked") + DataRequestMonitor<V> vPendingRM = (DataRequestMonitor<V>) pendingRM; + + vPendingRM.setData(subResult); + vPendingRM.done(); + } + } + } + } + } else { + // Save the command result in cache, but only if the command's context + // is still available. Otherwise an error may get cached incorrectly. + if (isTargetAvailable(context)) { + CommandResultInfo resultInfo = new CommandResultInfo(result, status); + + if (fCachedContexts.get(context) != null) { + fCachedContexts.get(context).put(finalCachedCmd, resultInfo); + } else { + HashMap<CommandInfo, CommandResultInfo> map = new HashMap<CommandInfo, CommandResultInfo>(); + map.put(finalCachedCmd, resultInfo); + fCachedContexts.put(context, map); + } + } + // This is an original request which completed. Indicate success or + // failure to the original requesters. + if (!isSuccess()) { + /* + * We had some form of error with the original command. So notify the + * original requesters of the issues. + */ + for (DataRequestMonitor<?> pendingRM : finalCachedCmd.getRequestMonitorList()) { + pendingRM.setStatus(status); + pendingRM.done(); + } + } else { + // Cast the calculated result back to the requested type. + @SuppressWarnings("unchecked") + V vResult = (V) result; + + for (DataRequestMonitor<? extends ICommandResult> pendingRM : finalCachedCmd + .getRequestMonitorList()) { + // Cast the pending return token to match the requested type. + @SuppressWarnings("unchecked") + DataRequestMonitor<V> vPendingRM = (DataRequestMonitor<V>) pendingRM; + + vPendingRM.setData(vResult); + vPendingRM.done(); + } + } + } + } + }); + } + + /** + * TODO + */ + public void setContextAvailable(IDMContext context, boolean isAvailable) { + if (isAvailable) { + fAvailableContexts.add(context); + } else { + fAvailableContexts.remove(context); + for (Iterator<IDMContext> itr = fAvailableContexts.iterator(); itr.hasNext();) { + if (DMContexts.isAncestorOf(context, itr.next())) { + itr.remove(); + } + } + } + } + + /** + * TODO + * @see #setContextAvailable(IDMContext, boolean) + */ + public boolean isTargetAvailable(IDMContext context) { + for (IDMContext availableContext : fAvailableContexts) { + if (context.equals(availableContext) || DMContexts.isAncestorOf(context, availableContext)) { + return true; + } + } + return false; + } /** * Clears all the cache data. Equivalent to <code>reset(null)</code>. */ - public void reset() { - fCachedContexts.clear(); - } - - @Override - public void commandRemoved(ICommandToken token) { - /* - * Do nothing. - */ - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.dsf.debug.service.command.ICommandListener#commandQueued(org.eclipse.cdt.dsf.debug.service.command.ICommandToken) - */ - @Override - public void commandQueued(ICommandToken token) { - /* - * Do nothing. - */ - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.dsf.debug.service.command.ICommandListener#commandDone(org.eclipse.cdt.dsf.debug.service.command.ICommandToken, org.eclipse.cdt.dsf.debug.service.command.ICommandResult) - */ - @Override - public void commandDone(ICommandToken token, ICommandResult result) { - /* - * We handle the done with a runnable where we initiated the command - * so there is nothing to do here. - */ - } - - /* - * Move the command into our internal sent list. This means we can no longer look at - * this command for possible coalescence since it has been given to the debug engine - * and is currently being processed. - * - * @see org.eclipse.cdt.dsf.debug.service.command.ICommandListener#commandSent(org.eclipse.cdt.dsf.debug.service.command.ICommandToken) - */ - @Override - public void commandSent(ICommandToken token) { - - // Cast the generic ?'s to concrete types in the cache implementation. - @SuppressWarnings("unchecked") - ICommand<ICommandResult> genericCommand = (ICommand<ICommandResult>)token.getCommand(); - - CommandInfo cachedCmd = new CommandInfo( CommandStyle.NONCOALESCED, genericCommand, null) ; - - // It is important to actually fetch the content of the fPendingQCommandsNotYetSent map - // instead of only using 'cachedCmd'. This is because although cachedCmd can be considered - // equal to unqueuedCommand, it is not identical and we need the full content of unqueuedCommand. - // For instance, cachedCmd does not have the list of requestMonitors that unqueuedCommand has. - for ( CommandInfo unqueuedCommand : new ArrayList<CommandInfo>(fPendingQCommandsNotYetSent) ) { - if ( unqueuedCommand.equals( cachedCmd )) { - fPendingQCommandsNotYetSent.remove(unqueuedCommand); - fPendingQCommandsSent.add(unqueuedCommand); - break; - } - } - } - + public void reset() { + fCachedContexts.clear(); + } + + @Override + public void commandRemoved(ICommandToken token) { + /* + * Do nothing. + */ + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.service.command.ICommandListener#commandQueued(org.eclipse.cdt.dsf.debug.service.command.ICommandToken) + */ + @Override + public void commandQueued(ICommandToken token) { + /* + * Do nothing. + */ + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.service.command.ICommandListener#commandDone(org.eclipse.cdt.dsf.debug.service.command.ICommandToken, org.eclipse.cdt.dsf.debug.service.command.ICommandResult) + */ + @Override + public void commandDone(ICommandToken token, ICommandResult result) { + /* + * We handle the done with a runnable where we initiated the command + * so there is nothing to do here. + */ + } + + /* + * Move the command into our internal sent list. This means we can no longer look at + * this command for possible coalescence since it has been given to the debug engine + * and is currently being processed. + * + * @see org.eclipse.cdt.dsf.debug.service.command.ICommandListener#commandSent(org.eclipse.cdt.dsf.debug.service.command.ICommandToken) + */ + @Override + public void commandSent(ICommandToken token) { + + // Cast the generic ?'s to concrete types in the cache implementation. + @SuppressWarnings("unchecked") + ICommand<ICommandResult> genericCommand = (ICommand<ICommandResult>) token.getCommand(); + + CommandInfo cachedCmd = new CommandInfo(CommandStyle.NONCOALESCED, genericCommand, null); + + // It is important to actually fetch the content of the fPendingQCommandsNotYetSent map + // instead of only using 'cachedCmd'. This is because although cachedCmd can be considered + // equal to unqueuedCommand, it is not identical and we need the full content of unqueuedCommand. + // For instance, cachedCmd does not have the list of requestMonitors that unqueuedCommand has. + for (CommandInfo unqueuedCommand : new ArrayList<CommandInfo>(fPendingQCommandsNotYetSent)) { + if (unqueuedCommand.equals(cachedCmd)) { + fPendingQCommandsNotYetSent.remove(unqueuedCommand); + fPendingQCommandsSent.add(unqueuedCommand); + break; + } + } + } + /** - * Clears the cache entries for given context. Clears the whole cache if + * Clears the cache entries for given context. Clears the whole cache if * context parameter is null. */ public void reset(IDMContext dmc) { - if (dmc == null) { - fCachedContexts.clear(); - return; - } - for (Iterator<IDMContext> itr = fCachedContexts.keySet().iterator(); itr.hasNext();) { - IDMContext keyDmc = itr.next(); - if (keyDmc != null && (dmc.equals(keyDmc) || DMContexts.isAncestorOf(keyDmc, dmc))) { - itr.remove(); - } - } + if (dmc == null) { + fCachedContexts.clear(); + return; + } + for (Iterator<IDMContext> itr = fCachedContexts.keySet().iterator(); itr.hasNext();) { + IDMContext keyDmc = itr.next(); + if (keyDmc != null && (dmc.equals(keyDmc) || DMContexts.isAncestorOf(keyDmc, dmc))) { + itr.remove(); + } + } } } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommand.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommand.java index 7597a2fc458..586bce0b0f2 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommand.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommand.java @@ -7,44 +7,41 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation - * Ericsson - Modified for additional features in DSF Reference implementation + * Ericsson - Modified for additional features in DSF Reference implementation *******************************************************************************/ - + package org.eclipse.cdt.dsf.debug.service.command; import org.eclipse.cdt.dsf.datamodel.IDMContext; - /** * Command interface for creating and manipulating GDB/MI commands * for the DSF GDB reference implementation. The command represents * the GDB/MI request which will be put on the wire to the GDB - * backend. - * + * backend. + * * @since 1.0 */ public interface ICommand<V extends ICommandResult> { - /** - * Takes the supplied command and coalesces it with this one. - * The result is a new third command which represent the two - * original commands. - * <br>Note: the result type associated with the returned command may be - * different than the result type associated with either of the commands - * being coalesced. - * - * @return newly created command, or null if command cannot be coalesced - */ - public ICommand<? extends ICommandResult> coalesceWith( ICommand<? extends ICommandResult> command ); - - /** - * Returns the context that this command is to be evaluated in. May be null - * if the command does not need to be evaluated in a specific context. - */ - public IDMContext getContext(); -} + /** + * Takes the supplied command and coalesces it with this one. + * The result is a new third command which represent the two + * original commands. + * <br>Note: the result type associated with the returned command may be + * different than the result type associated with either of the commands + * being coalesced. + * + * @return newly created command, or null if command cannot be coalesced + */ + public ICommand<? extends ICommandResult> coalesceWith(ICommand<? extends ICommandResult> command); - + /** + * Returns the context that this command is to be evaluated in. May be null + * if the command does not need to be evaluated in a specific context. + */ + public IDMContext getContext(); +} diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommandControl.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommandControl.java index 4cb05129e36..5f9e0c45fc5 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommandControl.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommandControl.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ @@ -19,59 +19,59 @@ import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; * API for sending commands to the debugger and for receiving command results * and asynchronous events. The command control may be implemented by a service * or a non-service object. - * + * * @see ICommandControlService - * + * * @since 1.0 */ public interface ICommandControl { - /** - * Adds the specified command to the queue of commands to be processed. - * - * @param command Specific command to be processed - * @param rm Request completion monitor - * @return None - */ - <V extends ICommandResult> ICommandToken queueCommand(ICommand<V> command, DataRequestMonitor<V> rm); - - /** - * Removes the specified command from the processor queue. - * - * @param command Specific command to be removed - * @return None - */ - void removeCommand(ICommandToken token); - - /** + /** + * Adds the specified command to the queue of commands to be processed. + * + * @param command Specific command to be processed + * @param rm Request completion monitor + * @return None + */ + <V extends ICommandResult> ICommandToken queueCommand(ICommand<V> command, DataRequestMonitor<V> rm); + + /** + * Removes the specified command from the processor queue. + * + * @param command Specific command to be removed + * @return None + */ + void removeCommand(ICommandToken token); + + /** * Adds a notification handler for the Command processor. - * + * * @param command listener to be added * @return None */ - void addCommandListener(ICommandListener listener); - - /** + void addCommandListener(ICommandListener listener); + + /** * Removes a notification handler for the Command processor. - * + * * @param command listener to be removed * @return None */ - void removeCommandListener(ICommandListener listener); - - /** + void removeCommandListener(ICommandListener listener); + + /** * Adds a notification handler for the Event processor. - * + * * @param event listener to be added * @return None */ - void addEventListener(IEventListener listener); - - /** + void addEventListener(IEventListener listener); + + /** * Removes a notification handler for the Event processor. - * + * * @param event listener to be removed * @return None */ - void removeEventListener(IEventListener listener); + void removeEventListener(IEventListener listener); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommandControlService.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommandControlService.java index eef2d0183a4..c80ab6603ac 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommandControlService.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommandControlService.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ @@ -18,53 +18,55 @@ import org.eclipse.cdt.dsf.datamodel.IDMEvent; import org.eclipse.cdt.dsf.service.IDsfService; /** - * Service which acts as a command control. - * + * Service which acts as a command control. + * * @since 1.1 */ public interface ICommandControlService extends ICommandControl, IDsfService { - - /** - * Context representing a command control service. All contexts which - * originate from a given command control service, should have that - * control's context in their hierarchy. - * - * @see ICommandControlService#getContext() - */ - public interface ICommandControlDMContext extends IDMContext { - /** - * Returns the ID of the command control that this context - * represents. - */ - public String getCommandControlId(); - } - - /** - * Event indicating that the back end process has started. - */ - public interface ICommandControlInitializedDMEvent extends IDMEvent<ICommandControlDMContext> {}; - - /** - * Event indicating that the back end process has terminated. - */ - public interface ICommandControlShutdownDMEvent extends IDMEvent<ICommandControlDMContext> {}; - /** - * Returns the identifier of this command control service. It can be used - * to distinguish between multiple instances of command control services. - */ - public String getId(); + /** + * Context representing a command control service. All contexts which + * originate from a given command control service, should have that + * control's context in their hierarchy. + * + * @see ICommandControlService#getContext() + */ + public interface ICommandControlDMContext extends IDMContext { + /** + * Returns the ID of the command control that this context + * represents. + */ + public String getCommandControlId(); + } + + /** + * Event indicating that the back end process has started. + */ + public interface ICommandControlInitializedDMEvent extends IDMEvent<ICommandControlDMContext> { + }; + + /** + * Event indicating that the back end process has terminated. + */ + public interface ICommandControlShutdownDMEvent extends IDMEvent<ICommandControlDMContext> { + }; + + /** + * Returns the identifier of this command control service. It can be used + * to distinguish between multiple instances of command control services. + */ + public String getId(); - /** - * returns the context representing this command control. - */ - public ICommandControlDMContext getContext(); + /** + * returns the context representing this command control. + */ + public ICommandControlDMContext getContext(); - /** - * Returns whether this command control is currently active. A command - * control service is active if it has been initialized and has not yet - * shut down. - * @return - */ - public boolean isActive(); + /** + * Returns whether this command control is currently active. A command + * control service is active if it has been initialized and has not yet + * shut down. + * @return + */ + public boolean isActive(); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommandListener.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommandListener.java index 6c1b7e6a0b9..e6e83b10cc1 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommandListener.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommandListener.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ @@ -17,9 +17,9 @@ import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor; /** * Synchronous listener to commands being sent and received. - * All the registered listeners will be called in the same - * dispatch cycle as when the result of the command is submitted. - * + * All the registered listeners will be called in the same + * dispatch cycle as when the result of the command is submitted. + * * @since 1.0 */ @@ -29,39 +29,39 @@ public interface ICommandListener { * Notifies that the specified command has been added to the Command Queue. * It has not yet been sent. In this state the command can be examined and * possibly withdrawn because it has been coalesced with another command. - * + * * @return None * @param command Command which has been added to the Queue - */ + */ public void commandQueued(ICommandToken token); - + /** - * Notification that the given command was sent to the debugger. At this - * point the command is no longer in the Command Queue and should not be - * examined. The only thing which can be done is to try and cancel the - * command. - * - * @return None - * @param command - */ - public void commandSent(ICommandToken token); + * Notification that the given command was sent to the debugger. At this + * point the command is no longer in the Command Queue and should not be + * examined. The only thing which can be done is to try and cancel the + * command. + * + * @return None + * @param command + */ + public void commandSent(ICommandToken token); /** - * Notifies that the specified command has been removed from the + * Notifies that the specified command has been removed from the * Command Queue. This notification means that the command has * been removed from the queue and not sent to the backend. The * user has specifically removed it, perhaps because it has been - * combined with another. Or some state change has occurred and + * combined with another. Or some state change has occurred and * there is no longer a need to get this particular set of data. - * + * * @return None * @param Command which has been sent to the backend */ public void commandRemoved(ICommandToken token); - + /** * Notifies that the specified command has been completed. - * + * * @return None * @param Command which has been sent to the backend */ diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommandResult.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommandResult.java index d1906a2e9b9..58677182979 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommandResult.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommandResult.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ @@ -18,16 +18,16 @@ package org.eclipse.cdt.dsf.debug.service.command; * @since 1.0 */ public interface ICommandResult { - /** - * Returns an ICommandResult which is a subset command result. The command - * result which is being passed in is from a coalesced command. The result - * which is desired is contained within those results. In this instance we - * are processing the command result from the coalesced command to get our - * command result. - * <i>Note:</i> The type of returned command result must match the type - * associated with the subset command that is passed in the argument. - * - * @return result for this particular command. - */ - public <V extends ICommandResult> V getSubsetResult( ICommand<V> command ); + /** + * Returns an ICommandResult which is a subset command result. The command + * result which is being passed in is from a coalesced command. The result + * which is desired is contained within those results. In this instance we + * are processing the command result from the coalesced command to get our + * command result. + * <i>Note:</i> The type of returned command result must match the type + * associated with the subset command that is passed in the argument. + * + * @return result for this particular command. + */ + public <V extends ICommandResult> V getSubsetResult(ICommand<V> command); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommandToken.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommandToken.java index 1f33fadf961..f1c6f6fc90b 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommandToken.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/ICommandToken.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ @@ -17,12 +17,12 @@ package org.eclipse.cdt.dsf.debug.service.command; * Token returned by ICommandControl.queueCommand(). This token can be used * to uniquely identify a command when calling ICommandControl.removeCommand() * or when implementing the ICommandListener listener methods. - * + * * @since 1.0 */ public interface ICommandToken { - /** - * Returns the command that this was created for. - */ - public ICommand<? extends ICommandResult> getCommand(); + /** + * Returns the command that this was created for. + */ + public ICommand<? extends ICommandResult> getCommand(); }
\ No newline at end of file diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/IEventListener.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/IEventListener.java index a98fc704c45..41b3255bdf6 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/IEventListener.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/command/IEventListener.java @@ -7,7 +7,7 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ @@ -16,18 +16,18 @@ package org.eclipse.cdt.dsf.debug.service.command; import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor; /** - * Synchronous listener for events issued from the debugger. All + * Synchronous listener for events issued from the debugger. All * registered listeners will be called in the same dispatch cycle. - * + * * @since 1.0 */ @ConfinedToDsfExecutor("") public interface IEventListener { - /** - * Notifies that the given asynchronous output was received from the - * debugger. - * @param output output that was received from the debugger. Format - * of the output data is debugger specific. - */ - public void eventReceived(Object output); + /** + * Notifies that the given asynchronous output was received from the + * debugger. + * @param output output that was received from the debugger. Format + * of the output data is debugger specific. + */ + public void eventReceived(Object output); } |