mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 14:42:11 +02:00
[298909] - [launch] DSF suspend trigger susceptible to race conditions
This commit is contained in:
parent
47e8b801a0
commit
e31d06b003
10 changed files with 389 additions and 27 deletions
|
@ -345,5 +345,15 @@
|
|||
id="org.eclipse.cdt.dsf.gdb.ui.GdbDebugTextHover">
|
||||
</hover>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.debug.ui.contextViewBindings">
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.debug.ui.debugModelContextBindings">
|
||||
<modelContextBinding
|
||||
contextId="org.eclipse.cdt.debug.ui.debugging"
|
||||
debugModelId="org.eclipse.cdt.dsf.gdb">
|
||||
</modelContextBinding>
|
||||
</extension>
|
||||
|
||||
</plugin>
|
||||
|
|
|
@ -29,7 +29,6 @@ import org.eclipse.cdt.dsf.debug.ui.actions.DsfStepIntoCommand;
|
|||
import org.eclipse.cdt.dsf.debug.ui.actions.DsfStepOverCommand;
|
||||
import org.eclipse.cdt.dsf.debug.ui.actions.DsfStepReturnCommand;
|
||||
import org.eclipse.cdt.dsf.debug.ui.actions.DsfSuspendCommand;
|
||||
import org.eclipse.cdt.dsf.debug.ui.contexts.DsfSuspendTrigger;
|
||||
import org.eclipse.cdt.dsf.debug.ui.sourcelookup.DsfSourceDisplayAdapter;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.SteppingController;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.actions.DefaultRefreshAllTarget;
|
||||
|
@ -99,7 +98,7 @@ public class GdbAdapterFactory
|
|||
final GdbConnectCommand fConnectCommand;
|
||||
final GdbDisconnectCommand fDisconnectCommand;
|
||||
final IDebugModelProvider fDebugModelProvider;
|
||||
final DsfSuspendTrigger fSuspendTrigger;
|
||||
final GdbSuspendTrigger fSuspendTrigger;
|
||||
final GdbSteppingModeTarget fSteppingModeTarget;
|
||||
final IModelSelectionPolicyFactory fModelSelectionPolicyFactory;
|
||||
final SteppingController fSteppingController;
|
||||
|
@ -137,7 +136,7 @@ public class GdbAdapterFactory
|
|||
fTerminateCommand = new DsfTerminateCommand(session);
|
||||
fConnectCommand = new GdbConnectCommand(session);
|
||||
fDisconnectCommand = new GdbDisconnectCommand(session);
|
||||
fSuspendTrigger = new DsfSuspendTrigger(session, fLaunch);
|
||||
fSuspendTrigger = new GdbSuspendTrigger(session, fLaunch);
|
||||
fModelSelectionPolicyFactory = new DefaultDsfModelSelectionPolicyFactory();
|
||||
fRefreshAllTarget = new DefaultRefreshAllTarget();
|
||||
fReverseToggleTarget = new GdbReverseToggleCommand(session);
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.internal.ui;
|
||||
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
||||
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
|
||||
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
|
||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IProcesses;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
|
||||
import org.eclipse.cdt.dsf.debug.ui.contexts.DsfSuspendTrigger;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.debug.core.ILaunch;
|
||||
|
||||
/**
|
||||
* @since 2.1
|
||||
*/
|
||||
public class GdbSuspendTrigger extends DsfSuspendTrigger {
|
||||
|
||||
public GdbSuspendTrigger(DsfSession session, ILaunch launch) {
|
||||
super(session, launch);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getLaunchTopContainers(final DataRequestMonitor<IContainerDMContext[]> rm) {
|
||||
try {
|
||||
getSession().getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
IProcesses processService = getServicesTracker().getService(IProcesses.class);
|
||||
ICommandControlService controlService = getServicesTracker().getService(ICommandControlService.class);
|
||||
if (processService == null || controlService == null) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Not available", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
processService.getProcessesBeingDebugged(
|
||||
controlService.getContext(),
|
||||
new DataRequestMonitor<IDMContext[]>(ImmediateExecutor.getInstance(), rm) {
|
||||
@Override
|
||||
public void handleSuccess() {
|
||||
IContainerDMContext[] containers = new IContainerDMContext[getData().length];
|
||||
for (int i = 0; i < containers.length; i++) {
|
||||
if (getData()[i] instanceof IContainerDMContext) {
|
||||
containers[i] = (IContainerDMContext)getData()[i];
|
||||
} else {
|
||||
// By convention the processes should be containers, but the API
|
||||
// does not enforce this.
|
||||
assert false;
|
||||
rm.setData(new IContainerDMContext[0]);
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
rm.setData(containers);
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} catch (RejectedExecutionException e) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Not available", e)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,11 +13,19 @@ package org.eclipse.cdt.dsf.debug.ui.contexts;
|
|||
import java.util.concurrent.RejectedExecutionException;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
|
||||
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
||||
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
|
||||
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
|
||||
import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
|
||||
import org.eclipse.cdt.dsf.datamodel.DataModelInitializedEvent;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
|
||||
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
|
||||
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.ISafeRunnable;
|
||||
|
@ -45,8 +53,9 @@ public class DsfSuspendTrigger implements ISuspendTrigger {
|
|||
|
||||
private final DsfSession fSession;
|
||||
private final ILaunch fLaunch;
|
||||
private boolean fDisposed = false;
|
||||
private volatile boolean fDisposed = false;
|
||||
private boolean fEventListenerRegisterd = false;
|
||||
private final DsfServicesTracker fServicesTracker;
|
||||
|
||||
@ThreadSafe
|
||||
private final ListenerList fListeners = new ListenerList();
|
||||
|
@ -55,6 +64,7 @@ public class DsfSuspendTrigger implements ISuspendTrigger {
|
|||
public DsfSuspendTrigger(DsfSession session, ILaunch launch) {
|
||||
fSession = session;
|
||||
fLaunch = launch;
|
||||
fServicesTracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), fSession.getId());
|
||||
try {
|
||||
fSession.getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
|
@ -68,28 +78,93 @@ public class DsfSuspendTrigger implements ISuspendTrigger {
|
|||
}
|
||||
|
||||
@ThreadSafe
|
||||
public void addSuspendTriggerListener(ISuspendTriggerListener listener) {
|
||||
if (fListeners != null) {
|
||||
fListeners.add(listener);
|
||||
}
|
||||
public void addSuspendTriggerListener(final ISuspendTriggerListener listener) {
|
||||
fListeners.add(listener);
|
||||
|
||||
// Check if an execution context in the model is already suspended.
|
||||
// If so notify the listener.
|
||||
getIsLaunchSuspended(new DataRequestMonitor<Boolean>(ImmediateExecutor.getInstance(), null) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
if (!fDisposed && getData().booleanValue()) {
|
||||
listener.suspended(fLaunch, null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ThreadSafe
|
||||
public void removeSuspendTriggerListener(ISuspendTriggerListener listener) {
|
||||
if (fListeners != null) {
|
||||
fListeners.remove(listener);
|
||||
}
|
||||
fListeners.remove(listener);
|
||||
}
|
||||
|
||||
@ThreadSafe
|
||||
public void dispose() {
|
||||
if (fEventListenerRegisterd) {
|
||||
fSession.removeServiceEventListener(this);
|
||||
}
|
||||
fServicesTracker.dispose();
|
||||
fDisposed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @noreference This method is not intended to be referenced by clients.
|
||||
*/
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(IRunControl.ISuspendedDMEvent e) {
|
||||
fireSuspended(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @noreference This method is not intended to be referenced by clients.
|
||||
*/
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(DataModelInitializedEvent e) {
|
||||
getIsLaunchSuspended(new DataRequestMonitor<Boolean>(ImmediateExecutor.getInstance(), null) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
if (!fDisposed && getData().booleanValue()) {
|
||||
fireSuspended(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the services tracker used by the suspend trigger.
|
||||
* @since 2.1
|
||||
*/
|
||||
protected DsfServicesTracker getServicesTracker() {
|
||||
return fServicesTracker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the launch for this suspend trigger.
|
||||
* @since 2.1
|
||||
*/
|
||||
@ThreadSafe
|
||||
protected ILaunch getLaunch() {
|
||||
return fLaunch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the DSF session for this suspend trigger.
|
||||
* @since 2.1
|
||||
*/
|
||||
@ThreadSafe
|
||||
protected DsfSession getSession() {
|
||||
return fSession;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the listeners that a suspend event was received.
|
||||
*
|
||||
* @param context
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
@ThreadSafe
|
||||
protected void fireSuspended(final Object context) {
|
||||
final Object[] listeners = fListeners.getListeners();
|
||||
if (listeners.length != 0) {
|
||||
new Job("DSF Suspend Trigger Notify") { //$NON-NLS-1$
|
||||
|
@ -104,7 +179,7 @@ public class DsfSuspendTrigger implements ISuspendTrigger {
|
|||
final ISuspendTriggerListener listener = (ISuspendTriggerListener) listeners[i];
|
||||
SafeRunner.run(new ISafeRunnable() {
|
||||
public void run() throws Exception {
|
||||
listener.suspended(fLaunch, null);
|
||||
listener.suspended(fLaunch, context);
|
||||
}
|
||||
|
||||
public void handleException(Throwable exception) {
|
||||
|
@ -120,4 +195,144 @@ public class DsfSuspendTrigger implements ISuspendTrigger {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the top-level containers for this launch. This method should
|
||||
* be overriden by specific debugger integrations.
|
||||
* @param rm
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
@ThreadSafe
|
||||
protected void getLaunchTopContainers(DataRequestMonitor<IContainerDMContext[]> rm) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Not implemented.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given launch is currently suspended.
|
||||
*
|
||||
* @param rm Request monitor.
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
@ThreadSafe
|
||||
private void getIsLaunchSuspended(final DataRequestMonitor<Boolean> rm) {
|
||||
getLaunchTopContainers(new DataRequestMonitor<IContainerDMContext[]>(fSession.getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
final CountingRequestMonitor crm = new CountingRequestMonitor(fSession.getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
if (rm.getData() == null) {
|
||||
rm.setData(Boolean.FALSE);
|
||||
}
|
||||
rm.done();
|
||||
};
|
||||
};
|
||||
int count = 0;
|
||||
for (final IContainerDMContext containerCtx : getData()) {
|
||||
getIsContainerSuspended(containerCtx, new DataRequestMonitor<Boolean>(ImmediateExecutor.getInstance(), crm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
if (getData().booleanValue()) {
|
||||
rm.setData(Boolean.TRUE);
|
||||
}
|
||||
crm.done();
|
||||
};
|
||||
});
|
||||
count++;
|
||||
}
|
||||
crm.setDoneCount(count);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively checks if the given container or any of its execution
|
||||
* contexts are suspended.
|
||||
*
|
||||
* @param container Container to check.
|
||||
* @param rm Request monitor.
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
@ConfinedToDsfExecutor("fSession.getExecutor()")
|
||||
private void getIsContainerSuspended(final IContainerDMContext container, final DataRequestMonitor<Boolean> rm) {
|
||||
// Check if run control service is still available.
|
||||
IRunControl rc = fServicesTracker.getService(IRunControl.class);
|
||||
if (rc == null) {
|
||||
rm.setData(Boolean.FALSE);
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if container is suspended. If so, stop searching.
|
||||
if (rc.isSuspended(container)) {
|
||||
rm.setData(Boolean.TRUE);
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieve the execution contexts and check if any of them are suspended.
|
||||
rc.getExecutionContexts(
|
||||
container,
|
||||
new DataRequestMonitor<IExecutionDMContext[]>(fSession.getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
// Check if run control service is still available.
|
||||
IRunControl rc = fServicesTracker.getService(IRunControl.class);
|
||||
if (rc == null) {
|
||||
rm.setData(Boolean.FALSE);
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
// If any of the execution contexts are suspended, stop searching
|
||||
boolean hasContainers = false;
|
||||
for (IExecutionDMContext execCtx : getData()) {
|
||||
if (rc.isSuspended(execCtx)) {
|
||||
rm.setData(Boolean.TRUE);
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
hasContainers = hasContainers || execCtx instanceof IContainerDMContext;
|
||||
}
|
||||
|
||||
// If any of the returned contexts were containers, check them recursively.
|
||||
if (hasContainers) {
|
||||
final CountingRequestMonitor crm = new CountingRequestMonitor(fSession.getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
if (rm.getData() == null) {
|
||||
rm.setData(Boolean.FALSE);
|
||||
}
|
||||
rm.done();
|
||||
};
|
||||
};
|
||||
int count = 0;
|
||||
for (IExecutionDMContext execCtx : getData()) {
|
||||
if (execCtx instanceof IContainerDMContext) {
|
||||
getIsContainerSuspended(
|
||||
(IContainerDMContext)execCtx,
|
||||
new DataRequestMonitor<Boolean>(ImmediateExecutor.getInstance(), crm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
if (getData().booleanValue()) {
|
||||
rm.setData(Boolean.TRUE);
|
||||
}
|
||||
crm.done();
|
||||
};
|
||||
});
|
||||
count++;
|
||||
}
|
||||
}
|
||||
crm.setDoneCount(count);
|
||||
} else {
|
||||
rm.setData(Boolean.FALSE);
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
point="org.eclipse.debug.ui.contextViewBindings">
|
||||
<contextViewBinding
|
||||
contextId="org.eclipse.cdt.examples.dsf.pda.debugging"
|
||||
viewId="org.eclipse.cdt.examples.dsf.pda.dataStackView"/>
|
||||
viewId="org.eclipse.debug.ui.ExpressionView"/>
|
||||
</extension>
|
||||
|
||||
<extension
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.examples.dsf.pda.ui;
|
||||
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
||||
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.ui.contexts.DsfSuspendTrigger;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.cdt.examples.dsf.pda.service.PDACommandControl;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.debug.core.ILaunch;
|
||||
|
||||
/**
|
||||
* @since 2.1
|
||||
*/
|
||||
public class PDASuspendTrigger extends DsfSuspendTrigger {
|
||||
|
||||
public PDASuspendTrigger(DsfSession session, ILaunch launch) {
|
||||
super(session, launch);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getLaunchTopContainers(final DataRequestMonitor<IContainerDMContext[]> rm) {
|
||||
try {
|
||||
getSession().getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
PDACommandControl control =
|
||||
getServicesTracker().getService(PDACommandControl.class);
|
||||
if (control != null) {
|
||||
rm.setData(new IContainerDMContext[] { control.getContext() });
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, PDAUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Not available", null));
|
||||
}
|
||||
rm.done();
|
||||
|
||||
}
|
||||
});
|
||||
} catch (RejectedExecutionException e) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, PDAUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Not available", e));
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,24 +10,19 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.examples.dsf.pda.ui;
|
||||
|
||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.ui.actions.DsfResumeCommand;
|
||||
import org.eclipse.cdt.dsf.debug.ui.actions.DsfStepIntoCommand;
|
||||
import org.eclipse.cdt.dsf.debug.ui.actions.DsfStepOverCommand;
|
||||
import org.eclipse.cdt.dsf.debug.ui.actions.DsfStepReturnCommand;
|
||||
import org.eclipse.cdt.dsf.debug.ui.actions.DsfSuspendCommand;
|
||||
import org.eclipse.cdt.dsf.debug.ui.contexts.DsfSuspendTrigger;
|
||||
import org.eclipse.cdt.dsf.debug.ui.sourcelookup.DsfSourceDisplayAdapter;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.SteppingController;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.DefaultDsfModelSelectionPolicyFactory;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.DefaultDsfSelectionPolicy;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
|
||||
import org.eclipse.cdt.examples.dsf.pda.PDAPlugin;
|
||||
import org.eclipse.cdt.examples.dsf.pda.launch.PDALaunch;
|
||||
import org.eclipse.cdt.examples.dsf.pda.ui.actions.PDATerminateCommand;
|
||||
import org.eclipse.cdt.examples.dsf.pda.ui.viewmodel.PDAVMAdapter;
|
||||
import org.eclipse.debug.core.ILaunch;
|
||||
import org.eclipse.debug.core.commands.IResumeHandler;
|
||||
import org.eclipse.debug.core.commands.IStepIntoHandler;
|
||||
import org.eclipse.debug.core.commands.IStepOverHandler;
|
||||
|
@ -36,10 +31,7 @@ import org.eclipse.debug.core.commands.ISuspendHandler;
|
|||
import org.eclipse.debug.core.commands.ITerminateHandler;
|
||||
import org.eclipse.debug.core.model.IDebugModelProvider;
|
||||
import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelSelectionPolicy;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelSelectionPolicyFactory;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
|
||||
import org.eclipse.debug.ui.IDebugUIConstants;
|
||||
import org.eclipse.debug.ui.sourcelookup.ISourceDisplay;
|
||||
|
||||
/**
|
||||
|
@ -59,7 +51,7 @@ class SessionAdapterSet {
|
|||
final DsfSuspendCommand fSuspendCommand;
|
||||
final DsfResumeCommand fResumeCommand;
|
||||
final PDATerminateCommand fTerminateCommand;
|
||||
final DsfSuspendTrigger fSuspendTrigger;
|
||||
final PDASuspendTrigger fSuspendTrigger;
|
||||
|
||||
// Adapters for integration with other UI actions
|
||||
final IDebugModelProvider fDebugModelProvider;
|
||||
|
@ -96,7 +88,7 @@ class SessionAdapterSet {
|
|||
fSuspendCommand = new DsfSuspendCommand(session);
|
||||
fResumeCommand = new DsfResumeCommand(session);
|
||||
fTerminateCommand = new PDATerminateCommand(session);
|
||||
fSuspendTrigger = new DsfSuspendTrigger(session, fLaunch);
|
||||
fSuspendTrigger = new PDASuspendTrigger(session, fLaunch);
|
||||
|
||||
session.registerModelAdapter(IStepIntoHandler.class, fStepIntoCommand);
|
||||
session.registerModelAdapter(IStepOverHandler.class, fStepOverCommand);
|
||||
|
|
|
@ -12,6 +12,7 @@ package org.eclipse.cdt.examples.dsf.pda.launch;
|
|||
|
||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.Sequence;
|
||||
import org.eclipse.cdt.dsf.datamodel.DataModelInitializedEvent;
|
||||
import org.eclipse.cdt.dsf.debug.service.BreakpointsMediator;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.cdt.examples.dsf.pda.service.PDABackend;
|
||||
|
@ -105,12 +106,18 @@ public class PDAServicesInitSequence extends Sequence {
|
|||
new PDARegisters(fSession).initialize(requestMonitor);
|
||||
}
|
||||
},
|
||||
/*
|
||||
* Indicate that the Data Model has been filled. This will trigger the Debug view to expand.
|
||||
*/
|
||||
new Step() {
|
||||
@Override
|
||||
public void execute(RequestMonitor requestMonitor) {
|
||||
fRunControl.resume(fCommandControl.getContext(), requestMonitor);
|
||||
public void execute(final RequestMonitor requestMonitor) {
|
||||
fSession.dispatchEvent(
|
||||
new DataModelInitializedEvent(fCommandControl.getContext()),
|
||||
fCommandControl.getProperties());
|
||||
requestMonitor.done();
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
// Sequence input parameters, used in initializing services.
|
||||
|
|
|
@ -192,6 +192,7 @@ public class PDAExpressions extends AbstractDsfService implements ICachingServic
|
|||
fCommandControl = getServicesTracker().getService(PDACommandControl.class);
|
||||
fStack = getServicesTracker().getService(PDAStack.class);
|
||||
fCommandCache = new CommandCache(getSession(), fCommandControl);
|
||||
fCommandCache.setContextAvailable(fCommandControl.getContext(), true);
|
||||
|
||||
getSession().addServiceEventListener(this, null);
|
||||
|
||||
|
|
|
@ -207,6 +207,7 @@ public class PDAStack extends AbstractDsfService implements IStack, ICachingServ
|
|||
|
||||
// Create the commands cache
|
||||
fCommandCache = new CommandCache(getSession(), fCommandControl);
|
||||
fCommandCache.setContextAvailable(fCommandControl.getContext(), true);
|
||||
|
||||
// Register to listen for run control events, to clear cache accordingly.
|
||||
getSession().addServiceEventListener(this, null);
|
||||
|
|
Loading…
Add table
Reference in a new issue