1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

[228062] - [run control][disassembly] Integrate DSF with CDT's toggle instruction step mode action.

This commit is contained in:
Pawel Piech 2008-05-07 17:40:51 +00:00
parent 23afc8c598
commit 05a1a3763b
6 changed files with 227 additions and 119 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006 Wind River Systems and others.
* Copyright (c) 2006, 2008 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -27,11 +27,13 @@ public class DsfStepIntoCommand implements IStepIntoHandler {
private final DsfExecutor fExecutor;
private final DsfServicesTracker fTracker;
private final DsfSteppingModeTarget fSteppingMode;
public DsfStepIntoCommand(DsfSession session) {
public DsfStepIntoCommand(DsfSession session, DsfSteppingModeTarget steppingMode) {
fExecutor = session.getExecutor();
fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
}
fSteppingMode = steppingMode;
}
public void dispose() {
fTracker.dispose();
@ -44,10 +46,11 @@ public class DsfStepIntoCommand implements IStepIntoHandler {
return;
}
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
final StepType stepType= getStepType();
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
@Override public void doExecute() {
getStepQueueMgr().canEnqueueStep(
getContext(), StepType.STEP_INTO,
getContext(), stepType,
new DataRequestMonitor<Boolean>(ImmediateExecutor.getInstance(), null) {
@Override
protected void handleCompleted() {
@ -65,11 +68,21 @@ public class DsfStepIntoCommand implements IStepIntoHandler {
return false;
}
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
final StepType stepType= getStepType();
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
@Override public void doExecute() {
getStepQueueMgr().enqueueStep(getContext(), StepType.STEP_INTO);
getStepQueueMgr().enqueueStep(getContext(), stepType);
}
});
return true;
}
/**
* @return the currently active step type
*/
protected final StepType getStepType() {
boolean instructionSteppingEnabled= fSteppingMode != null && fSteppingMode.isInstructionSteppingEnabled();
return instructionSteppingEnabled ? StepType.INSTRUCTION_STEP_INTO : StepType.STEP_INTO;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006 Wind River Systems and others.
* Copyright (c) 2006, 2008 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -27,11 +27,13 @@ public class DsfStepOverCommand implements IStepOverHandler {
private final DsfExecutor fExecutor;
private final DsfServicesTracker fTracker;
private final DsfSteppingModeTarget fSteppingMode;
public DsfStepOverCommand(DsfSession session) {
public DsfStepOverCommand(DsfSession session, DsfSteppingModeTarget steppingMode) {
fExecutor = session.getExecutor();
fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
}
fSteppingMode = steppingMode;
}
public void dispose() {
fTracker.dispose();
@ -44,10 +46,11 @@ public class DsfStepOverCommand implements IStepOverHandler {
return;
}
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
final StepType stepType= getStepType();
@Override public void doExecute() {
getStepQueueMgr().canEnqueueStep(
getContext(), StepType.STEP_OVER,
getStepQueueMgr().canEnqueueStep(
getContext(), stepType,
new DataRequestMonitor<Boolean>(ImmediateExecutor.getInstance(), null) {
@Override
protected void handleCompleted() {
@ -59,17 +62,27 @@ public class DsfStepOverCommand implements IStepOverHandler {
});
}
public boolean execute(final IDebugCommandRequest request) {
public boolean execute(final IDebugCommandRequest request) {
if (request.getElements().length != 1) {
request.done();
return false;
}
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
final StepType stepType= getStepType();
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
@Override public void doExecute() {
getStepQueueMgr().enqueueStep(getContext(), StepType.STEP_OVER);
getStepQueueMgr().enqueueStep(getContext(), stepType);
}
});
return true;
}
/**
* @return the currently active step type
*/
protected final StepType getStepType() {
boolean instructionSteppingEnabled= fSteppingMode != null && fSteppingMode.isInstructionSteppingEnabled();
return instructionSteppingEnabled ? StepType.INSTRUCTION_STEP_OVER : StepType.STEP_OVER;
}
}

View file

@ -0,0 +1,64 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug.ui.actions;
import org.eclipse.cdt.debug.core.model.ISteppingModeTarget;
import org.eclipse.cdt.debug.core.model.ITargetProperties;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
/**
*/
public class DsfSteppingModeTarget implements ISteppingModeTarget, ITargetProperties {
private final Preferences fPreferences;
public DsfSteppingModeTarget() {
fPreferences= new Preferences();
fPreferences.setDefault(PREF_INSTRUCTION_STEPPING_MODE, false);
}
/*
* @see org.eclipse.cdt.debug.core.model.ISteppingModeTarget#enableInstructionStepping(boolean)
*/
public void enableInstructionStepping(boolean enabled) {
fPreferences.setValue(PREF_INSTRUCTION_STEPPING_MODE, enabled);
}
/*
* @see org.eclipse.cdt.debug.core.model.ISteppingModeTarget#isInstructionSteppingEnabled()
*/
public boolean isInstructionSteppingEnabled() {
return fPreferences.getBoolean(PREF_INSTRUCTION_STEPPING_MODE);
}
/*
* @see org.eclipse.cdt.debug.core.model.ISteppingModeTarget#supportsInstructionStepping()
*/
public boolean supportsInstructionStepping() {
return true;
}
/*
* @see org.eclipse.cdt.debug.core.model.ITargetProperties#addPropertyChangeListener(org.eclipse.core.runtime.Preferences.IPropertyChangeListener)
*/
public void addPropertyChangeListener(IPropertyChangeListener listener) {
fPreferences.addPropertyChangeListener(listener);
}
/*
* @see org.eclipse.cdt.debug.core.model.ITargetProperties#removePropertyChangeListener(org.eclipse.core.runtime.Preferences.IPropertyChangeListener)
*/
public void removePropertyChangeListener(IPropertyChangeListener listener) {
fPreferences.removePropertyChangeListener(listener);
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006 Wind River Systems and others.
* Copyright (c) 2006, 2008 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -46,13 +46,13 @@ import org.eclipse.debug.ui.sourcelookup.ISourceDisplay;
/**
* The adapter factory is the central point of control of view model and other
* UI adapters of a DSF-based debugger. As new launches are created and
* UI adapters of a DSF-based debugger. As new launches are created and
* old ones removed, this factory manages the life cycle of the associated
* UI adapters.
* UI adapters.
* <p>
* As a platform adapter factory, this factory only provides adapters for
* the launch object. Adapters for all other objects in the DSF model hierarchy
* are registered with the DSF session.
* are registered with the DSF session.
* </p>
*/
@ThreadSafe
@ -95,8 +95,8 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
session.registerModelAdapter(ISourceDisplay.class, fSourceDisplayAdapter);
// Initialize retargetable command handler.
fStepIntoCommand = new DsfStepIntoCommand(session);
fStepOverCommand = new DsfStepOverCommand(session);
fStepIntoCommand = new DsfStepIntoCommand(session, null);
fStepOverCommand = new DsfStepOverCommand(session, null);
fStepReturnCommand = new DsfStepReturnCommand(session);
fSuspendCommand = new DsfSuspendCommand(session);
fResumeCommand = new DsfResumeCommand(session);
@ -116,9 +116,9 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
};
session.registerModelAdapter(IDebugModelProvider.class, fDebugModelProvider);
// Register the launch as an adapter This ensures that the launch,
// and debug model ID will be associated with all DMContexts from this
// session.
// Register the launch as an adapter This ensures that the launch,
// and debug model ID will be associated with all DMContexts from this
// session.
session.registerModelAdapter(ILaunch.class, fLaunch);
}
@ -135,33 +135,33 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
session.unregisterModelAdapter(IStepReturnHandler.class);
session.unregisterModelAdapter(ISuspendHandler.class);
session.unregisterModelAdapter(IResumeHandler.class);
session.unregisterModelAdapter(ITerminateHandler.class);
session.unregisterModelAdapter(ITerminateHandler.class);
fStepIntoCommand.dispose();
fStepOverCommand.dispose();
fStepReturnCommand.dispose();
fSuspendCommand.dispose();
fResumeCommand.dispose();
fTerminateCommand.dispose();
}
}
}
}
private Map<PDALaunch, LaunchAdapterSet> fLaunchAdapterSets =
private Map<PDALaunch, LaunchAdapterSet> fLaunchAdapterSets =
Collections.synchronizedMap(new HashMap<PDALaunch, LaunchAdapterSet>());
public PDAAdapterFactory() {
DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
}
// This IAdapterFactory method returns adapters for the PDA launch object only.
// This IAdapterFactory method returns adapters for the PDA launch object only.
@SuppressWarnings("unchecked") // IAdapterFactory is Java 1.3
public Object getAdapter(Object adaptableObject, Class adapterType) {
if (!(adaptableObject instanceof PDALaunch)) return null;
if (!(adaptableObject instanceof PDALaunch)) return null;
PDALaunch launch = (PDALaunch)adaptableObject;
// Find the correct set of adapters based on the launch. If not found
// it means that we have a new launch, and we have to create a
// new set of adapters.
// it means that we have a new launch, and we have to create a
// new set of adapters.
LaunchAdapterSet adapterSet;
synchronized(fLaunchAdapterSets) {
adapterSet = fLaunchAdapterSets.get(launch);
@ -183,7 +183,7 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
}
public void launchesRemoved(ILaunch[] launches) {
// Dispose the set of adapters for a launch only after the launch is
// Dispose the set of adapters for a launch only after the launch is
// removed from the view. If the launch is terminated, the adapters
// are still needed to populate the contents of the view.
for (ILaunch launch : launches) {
@ -194,7 +194,7 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
fLaunchAdapterSets.remove(pdaLaunch).dispose();
}
}
}
}
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006 Wind River Systems and others.
* Copyright (c) 2006, 2008 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -15,6 +15,7 @@ import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.debug.core.model.IRestart;
import org.eclipse.cdt.debug.core.model.ISteppingModeTarget;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.dd.dsf.concurrent.Immutable;
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
@ -22,6 +23,7 @@ import org.eclipse.dd.dsf.debug.ui.actions.DsfResumeCommand;
import org.eclipse.dd.dsf.debug.ui.actions.DsfStepIntoCommand;
import org.eclipse.dd.dsf.debug.ui.actions.DsfStepOverCommand;
import org.eclipse.dd.dsf.debug.ui.actions.DsfStepReturnCommand;
import org.eclipse.dd.dsf.debug.ui.actions.DsfSteppingModeTarget;
import org.eclipse.dd.dsf.debug.ui.actions.DsfSuspendCommand;
import org.eclipse.dd.dsf.debug.ui.contexts.DsfSuspendTrigger;
import org.eclipse.dd.dsf.debug.ui.sourcelookup.DsfSourceDisplayAdapter;
@ -50,13 +52,13 @@ import org.eclipse.debug.ui.sourcelookup.ISourceDisplay;
/**
* This implementation of platform adapter factory only retrieves the adapters
* for the launch object. But it also manages the creation and destruction
* of the session-based adapters which are returned by the
* for the launch object. But it also manages the creation and destruction
* of the session-based adapters which are returned by the
* IDMContext.getAdapter() methods.
*/
@ThreadSafe
@SuppressWarnings({"restriction"})
public class GdbAdapterFactory
public class GdbAdapterFactory
implements IAdapterFactory, ILaunchesListener2
{
@Immutable
@ -73,6 +75,7 @@ public class GdbAdapterFactory
final DsfTerminateCommand fTerminateCommand;
final IDebugModelProvider fDebugModelProvider;
final DsfSuspendTrigger fSuspendTrigger;
final DsfSteppingModeTarget fSteppingModeTarget;
SessionAdapterSet(GdbLaunch launch) {
fLaunch = launch;
@ -87,14 +90,16 @@ public class GdbAdapterFactory
}
session.registerModelAdapter(ISourceDisplay.class, fSourceDisplayAdapter);
fStepIntoCommand = new DsfStepIntoCommand(session);
fStepOverCommand = new DsfStepOverCommand(session);
fSteppingModeTarget= new DsfSteppingModeTarget();
fStepIntoCommand = new DsfStepIntoCommand(session, fSteppingModeTarget);
fStepOverCommand = new DsfStepOverCommand(session, fSteppingModeTarget);
fStepReturnCommand = new DsfStepReturnCommand(session);
fSuspendCommand = new DsfSuspendCommand(session);
fResumeCommand = new DsfResumeCommand(session);
fRestartCommand = new GdbRestartCommand(session, fLaunch);
fTerminateCommand = new DsfTerminateCommand(session);
fSuspendTrigger = new DsfSuspendTrigger(session, fLaunch);
session.registerModelAdapter(ISteppingModeTarget.class, fSteppingModeTarget);
session.registerModelAdapter(IStepIntoHandler.class, fStepIntoCommand);
session.registerModelAdapter(IStepOverHandler.class, fStepOverCommand);
session.registerModelAdapter(IStepReturnHandler.class, fStepReturnCommand);
@ -112,10 +117,10 @@ public class GdbAdapterFactory
session.registerModelAdapter(IDebugModelProvider.class, fDebugModelProvider);
/*
* Registering the launch as an adapter, ensures that this launch,
* and debug model ID will be associated with all DMContexts from this
* session.
*/
* Registering the launch as an adapter, ensures that this launch,
* and debug model ID will be associated with all DMContexts from this
* session.
*/
session.registerModelAdapter(ILaunch.class, fLaunch);
}
@ -127,13 +132,14 @@ public class GdbAdapterFactory
session.unregisterModelAdapter(ISourceDisplay.class);
if (fSourceDisplayAdapter != null) fSourceDisplayAdapter.dispose();
session.unregisterModelAdapter(ISteppingModeTarget.class);
session.unregisterModelAdapter(IStepIntoHandler.class);
session.unregisterModelAdapter(IStepOverHandler.class);
session.unregisterModelAdapter(IStepReturnHandler.class);
session.unregisterModelAdapter(ISuspendHandler.class);
session.unregisterModelAdapter(IResumeHandler.class);
session.unregisterModelAdapter(IRestart.class);
session.unregisterModelAdapter(ITerminateHandler.class);
session.unregisterModelAdapter(ITerminateHandler.class);
fStepIntoCommand.dispose();
fStepOverCommand.dispose();
fStepReturnCommand.dispose();
@ -142,12 +148,12 @@ public class GdbAdapterFactory
fRestartCommand.dispose();
fTerminateCommand.dispose();
fSuspendTrigger.dispose();
}
}
}
}
private Map<GdbLaunch, SessionAdapterSet> fLaunchAdapterSets =
private Map<GdbLaunch, SessionAdapterSet> fLaunchAdapterSets =
Collections.synchronizedMap(new HashMap<GdbLaunch, SessionAdapterSet>());
public GdbAdapterFactory() {
@ -155,17 +161,17 @@ public class GdbAdapterFactory
}
/**
* This method only actually returns adapters for the launch object.
* This method only actually returns adapters for the launch object.
*/
@SuppressWarnings("unchecked")
public Object getAdapter(Object adaptableObject, Class adapterType) {
if (!(adaptableObject instanceof GdbLaunch)) return null;
if (!(adaptableObject instanceof GdbLaunch)) return null;
GdbLaunch launch = (GdbLaunch)adaptableObject;
// Find the correct set of adapters based on the launch session-ID. If not found
// it means that we have a new launch and new session, and we have to create a
// new set of adapters.
// it means that we have a new launch and new session, and we have to create a
// new set of adapters.
DsfSession session = launch.getSession();
if (session == null) return null;
@ -182,20 +188,20 @@ public class GdbAdapterFactory
if (adapterType.equals(IElementContentProvider.class)) return adapterSet.fViewModelAdapter;
else if (adapterType.equals(IModelProxyFactory.class)) return adapterSet.fViewModelAdapter;
else if (adapterType.equals(IColumnPresentationFactory.class)) return adapterSet.fViewModelAdapter;
else if (adapterType.equals(ISuspendTrigger.class)) return adapterSet.fSuspendTrigger;
else if (adapterType.equals(ISuspendTrigger.class)) return adapterSet.fSuspendTrigger;
else return null;
}
@SuppressWarnings("unchecked")
public Class[] getAdapterList() {
return new Class[] {
IElementContentProvider.class, IModelProxyFactory.class, ISuspendTrigger.class,
IColumnPresentationFactory.class
return new Class[] {
IElementContentProvider.class, IModelProxyFactory.class, ISuspendTrigger.class,
IColumnPresentationFactory.class
};
}
public void launchesRemoved(ILaunch[] launches) {
// Dispose the set of adapters for a launch only after the launch is
// Dispose the set of adapters for a launch only after the launch is
// removed.
for (ILaunch launch : launches) {
if (launch instanceof GdbLaunch) {
@ -204,7 +210,7 @@ public class GdbAdapterFactory
fLaunchAdapterSets.remove(launch).dispose();
}
}
}
}
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006 Wind River Systems and others.
* Copyright (c) 2006, 2008 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -33,7 +33,9 @@ import org.eclipse.dd.mi.service.command.commands.MIExecContinue;
import org.eclipse.dd.mi.service.command.commands.MIExecFinish;
import org.eclipse.dd.mi.service.command.commands.MIExecInterrupt;
import org.eclipse.dd.mi.service.command.commands.MIExecNext;
import org.eclipse.dd.mi.service.command.commands.MIExecNextInstruction;
import org.eclipse.dd.mi.service.command.commands.MIExecStep;
import org.eclipse.dd.mi.service.command.commands.MIExecStepInstruction;
import org.eclipse.dd.mi.service.command.commands.MIExecUntil;
import org.eclipse.dd.mi.service.command.commands.MIThreadListIds;
import org.eclipse.dd.mi.service.command.events.MIBreakpointHitEvent;
@ -55,23 +57,23 @@ import org.osgi.framework.BundleContext;
/**
*
* <p>
* <p>
* Implementation note:
* This class implements event handlers for the events that are generated by
* This class implements event handlers for the events that are generated by
* this service itself. When the event is dispatched, these handlers will
* be called first, before any of the clients. These handlers update the
* service's internal state information to make them consistent with the
* events being issued. Doing this in the handlers as opposed to when
* be called first, before any of the clients. These handlers update the
* service's internal state information to make them consistent with the
* events being issued. Doing this in the handlers as opposed to when
* the events are generated, guarantees that the state of the service will
* always be consistent with the events.
* The purpose of this pattern is to allow clients that listen to service
* The purpose of this pattern is to allow clients that listen to service
* events and track service state, to be perfectly in sync with the service
* state.
*/
public class MIRunControl extends AbstractDsfService implements IRunControl
{
protected class MIExecutionDMC extends AbstractDMContext
implements IMIExecutionDMContext
protected class MIExecutionDMC extends AbstractDMContext
implements IMIExecutionDMContext
{
/**
* Integer ID that is used to identify the thread in the GDB/MI protocol.
@ -126,22 +128,22 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
/**
* Base class for events generated by the MI Run Control service. Most events
* generated by the MI Run Control service are directly caused by some MI event.
* Other services may need access to the extended MI data carried in the event.
*
* generated by the MI Run Control service are directly caused by some MI event.
* Other services may need access to the extended MI data carried in the event.
*
* @param <V> DMC that this event refers to
* @param <T> MIInfo object that is the direct cause of this event
* @see MIRunControl
*/
@Immutable
protected static class RunControlEvent<V extends IDMContext, T extends MIEvent<? extends IDMContext>> extends AbstractDMEvent<V>
implements IDMEvent<V>
implements IDMEvent<V>
{
final private T fMIInfo;
public RunControlEvent(V dmc, T miInfo) {
public RunControlEvent(V dmc, T miInfo) {
super(dmc);
fMIInfo = miInfo;
}
fMIInfo = miInfo;
}
public T getMIEvent() { return fMIInfo; }
}
@ -150,10 +152,10 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
* Indicates that the given thread has been suspended.
*/
@Immutable
protected static class SuspendedEvent extends RunControlEvent<IExecutionDMContext, MIStoppedEvent>
protected static class SuspendedEvent extends RunControlEvent<IExecutionDMContext, MIStoppedEvent>
implements ISuspendedDMEvent
{
SuspendedEvent(IExecutionDMContext ctx, MIStoppedEvent miInfo) {
SuspendedEvent(IExecutionDMContext ctx, MIStoppedEvent miInfo) {
super(ctx, miInfo);
}
@ -172,18 +174,18 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
return StateChangeReason.ERROR;
}else {
return StateChangeReason.USER_REQUEST;
}
}
}
}
@Immutable
protected static class ContainerSuspendedEvent extends SuspendedEvent
protected static class ContainerSuspendedEvent extends SuspendedEvent
implements IContainerSuspendedDMEvent
{
final IExecutionDMContext[] triggeringDmcs;
ContainerSuspendedEvent(IContainerDMContext containerDmc, MIStoppedEvent miInfo, IExecutionDMContext triggeringDmc) {
ContainerSuspendedEvent(IContainerDMContext containerDmc, MIStoppedEvent miInfo, IExecutionDMContext triggeringDmc) {
super(containerDmc, miInfo);
this.triggeringDmcs = triggeringDmc != null
this.triggeringDmcs = triggeringDmc != null
? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0];
}
@ -193,10 +195,10 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
}
@Immutable
protected static class ResumedEvent extends RunControlEvent<IExecutionDMContext, MIRunningEvent>
protected static class ResumedEvent extends RunControlEvent<IExecutionDMContext, MIRunningEvent>
implements IResumedDMEvent
{
ResumedEvent(IExecutionDMContext ctx, MIRunningEvent miInfo) {
ResumedEvent(IExecutionDMContext ctx, MIRunningEvent miInfo) {
super(ctx, miInfo);
}
@ -221,14 +223,14 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
}
@Immutable
protected static class ContainerResumedEvent extends ResumedEvent
protected static class ContainerResumedEvent extends ResumedEvent
implements IContainerResumedDMEvent
{
final IExecutionDMContext[] triggeringDmcs;
ContainerResumedEvent(IContainerDMContext containerDmc, MIRunningEvent miInfo, IExecutionDMContext triggeringDmc) {
ContainerResumedEvent(IContainerDMContext containerDmc, MIRunningEvent miInfo, IExecutionDMContext triggeringDmc) {
super(containerDmc, miInfo);
this.triggeringDmcs = triggeringDmc != null
this.triggeringDmcs = triggeringDmc != null
? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0];
}
@ -238,19 +240,19 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
}
@Immutable
protected static class StartedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadCreatedEvent>
protected static class StartedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadCreatedEvent>
implements IStartedDMEvent
{
StartedDMEvent(IMIExecutionDMContext executionDmc, MIThreadCreatedEvent miInfo) {
StartedDMEvent(IMIExecutionDMContext executionDmc, MIThreadCreatedEvent miInfo) {
super(executionDmc, miInfo);
}
}
@Immutable
protected static class ExitedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadExitEvent>
protected static class ExitedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadExitEvent>
implements IExitedDMEvent
{
ExitedDMEvent(IMIExecutionDMContext executionDmc, MIThreadExitEvent miInfo) {
ExitedDMEvent(IMIExecutionDMContext executionDmc, MIThreadExitEvent miInfo) {
super(executionDmc, miInfo);
}
}
@ -267,7 +269,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
private StateChangeReason fStateChangeReason;
private IExecutionDMContext fStateChangeTriggeringContext;
private static final int NO_THREAD_ID = 0;
private static final int NO_THREAD_ID = 0;
public MIRunControl(DsfSession session) {
super(session);
@ -276,7 +278,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
@Override
public void initialize(final RequestMonitor rm) {
super.initialize(
new RequestMonitor(getExecutor(), rm) {
new RequestMonitor(getExecutor(), rm) {
@Override
protected void handleSuccess() {
doInitialize(rm);
@ -305,7 +307,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
@SuppressWarnings("unchecked")
public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
if (dmc instanceof IExecutionDMContext) {
getExecutionData((IExecutionDMContext)dmc, (DataRequestMonitor<IExecutionDMData>)rm);
getExecutionData((IExecutionDMContext)dmc, (DataRequestMonitor<IExecutionDMData>)rm);
} else {
rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
rm.done();
@ -321,7 +323,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
//
// Running event handling
//
@DsfServiceEventHandler
@DsfServiceEventHandler
public void eventDispatched(final MIRunningEvent e) {
IDMEvent<?> event = null;
// Find the container context, which is used in multi-threaded debugging.
@ -338,8 +340,8 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
//
// Suspended event handling
//
@DsfServiceEventHandler
//
@DsfServiceEventHandler
public void eventDispatched(final MIStoppedEvent e) {
IDMEvent<?> event = null;
// Find the container context, which is used in multi-threaded debugging.
@ -358,7 +360,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
// Thread Created event handling
// When a new thread is created - OOB Event fired ~"[New Thread 1077300144 (LWP 7973)]\n"
//
@DsfServiceEventHandler
@DsfServiceEventHandler
public void eventDispatched(final MIThreadCreatedEvent e) {
IContainerDMContext containerDmc = e.getDMContext();
IMIExecutionDMContext executionCtx = e.getId() != -1 ? new MIExecutionDMC(getSession().getId(), containerDmc, e.getId()) : null;
@ -369,14 +371,14 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
// Thread exit event handling
// When a new thread is destroyed - OOB Event fired "
//
@DsfServiceEventHandler
@DsfServiceEventHandler
public void eventDispatched(final MIThreadExitEvent e) {
IContainerDMContext containerDmc = e.getDMContext();
IMIExecutionDMContext executionCtx = e.getId() != -1 ? new MIExecutionDMC(getSession().getId(), containerDmc, e.getId()) : null;
getSession().dispatchEvent(new ExitedDMEvent(executionCtx, e), getProperties());
}
@DsfServiceEventHandler
@DsfServiceEventHandler
public void eventDispatched(ContainerResumedEvent e) {
fSuspended = false;
fResumePending = false;
@ -384,45 +386,45 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
fMICommandCache.setContextAvailable(e.getDMContext(), false);
//fStateChangeTriggeringContext = e.getTriggeringContext();
if (e.getReason().equals(StateChangeReason.STEP)) {
fStepping = true;
fStepping = true;
} else {
fMICommandCache.reset();
}
}
}
@DsfServiceEventHandler
@DsfServiceEventHandler
public void eventDispatched(ContainerSuspendedEvent e) {
fMICommandCache.setContextAvailable(e.getDMContext(), true);
fMICommandCache.reset();
fStateChangeReason = e.getReason();
fStateChangeTriggeringContext = e.getTriggeringContexts().length != 0
fStateChangeTriggeringContext = e.getTriggeringContexts().length != 0
? e.getTriggeringContexts()[0] : null;
fSuspended = true;
fStepping = false;
}
@DsfServiceEventHandler
@DsfServiceEventHandler
public void eventDispatched(MIGDBExitEvent e) {
fTerminated = true;
}
// Event handler when New thread is created
@DsfServiceEventHandler
@DsfServiceEventHandler
public void eventDispatched(StartedDMEvent e) {
}
}
// Event handler when a thread is destroyed
@DsfServiceEventHandler
@DsfServiceEventHandler
public void eventDispatched(ExitedDMEvent e) {
fMICommandCache.reset(e.getDMContext());
}
}
///////////////////////////////////////////////////////////////////////////
// AbstractService
// AbstractService
@Override
protected BundleContext getBundleContext() {
return MIPlugin.getBundleContext();
@ -459,7 +461,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
public void resume(IExecutionDMContext context, final RequestMonitor rm) {
assert context != null;
if (doCanResume(context)) {
if (doCanResume(context)) {
fResumePending = true;
// Cygwin GDB will accept commands and execute them after the step
// which is not what we want, so mark the target as unavailable
@ -479,7 +481,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
}
fConnection.queueCommand(
cmd,
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
rm.done();
@ -507,11 +509,11 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
rm.done();
return;
}
cmd = new MIExecInterrupt(dmc);
cmd = new MIExecInterrupt(dmc);
}
fConnection.queueCommand(
cmd,
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
rm.done();
@ -562,7 +564,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
// want it to operate on the stop stack frame. So we manually create a top-frame
// context to use with the MI command.
// We get a local instance of the stack service because the stack service can be shut
// down before the run control service is shut down. So it is possible for the
// down before the run control service is shut down. So it is possible for the
// getService() reqeust below to return null.
MIStack stackService = getServicesTracker().getService(MIStack.class);
if (stackService != null) {
@ -571,9 +573,19 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
new MIExecFinish(topFrameDmc), new DataRequestMonitor<MIInfo>(getExecutor(), rm) {});
} else {
rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, "Cannot create context for command, stack service not available.", null)); //$NON-NLS-1$
rm.done();
rm.done();
}
break;
case INSTRUCTION_STEP_INTO:
fConnection.queueCommand(
new MIExecStepInstruction(dmc, 1), new DataRequestMonitor<MIInfo>(getExecutor(), rm) {}
);
break;
case INSTRUCTION_STEP_OVER:
fConnection.queueCommand(
new MIExecNextInstruction(dmc, 1), new DataRequestMonitor<MIInfo>(getExecutor(), rm) {}
);
break;
default:
rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Given step type not supported", null)); //$NON-NLS-1$
rm.done();
@ -623,7 +635,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
/*
* Run selected execution thread to a given line number.
*/
// Later add support for Address and function.
// Later add support for Address and function.
// skipBreakpoints is not used at the moment. Implement later
public void runToLine(IExecutionDMContext context, String fileName, String lineNo, boolean skipBreakpoints, final DataRequestMonitor<MIInfo> rm){
assert context != null;
@ -635,7 +647,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
return;
}
if (doCanResume(context)) {
if (doCanResume(context)) {
fResumePending = true;
fMICommandCache.setContextAvailable(context, false);
fConnection.queueCommand(new MIExecUntil(dmc, fileName + ":" + lineNo), //$NON-NLS-1$
@ -647,8 +659,8 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
}
});
} else {
rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED,
"Cannot resume given DMC.", null)); //$NON-NLS-1$
rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED,
"Cannot resume given DMC.", null)); //$NON-NLS-1$
rm.done();
}
}