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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -27,11 +27,13 @@ public class DsfStepIntoCommand implements IStepIntoHandler {
private final DsfExecutor fExecutor; private final DsfExecutor fExecutor;
private final DsfServicesTracker fTracker; private final DsfServicesTracker fTracker;
private final DsfSteppingModeTarget fSteppingMode;
public DsfStepIntoCommand(DsfSession session) { public DsfStepIntoCommand(DsfSession session, DsfSteppingModeTarget steppingMode) {
fExecutor = session.getExecutor(); fExecutor = session.getExecutor();
fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId()); fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
} fSteppingMode = steppingMode;
}
public void dispose() { public void dispose() {
fTracker.dispose(); fTracker.dispose();
@ -44,10 +46,11 @@ public class DsfStepIntoCommand implements IStepIntoHandler {
return; 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() { @Override public void doExecute() {
getStepQueueMgr().canEnqueueStep( getStepQueueMgr().canEnqueueStep(
getContext(), StepType.STEP_INTO, getContext(), stepType,
new DataRequestMonitor<Boolean>(ImmediateExecutor.getInstance(), null) { new DataRequestMonitor<Boolean>(ImmediateExecutor.getInstance(), null) {
@Override @Override
protected void handleCompleted() { protected void handleCompleted() {
@ -65,11 +68,21 @@ public class DsfStepIntoCommand implements IStepIntoHandler {
return false; 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() { @Override public void doExecute() {
getStepQueueMgr().enqueueStep(getContext(), StepType.STEP_INTO); getStepQueueMgr().enqueueStep(getContext(), stepType);
} }
}); });
return true; 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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -27,11 +27,13 @@ public class DsfStepOverCommand implements IStepOverHandler {
private final DsfExecutor fExecutor; private final DsfExecutor fExecutor;
private final DsfServicesTracker fTracker; private final DsfServicesTracker fTracker;
private final DsfSteppingModeTarget fSteppingMode;
public DsfStepOverCommand(DsfSession session) { public DsfStepOverCommand(DsfSession session, DsfSteppingModeTarget steppingMode) {
fExecutor = session.getExecutor(); fExecutor = session.getExecutor();
fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId()); fTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
} fSteppingMode = steppingMode;
}
public void dispose() { public void dispose() {
fTracker.dispose(); fTracker.dispose();
@ -44,10 +46,11 @@ public class DsfStepOverCommand implements IStepOverHandler {
return; 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() { @Override public void doExecute() {
getStepQueueMgr().canEnqueueStep( getStepQueueMgr().canEnqueueStep(
getContext(), StepType.STEP_OVER, getContext(), stepType,
new DataRequestMonitor<Boolean>(ImmediateExecutor.getInstance(), null) { new DataRequestMonitor<Boolean>(ImmediateExecutor.getInstance(), null) {
@Override @Override
protected void handleCompleted() { 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) { if (request.getElements().length != 1) {
request.done(); request.done();
return false; 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() { @Override public void doExecute() {
getStepQueueMgr().enqueueStep(getContext(), StepType.STEP_OVER); getStepQueueMgr().enqueueStep(getContext(), stepType);
} }
}); });
return true; 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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * 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 * 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 * old ones removed, this factory manages the life cycle of the associated
* UI adapters. * UI adapters.
* <p> * <p>
* As a platform adapter factory, this factory only provides adapters for * As a platform adapter factory, this factory only provides adapters for
* the launch object. Adapters for all other objects in the DSF model hierarchy * 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> * </p>
*/ */
@ThreadSafe @ThreadSafe
@ -95,8 +95,8 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
session.registerModelAdapter(ISourceDisplay.class, fSourceDisplayAdapter); session.registerModelAdapter(ISourceDisplay.class, fSourceDisplayAdapter);
// Initialize retargetable command handler. // Initialize retargetable command handler.
fStepIntoCommand = new DsfStepIntoCommand(session); fStepIntoCommand = new DsfStepIntoCommand(session, null);
fStepOverCommand = new DsfStepOverCommand(session); fStepOverCommand = new DsfStepOverCommand(session, null);
fStepReturnCommand = new DsfStepReturnCommand(session); fStepReturnCommand = new DsfStepReturnCommand(session);
fSuspendCommand = new DsfSuspendCommand(session); fSuspendCommand = new DsfSuspendCommand(session);
fResumeCommand = new DsfResumeCommand(session); fResumeCommand = new DsfResumeCommand(session);
@ -116,9 +116,9 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
}; };
session.registerModelAdapter(IDebugModelProvider.class, fDebugModelProvider); session.registerModelAdapter(IDebugModelProvider.class, fDebugModelProvider);
// Register the launch as an adapter This ensures that the launch, // Register the launch as an adapter This ensures that the launch,
// and debug model ID will be associated with all DMContexts from this // and debug model ID will be associated with all DMContexts from this
// session. // session.
session.registerModelAdapter(ILaunch.class, fLaunch); session.registerModelAdapter(ILaunch.class, fLaunch);
} }
@ -135,33 +135,33 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
session.unregisterModelAdapter(IStepReturnHandler.class); session.unregisterModelAdapter(IStepReturnHandler.class);
session.unregisterModelAdapter(ISuspendHandler.class); session.unregisterModelAdapter(ISuspendHandler.class);
session.unregisterModelAdapter(IResumeHandler.class); session.unregisterModelAdapter(IResumeHandler.class);
session.unregisterModelAdapter(ITerminateHandler.class); session.unregisterModelAdapter(ITerminateHandler.class);
fStepIntoCommand.dispose(); fStepIntoCommand.dispose();
fStepOverCommand.dispose(); fStepOverCommand.dispose();
fStepReturnCommand.dispose(); fStepReturnCommand.dispose();
fSuspendCommand.dispose(); fSuspendCommand.dispose();
fResumeCommand.dispose(); fResumeCommand.dispose();
fTerminateCommand.dispose(); fTerminateCommand.dispose();
} }
} }
private Map<PDALaunch, LaunchAdapterSet> fLaunchAdapterSets = private Map<PDALaunch, LaunchAdapterSet> fLaunchAdapterSets =
Collections.synchronizedMap(new HashMap<PDALaunch, LaunchAdapterSet>()); Collections.synchronizedMap(new HashMap<PDALaunch, LaunchAdapterSet>());
public PDAAdapterFactory() { public PDAAdapterFactory() {
DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this); 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 @SuppressWarnings("unchecked") // IAdapterFactory is Java 1.3
public Object getAdapter(Object adaptableObject, Class adapterType) { public Object getAdapter(Object adaptableObject, Class adapterType) {
if (!(adaptableObject instanceof PDALaunch)) return null; if (!(adaptableObject instanceof PDALaunch)) return null;
PDALaunch launch = (PDALaunch)adaptableObject; PDALaunch launch = (PDALaunch)adaptableObject;
// Find the correct set of adapters based on the launch. If not found // 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 // it means that we have a new launch, and we have to create a
// new set of adapters. // new set of adapters.
LaunchAdapterSet adapterSet; LaunchAdapterSet adapterSet;
synchronized(fLaunchAdapterSets) { synchronized(fLaunchAdapterSets) {
adapterSet = fLaunchAdapterSets.get(launch); adapterSet = fLaunchAdapterSets.get(launch);
@ -183,7 +183,7 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
} }
public void launchesRemoved(ILaunch[] launches) { 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 // removed from the view. If the launch is terminated, the adapters
// are still needed to populate the contents of the view. // are still needed to populate the contents of the view.
for (ILaunch launch : launches) { for (ILaunch launch : launches) {
@ -194,7 +194,7 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
fLaunchAdapterSets.remove(pdaLaunch).dispose(); 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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -15,6 +15,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.debug.core.model.IRestart; 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.core.runtime.IAdapterFactory;
import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.concurrent.Immutable;
import org.eclipse.dd.dsf.concurrent.ThreadSafe; 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.DsfStepIntoCommand;
import org.eclipse.dd.dsf.debug.ui.actions.DsfStepOverCommand; 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.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.actions.DsfSuspendCommand;
import org.eclipse.dd.dsf.debug.ui.contexts.DsfSuspendTrigger; import org.eclipse.dd.dsf.debug.ui.contexts.DsfSuspendTrigger;
import org.eclipse.dd.dsf.debug.ui.sourcelookup.DsfSourceDisplayAdapter; 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 * This implementation of platform adapter factory only retrieves the adapters
* for the launch object. But it also manages the creation and destruction * for the launch object. But it also manages the creation and destruction
* of the session-based adapters which are returned by the * of the session-based adapters which are returned by the
* IDMContext.getAdapter() methods. * IDMContext.getAdapter() methods.
*/ */
@ThreadSafe @ThreadSafe
@SuppressWarnings({"restriction"}) @SuppressWarnings({"restriction"})
public class GdbAdapterFactory public class GdbAdapterFactory
implements IAdapterFactory, ILaunchesListener2 implements IAdapterFactory, ILaunchesListener2
{ {
@Immutable @Immutable
@ -73,6 +75,7 @@ public class GdbAdapterFactory
final DsfTerminateCommand fTerminateCommand; final DsfTerminateCommand fTerminateCommand;
final IDebugModelProvider fDebugModelProvider; final IDebugModelProvider fDebugModelProvider;
final DsfSuspendTrigger fSuspendTrigger; final DsfSuspendTrigger fSuspendTrigger;
final DsfSteppingModeTarget fSteppingModeTarget;
SessionAdapterSet(GdbLaunch launch) { SessionAdapterSet(GdbLaunch launch) {
fLaunch = launch; fLaunch = launch;
@ -87,14 +90,16 @@ public class GdbAdapterFactory
} }
session.registerModelAdapter(ISourceDisplay.class, fSourceDisplayAdapter); session.registerModelAdapter(ISourceDisplay.class, fSourceDisplayAdapter);
fStepIntoCommand = new DsfStepIntoCommand(session); fSteppingModeTarget= new DsfSteppingModeTarget();
fStepOverCommand = new DsfStepOverCommand(session); fStepIntoCommand = new DsfStepIntoCommand(session, fSteppingModeTarget);
fStepOverCommand = new DsfStepOverCommand(session, fSteppingModeTarget);
fStepReturnCommand = new DsfStepReturnCommand(session); fStepReturnCommand = new DsfStepReturnCommand(session);
fSuspendCommand = new DsfSuspendCommand(session); fSuspendCommand = new DsfSuspendCommand(session);
fResumeCommand = new DsfResumeCommand(session); fResumeCommand = new DsfResumeCommand(session);
fRestartCommand = new GdbRestartCommand(session, fLaunch); fRestartCommand = new GdbRestartCommand(session, fLaunch);
fTerminateCommand = new DsfTerminateCommand(session); fTerminateCommand = new DsfTerminateCommand(session);
fSuspendTrigger = new DsfSuspendTrigger(session, fLaunch); fSuspendTrigger = new DsfSuspendTrigger(session, fLaunch);
session.registerModelAdapter(ISteppingModeTarget.class, fSteppingModeTarget);
session.registerModelAdapter(IStepIntoHandler.class, fStepIntoCommand); session.registerModelAdapter(IStepIntoHandler.class, fStepIntoCommand);
session.registerModelAdapter(IStepOverHandler.class, fStepOverCommand); session.registerModelAdapter(IStepOverHandler.class, fStepOverCommand);
session.registerModelAdapter(IStepReturnHandler.class, fStepReturnCommand); session.registerModelAdapter(IStepReturnHandler.class, fStepReturnCommand);
@ -112,10 +117,10 @@ public class GdbAdapterFactory
session.registerModelAdapter(IDebugModelProvider.class, fDebugModelProvider); session.registerModelAdapter(IDebugModelProvider.class, fDebugModelProvider);
/* /*
* Registering the launch as an adapter, ensures that this launch, * Registering the launch as an adapter, ensures that this launch,
* and debug model ID will be associated with all DMContexts from this * and debug model ID will be associated with all DMContexts from this
* session. * session.
*/ */
session.registerModelAdapter(ILaunch.class, fLaunch); session.registerModelAdapter(ILaunch.class, fLaunch);
} }
@ -127,13 +132,14 @@ public class GdbAdapterFactory
session.unregisterModelAdapter(ISourceDisplay.class); session.unregisterModelAdapter(ISourceDisplay.class);
if (fSourceDisplayAdapter != null) fSourceDisplayAdapter.dispose(); if (fSourceDisplayAdapter != null) fSourceDisplayAdapter.dispose();
session.unregisterModelAdapter(ISteppingModeTarget.class);
session.unregisterModelAdapter(IStepIntoHandler.class); session.unregisterModelAdapter(IStepIntoHandler.class);
session.unregisterModelAdapter(IStepOverHandler.class); session.unregisterModelAdapter(IStepOverHandler.class);
session.unregisterModelAdapter(IStepReturnHandler.class); session.unregisterModelAdapter(IStepReturnHandler.class);
session.unregisterModelAdapter(ISuspendHandler.class); session.unregisterModelAdapter(ISuspendHandler.class);
session.unregisterModelAdapter(IResumeHandler.class); session.unregisterModelAdapter(IResumeHandler.class);
session.unregisterModelAdapter(IRestart.class); session.unregisterModelAdapter(IRestart.class);
session.unregisterModelAdapter(ITerminateHandler.class); session.unregisterModelAdapter(ITerminateHandler.class);
fStepIntoCommand.dispose(); fStepIntoCommand.dispose();
fStepOverCommand.dispose(); fStepOverCommand.dispose();
fStepReturnCommand.dispose(); fStepReturnCommand.dispose();
@ -142,12 +148,12 @@ public class GdbAdapterFactory
fRestartCommand.dispose(); fRestartCommand.dispose();
fTerminateCommand.dispose(); fTerminateCommand.dispose();
fSuspendTrigger.dispose(); fSuspendTrigger.dispose();
} }
} }
private Map<GdbLaunch, SessionAdapterSet> fLaunchAdapterSets = private Map<GdbLaunch, SessionAdapterSet> fLaunchAdapterSets =
Collections.synchronizedMap(new HashMap<GdbLaunch, SessionAdapterSet>()); Collections.synchronizedMap(new HashMap<GdbLaunch, SessionAdapterSet>());
public GdbAdapterFactory() { 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") @SuppressWarnings("unchecked")
public Object getAdapter(Object adaptableObject, Class adapterType) { public Object getAdapter(Object adaptableObject, Class adapterType) {
if (!(adaptableObject instanceof GdbLaunch)) return null; if (!(adaptableObject instanceof GdbLaunch)) return null;
GdbLaunch launch = (GdbLaunch)adaptableObject; GdbLaunch launch = (GdbLaunch)adaptableObject;
// Find the correct set of adapters based on the launch session-ID. If not found // 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 // it means that we have a new launch and new session, and we have to create a
// new set of adapters. // new set of adapters.
DsfSession session = launch.getSession(); DsfSession session = launch.getSession();
if (session == null) return null; if (session == null) return null;
@ -182,20 +188,20 @@ public class GdbAdapterFactory
if (adapterType.equals(IElementContentProvider.class)) return adapterSet.fViewModelAdapter; if (adapterType.equals(IElementContentProvider.class)) return adapterSet.fViewModelAdapter;
else if (adapterType.equals(IModelProxyFactory.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(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; else return null;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Class[] getAdapterList() { public Class[] getAdapterList() {
return new Class[] { return new Class[] {
IElementContentProvider.class, IModelProxyFactory.class, ISuspendTrigger.class, IElementContentProvider.class, IModelProxyFactory.class, ISuspendTrigger.class,
IColumnPresentationFactory.class IColumnPresentationFactory.class
}; };
} }
public void launchesRemoved(ILaunch[] launches) { 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. // removed.
for (ILaunch launch : launches) { for (ILaunch launch : launches) {
if (launch instanceof GdbLaunch) { if (launch instanceof GdbLaunch) {
@ -204,7 +210,7 @@ public class GdbAdapterFactory
fLaunchAdapterSets.remove(launch).dispose(); 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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * 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.MIExecFinish;
import org.eclipse.dd.mi.service.command.commands.MIExecInterrupt; 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.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.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.MIExecUntil;
import org.eclipse.dd.mi.service.command.commands.MIThreadListIds; import org.eclipse.dd.mi.service.command.commands.MIThreadListIds;
import org.eclipse.dd.mi.service.command.events.MIBreakpointHitEvent; import org.eclipse.dd.mi.service.command.events.MIBreakpointHitEvent;
@ -55,23 +57,23 @@ import org.osgi.framework.BundleContext;
/** /**
* *
* <p> * <p>
* Implementation note: * 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 * this service itself. When the event is dispatched, these handlers will
* be called first, before any of the clients. These handlers update the * be called first, before any of the clients. These handlers update the
* service's internal state information to make them consistent with the * service's internal state information to make them consistent with the
* events being issued. Doing this in the handlers as opposed to when * events being issued. Doing this in the handlers as opposed to when
* the events are generated, guarantees that the state of the service will * the events are generated, guarantees that the state of the service will
* always be consistent with the events. * 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 * events and track service state, to be perfectly in sync with the service
* state. * state.
*/ */
public class MIRunControl extends AbstractDsfService implements IRunControl public class MIRunControl extends AbstractDsfService implements IRunControl
{ {
protected class MIExecutionDMC extends AbstractDMContext protected class MIExecutionDMC extends AbstractDMContext
implements IMIExecutionDMContext implements IMIExecutionDMContext
{ {
/** /**
* Integer ID that is used to identify the thread in the GDB/MI protocol. * 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 * 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. * 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. * Other services may need access to the extended MI data carried in the event.
* *
* @param <V> DMC that this event refers to * @param <V> DMC that this event refers to
* @param <T> MIInfo object that is the direct cause of this event * @param <T> MIInfo object that is the direct cause of this event
* @see MIRunControl * @see MIRunControl
*/ */
@Immutable @Immutable
protected static class RunControlEvent<V extends IDMContext, T extends MIEvent<? extends IDMContext>> extends AbstractDMEvent<V> 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; final private T fMIInfo;
public RunControlEvent(V dmc, T miInfo) { public RunControlEvent(V dmc, T miInfo) {
super(dmc); super(dmc);
fMIInfo = miInfo; fMIInfo = miInfo;
} }
public T getMIEvent() { return fMIInfo; } public T getMIEvent() { return fMIInfo; }
} }
@ -150,10 +152,10 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
* Indicates that the given thread has been suspended. * Indicates that the given thread has been suspended.
*/ */
@Immutable @Immutable
protected static class SuspendedEvent extends RunControlEvent<IExecutionDMContext, MIStoppedEvent> protected static class SuspendedEvent extends RunControlEvent<IExecutionDMContext, MIStoppedEvent>
implements ISuspendedDMEvent implements ISuspendedDMEvent
{ {
SuspendedEvent(IExecutionDMContext ctx, MIStoppedEvent miInfo) { SuspendedEvent(IExecutionDMContext ctx, MIStoppedEvent miInfo) {
super(ctx, miInfo); super(ctx, miInfo);
} }
@ -172,18 +174,18 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
return StateChangeReason.ERROR; return StateChangeReason.ERROR;
}else { }else {
return StateChangeReason.USER_REQUEST; return StateChangeReason.USER_REQUEST;
} }
} }
} }
@Immutable @Immutable
protected static class ContainerSuspendedEvent extends SuspendedEvent protected static class ContainerSuspendedEvent extends SuspendedEvent
implements IContainerSuspendedDMEvent implements IContainerSuspendedDMEvent
{ {
final IExecutionDMContext[] triggeringDmcs; final IExecutionDMContext[] triggeringDmcs;
ContainerSuspendedEvent(IContainerDMContext containerDmc, MIStoppedEvent miInfo, IExecutionDMContext triggeringDmc) { ContainerSuspendedEvent(IContainerDMContext containerDmc, MIStoppedEvent miInfo, IExecutionDMContext triggeringDmc) {
super(containerDmc, miInfo); super(containerDmc, miInfo);
this.triggeringDmcs = triggeringDmc != null this.triggeringDmcs = triggeringDmc != null
? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0]; ? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0];
} }
@ -193,10 +195,10 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
} }
@Immutable @Immutable
protected static class ResumedEvent extends RunControlEvent<IExecutionDMContext, MIRunningEvent> protected static class ResumedEvent extends RunControlEvent<IExecutionDMContext, MIRunningEvent>
implements IResumedDMEvent implements IResumedDMEvent
{ {
ResumedEvent(IExecutionDMContext ctx, MIRunningEvent miInfo) { ResumedEvent(IExecutionDMContext ctx, MIRunningEvent miInfo) {
super(ctx, miInfo); super(ctx, miInfo);
} }
@ -221,14 +223,14 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
} }
@Immutable @Immutable
protected static class ContainerResumedEvent extends ResumedEvent protected static class ContainerResumedEvent extends ResumedEvent
implements IContainerResumedDMEvent implements IContainerResumedDMEvent
{ {
final IExecutionDMContext[] triggeringDmcs; final IExecutionDMContext[] triggeringDmcs;
ContainerResumedEvent(IContainerDMContext containerDmc, MIRunningEvent miInfo, IExecutionDMContext triggeringDmc) { ContainerResumedEvent(IContainerDMContext containerDmc, MIRunningEvent miInfo, IExecutionDMContext triggeringDmc) {
super(containerDmc, miInfo); super(containerDmc, miInfo);
this.triggeringDmcs = triggeringDmc != null this.triggeringDmcs = triggeringDmc != null
? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0]; ? new IExecutionDMContext[] { triggeringDmc } : new IExecutionDMContext[0];
} }
@ -238,19 +240,19 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
} }
@Immutable @Immutable
protected static class StartedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadCreatedEvent> protected static class StartedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadCreatedEvent>
implements IStartedDMEvent implements IStartedDMEvent
{ {
StartedDMEvent(IMIExecutionDMContext executionDmc, MIThreadCreatedEvent miInfo) { StartedDMEvent(IMIExecutionDMContext executionDmc, MIThreadCreatedEvent miInfo) {
super(executionDmc, miInfo); super(executionDmc, miInfo);
} }
} }
@Immutable @Immutable
protected static class ExitedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadExitEvent> protected static class ExitedDMEvent extends RunControlEvent<IExecutionDMContext,MIThreadExitEvent>
implements IExitedDMEvent implements IExitedDMEvent
{ {
ExitedDMEvent(IMIExecutionDMContext executionDmc, MIThreadExitEvent miInfo) { ExitedDMEvent(IMIExecutionDMContext executionDmc, MIThreadExitEvent miInfo) {
super(executionDmc, miInfo); super(executionDmc, miInfo);
} }
} }
@ -267,7 +269,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
private StateChangeReason fStateChangeReason; private StateChangeReason fStateChangeReason;
private IExecutionDMContext fStateChangeTriggeringContext; private IExecutionDMContext fStateChangeTriggeringContext;
private static final int NO_THREAD_ID = 0; private static final int NO_THREAD_ID = 0;
public MIRunControl(DsfSession session) { public MIRunControl(DsfSession session) {
super(session); super(session);
@ -276,7 +278,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
@Override @Override
public void initialize(final RequestMonitor rm) { public void initialize(final RequestMonitor rm) {
super.initialize( super.initialize(
new RequestMonitor(getExecutor(), rm) { new RequestMonitor(getExecutor(), rm) {
@Override @Override
protected void handleSuccess() { protected void handleSuccess() {
doInitialize(rm); doInitialize(rm);
@ -305,7 +307,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) { public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
if (dmc instanceof IExecutionDMContext) { if (dmc instanceof IExecutionDMContext) {
getExecutionData((IExecutionDMContext)dmc, (DataRequestMonitor<IExecutionDMData>)rm); getExecutionData((IExecutionDMContext)dmc, (DataRequestMonitor<IExecutionDMData>)rm);
} else { } else {
rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
rm.done(); rm.done();
@ -321,7 +323,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
// //
// Running event handling // Running event handling
// //
@DsfServiceEventHandler @DsfServiceEventHandler
public void eventDispatched(final MIRunningEvent e) { public void eventDispatched(final MIRunningEvent e) {
IDMEvent<?> event = null; IDMEvent<?> event = null;
// Find the container context, which is used in multi-threaded debugging. // 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 // Suspended event handling
// //
@DsfServiceEventHandler @DsfServiceEventHandler
public void eventDispatched(final MIStoppedEvent e) { public void eventDispatched(final MIStoppedEvent e) {
IDMEvent<?> event = null; IDMEvent<?> event = null;
// Find the container context, which is used in multi-threaded debugging. // 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 // Thread Created event handling
// When a new thread is created - OOB Event fired ~"[New Thread 1077300144 (LWP 7973)]\n" // When a new thread is created - OOB Event fired ~"[New Thread 1077300144 (LWP 7973)]\n"
// //
@DsfServiceEventHandler @DsfServiceEventHandler
public void eventDispatched(final MIThreadCreatedEvent e) { public void eventDispatched(final MIThreadCreatedEvent e) {
IContainerDMContext containerDmc = e.getDMContext(); IContainerDMContext containerDmc = e.getDMContext();
IMIExecutionDMContext executionCtx = e.getId() != -1 ? new MIExecutionDMC(getSession().getId(), containerDmc, e.getId()) : null; 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 // Thread exit event handling
// When a new thread is destroyed - OOB Event fired " // When a new thread is destroyed - OOB Event fired "
// //
@DsfServiceEventHandler @DsfServiceEventHandler
public void eventDispatched(final MIThreadExitEvent e) { public void eventDispatched(final MIThreadExitEvent e) {
IContainerDMContext containerDmc = e.getDMContext(); IContainerDMContext containerDmc = e.getDMContext();
IMIExecutionDMContext executionCtx = e.getId() != -1 ? new MIExecutionDMC(getSession().getId(), containerDmc, e.getId()) : null; IMIExecutionDMContext executionCtx = e.getId() != -1 ? new MIExecutionDMC(getSession().getId(), containerDmc, e.getId()) : null;
getSession().dispatchEvent(new ExitedDMEvent(executionCtx, e), getProperties()); getSession().dispatchEvent(new ExitedDMEvent(executionCtx, e), getProperties());
} }
@DsfServiceEventHandler @DsfServiceEventHandler
public void eventDispatched(ContainerResumedEvent e) { public void eventDispatched(ContainerResumedEvent e) {
fSuspended = false; fSuspended = false;
fResumePending = false; fResumePending = false;
@ -384,45 +386,45 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
fMICommandCache.setContextAvailable(e.getDMContext(), false); fMICommandCache.setContextAvailable(e.getDMContext(), false);
//fStateChangeTriggeringContext = e.getTriggeringContext(); //fStateChangeTriggeringContext = e.getTriggeringContext();
if (e.getReason().equals(StateChangeReason.STEP)) { if (e.getReason().equals(StateChangeReason.STEP)) {
fStepping = true; fStepping = true;
} else { } else {
fMICommandCache.reset(); fMICommandCache.reset();
} }
} }
@DsfServiceEventHandler @DsfServiceEventHandler
public void eventDispatched(ContainerSuspendedEvent e) { public void eventDispatched(ContainerSuspendedEvent e) {
fMICommandCache.setContextAvailable(e.getDMContext(), true); fMICommandCache.setContextAvailable(e.getDMContext(), true);
fMICommandCache.reset(); fMICommandCache.reset();
fStateChangeReason = e.getReason(); fStateChangeReason = e.getReason();
fStateChangeTriggeringContext = e.getTriggeringContexts().length != 0 fStateChangeTriggeringContext = e.getTriggeringContexts().length != 0
? e.getTriggeringContexts()[0] : null; ? e.getTriggeringContexts()[0] : null;
fSuspended = true; fSuspended = true;
fStepping = false; fStepping = false;
} }
@DsfServiceEventHandler @DsfServiceEventHandler
public void eventDispatched(MIGDBExitEvent e) { public void eventDispatched(MIGDBExitEvent e) {
fTerminated = true; fTerminated = true;
} }
// Event handler when New thread is created // Event handler when New thread is created
@DsfServiceEventHandler @DsfServiceEventHandler
public void eventDispatched(StartedDMEvent e) { public void eventDispatched(StartedDMEvent e) {
} }
// Event handler when a thread is destroyed // Event handler when a thread is destroyed
@DsfServiceEventHandler @DsfServiceEventHandler
public void eventDispatched(ExitedDMEvent e) { public void eventDispatched(ExitedDMEvent e) {
fMICommandCache.reset(e.getDMContext()); fMICommandCache.reset(e.getDMContext());
} }
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// AbstractService // AbstractService
@Override @Override
protected BundleContext getBundleContext() { protected BundleContext getBundleContext() {
return MIPlugin.getBundleContext(); return MIPlugin.getBundleContext();
@ -459,7 +461,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
public void resume(IExecutionDMContext context, final RequestMonitor rm) { public void resume(IExecutionDMContext context, final RequestMonitor rm) {
assert context != null; assert context != null;
if (doCanResume(context)) { if (doCanResume(context)) {
fResumePending = true; fResumePending = true;
// Cygwin GDB will accept commands and execute them after the step // Cygwin GDB will accept commands and execute them after the step
// which is not what we want, so mark the target as unavailable // 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( fConnection.queueCommand(
cmd, cmd,
new DataRequestMonitor<MIInfo>(getExecutor(), rm) { new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
@Override @Override
protected void handleSuccess() { protected void handleSuccess() {
rm.done(); rm.done();
@ -507,11 +509,11 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
rm.done(); rm.done();
return; return;
} }
cmd = new MIExecInterrupt(dmc); cmd = new MIExecInterrupt(dmc);
} }
fConnection.queueCommand( fConnection.queueCommand(
cmd, cmd,
new DataRequestMonitor<MIInfo>(getExecutor(), rm) { new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
@Override @Override
protected void handleSuccess() { protected void handleSuccess() {
rm.done(); 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 // want it to operate on the stop stack frame. So we manually create a top-frame
// context to use with the MI command. // context to use with the MI command.
// We get a local instance of the stack service because the stack service can be shut // 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. // getService() reqeust below to return null.
MIStack stackService = getServicesTracker().getService(MIStack.class); MIStack stackService = getServicesTracker().getService(MIStack.class);
if (stackService != null) { if (stackService != null) {
@ -571,9 +573,19 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
new MIExecFinish(topFrameDmc), new DataRequestMonitor<MIInfo>(getExecutor(), rm) {}); new MIExecFinish(topFrameDmc), new DataRequestMonitor<MIInfo>(getExecutor(), rm) {});
} else { } 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.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; 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: default:
rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Given step type not supported", null)); //$NON-NLS-1$ rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Given step type not supported", null)); //$NON-NLS-1$
rm.done(); rm.done();
@ -623,7 +635,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
/* /*
* Run selected execution thread to a given line number. * 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 // skipBreakpoints is not used at the moment. Implement later
public void runToLine(IExecutionDMContext context, String fileName, String lineNo, boolean skipBreakpoints, final DataRequestMonitor<MIInfo> rm){ public void runToLine(IExecutionDMContext context, String fileName, String lineNo, boolean skipBreakpoints, final DataRequestMonitor<MIInfo> rm){
assert context != null; assert context != null;
@ -635,7 +647,7 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
return; return;
} }
if (doCanResume(context)) { if (doCanResume(context)) {
fResumePending = true; fResumePending = true;
fMICommandCache.setContextAvailable(context, false); fMICommandCache.setContextAvailable(context, false);
fConnection.queueCommand(new MIExecUntil(dmc, fileName + ":" + lineNo), //$NON-NLS-1$ fConnection.queueCommand(new MIExecUntil(dmc, fileName + ":" + lineNo), //$NON-NLS-1$
@ -647,8 +659,8 @@ public class MIRunControl extends AbstractDsfService implements IRunControl
} }
}); });
} else { } else {
rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED, rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, NOT_SUPPORTED,
"Cannot resume given DMC.", null)); //$NON-NLS-1$ "Cannot resume given DMC.", null)); //$NON-NLS-1$
rm.done(); rm.done();
} }
} }