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:
parent
23afc8c598
commit
05a1a3763b
6 changed files with 227 additions and 119 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue