1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 08:55:25 +02:00

[249162] Added MoveToLine support for both the Editor and the DSF Disassembly view. Currently this only works for GDB 7.0. Bug 302597 must be fixed to have this work with older GDBs

This commit is contained in:
Marc Khouzam 2010-02-11 16:27:03 +00:00
parent fce20bcbf6
commit faae34208e
12 changed files with 510 additions and 111 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2005 QNX Software Systems and others.
* Copyright (c) 2004, 2010 QNX Software 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
@ -7,6 +7,7 @@
*
* Contributors:
* QNX Software Systems - Initial API and implementation
* Ericsson - Update to support DSF-GDB retargetting MoveToLine
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.actions;
@ -67,31 +68,30 @@ public class MoveToLineAdapter implements IMoveToLineTarget {
else {
final String fileName = getFileName( input );
IDebugTarget debugTarget = null;
if (target instanceof CDebugElement) { // should always be, but just in case
if (target instanceof CDebugElement) {
debugTarget = ((CDebugElement)target).getDebugTarget();
}
if (debugTarget != null) {
ITextSelection textSelection = (ITextSelection)selection;
final int lineNumber = textSelection.getStartLine() + 1;
if ( target instanceof IAdaptable ) {
final IPath path = convertPath( fileName, debugTarget );
final IMoveToLine moveToLine = (IMoveToLine)((IAdaptable)target).getAdapter( IMoveToLine.class );
if ( moveToLine != null && moveToLine.canMoveToLine( path.toPortableString(), lineNumber ) ) {
Runnable r = new Runnable() {
public void run() {
try {
moveToLine.moveToLine(path.toPortableString(), lineNumber );
}
catch( DebugException e ) {
failed( e );
}
ITextSelection textSelection = (ITextSelection)selection;
final int lineNumber = textSelection.getStartLine() + 1;
if ( target instanceof IAdaptable ) {
final IPath path = convertPath( fileName, debugTarget );
final IMoveToLine moveToLine = (IMoveToLine)((IAdaptable)target).getAdapter( IMoveToLine.class );
if ( moveToLine != null && moveToLine.canMoveToLine( path.toPortableString(), lineNumber ) ) {
Runnable r = new Runnable() {
public void run() {
try {
moveToLine.moveToLine(path.toPortableString(), lineNumber );
}
};
runInBackground( r );
}
catch( DebugException e ) {
failed( e );
}
}
};
runInBackground( r );
}
return;
}
return;
}
}
}
@ -163,12 +163,9 @@ public class MoveToLineAdapter implements IMoveToLineTarget {
}
IDebugTarget debugTarget = null;
if (target instanceof CDebugElement) { // should always be, but just in case
if (target instanceof CDebugElement) {
debugTarget = ((CDebugElement)target).getDebugTarget();
}
if (debugTarget == null) {
return false;
}
final IPath path = convertPath( fileName, debugTarget );
ITextSelection textSelection = (ITextSelection)selection;

View file

@ -163,7 +163,7 @@
<adapter type="org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory"/>
</factory>
<factory
class="org.eclipse.cdt.dsf.gdb.internal.ui.GdbRunToLineAdapterFactory"
class="org.eclipse.cdt.dsf.gdb.internal.ui.GdbSuspendResumeAdapterFactory"
adaptableType="org.eclipse.cdt.dsf.ui.viewmodel.IVMContext">
<adapter type="org.eclipse.debug.core.model.ISuspendResume"/>
</factory>

View file

@ -1,68 +1,78 @@
/*******************************************************************************
* Copyright (c) 2009 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 org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.gdb.internal.ui.actions.GdbRunToLine;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.ISuspendResume;
/**
* @since 2.0
*/
public class GdbRunToLineAdapterFactory implements IAdapterFactory {
static class GdbSuspendResume implements ISuspendResume, IAdaptable {
private final GdbRunToLine fRunToLine;
GdbSuspendResume(IExecutionDMContext execCtx) {
fRunToLine = new GdbRunToLine(execCtx);
}
public Object getAdapter(Class adapter) {
if (adapter.isInstance(fRunToLine)) {
return fRunToLine;
}
return null;
}
public boolean canResume() { return false; }
public boolean canSuspend() { return false; }
public boolean isSuspended() { return false; }
public void resume() throws DebugException {}
public void suspend() throws DebugException {}
}
public Object getAdapter(Object adaptableObject, Class adapterType) {
if (ISuspendResume.class.equals(adapterType)) {
if (adaptableObject instanceof IDMVMContext) {
IExecutionDMContext execDmc = DMContexts.getAncestorOfType(
((IDMVMContext)adaptableObject).getDMContext(),
IExecutionDMContext.class);
// It only makes sense to RunToLine if we are dealing with a thread, not a container
if (execDmc != null && !(execDmc instanceof IContainerDMContext)) {
return new GdbSuspendResume(execDmc);
}
}
}
return null;
}
public Class[] getAdapterList() {
return new Class[] { ISuspendResume.class };
}
/*******************************************************************************
* Copyright (c) 2009, 2010 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
* Ericsson - Updated to support Move-To-Line
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.gdb.internal.ui.actions.GdbMoveToLine;
import org.eclipse.cdt.dsf.gdb.internal.ui.actions.GdbRunToLine;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.ISuspendResume;
/**
* Adapter factory for Run-To-Line and Move-To-Line
*
* @since 3.0
*/
public class GdbSuspendResumeAdapterFactory implements IAdapterFactory {
static class GdbSuspendResume implements ISuspendResume, IAdaptable {
private final GdbRunToLine fRunToLine;
private final GdbMoveToLine fMoveToLine;
GdbSuspendResume(IExecutionDMContext execCtx) {
fRunToLine = new GdbRunToLine(execCtx);
fMoveToLine = new GdbMoveToLine(execCtx);
}
public Object getAdapter(Class adapter) {
if (adapter.isInstance(fRunToLine)) {
return fRunToLine;
}
if (adapter.isInstance(fMoveToLine)) {
return fMoveToLine;
}
return null;
}
public boolean canResume() { return false; }
public boolean canSuspend() { return false; }
public boolean isSuspended() { return false; }
public void resume() throws DebugException {}
public void suspend() throws DebugException {}
}
public Object getAdapter(Object adaptableObject, Class adapterType) {
if (ISuspendResume.class.equals(adapterType)) {
if (adaptableObject instanceof IDMVMContext) {
IExecutionDMContext execDmc = DMContexts.getAncestorOfType(
((IDMVMContext)adaptableObject).getDMContext(),
IExecutionDMContext.class);
// It only makes sense to RunToLine or MoveToLine
// if we are dealing with a thread, not a container
if (execDmc != null && !(execDmc instanceof IContainerDMContext)) {
return new GdbSuspendResume(execDmc);
}
}
}
return null;
}
public Class[] getAdapterList() {
return new Class[] { ISuspendResume.class };
}
}

View file

@ -0,0 +1,97 @@
/*******************************************************************************
* Copyright (c) 2010 Ericsson 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:
* Ericsson - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.actions;
import java.math.BigInteger;
import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.debug.core.CDIDebugModel;
import org.eclipse.cdt.debug.core.model.IMoveToAddress;
import org.eclipse.cdt.debug.internal.ui.actions.IMoveToLineTarget;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.DisassemblySelection;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.IDisassemblyPart;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.IDisassemblySelection;
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
import org.eclipse.cdt.utils.Addr64;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.ISuspendResume;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IWorkbenchPart;
/**
* Move to line target adapter for the DSF Disassembly view
*
* @since 2.1
*/
public class DisassemblyMoveToLineAdapter implements IMoveToLineTarget {
public void moveToLine(IWorkbenchPart part, ISelection selection, ISuspendResume target) throws CoreException {
if (part instanceof IDisassemblyPart && selection instanceof ITextSelection) {
if (!(selection instanceof IDisassemblySelection)) {
selection = new DisassemblySelection((ITextSelection)selection, (IDisassemblyPart)part);
}
IDisassemblySelection disassemblySelection = (IDisassemblySelection)selection;
BigInteger rawAddress = disassemblySelection.getStartAddress();
if (rawAddress == null) {
return;
}
final IAddress address = new Addr64(rawAddress);
if (address != null && target instanceof IAdaptable) {
final IMoveToAddress runToAddress = (IMoveToAddress)((IAdaptable)target).getAdapter(IMoveToAddress.class);
if (runToAddress != null && runToAddress.canMoveToAddress(address)) {
try {
runToAddress.moveToAddress(address);
}
catch(DebugException e) {
failed(e);
}
}
}
}
}
public boolean canMoveToLine(IWorkbenchPart part, ISelection selection, ISuspendResume target) {
if (target instanceof IAdaptable && part instanceof IDisassemblyPart && selection instanceof ITextSelection) {
IMoveToAddress runToAddress = (IMoveToAddress)((IAdaptable)target).getAdapter(IMoveToAddress.class);
if (runToAddress == null) {
return false;
}
if (!(selection instanceof IDisassemblySelection)) {
selection = new DisassemblySelection((ITextSelection)selection, (IDisassemblyPart)part);
}
IDisassemblySelection disassemblySelection = (IDisassemblySelection)selection;
BigInteger rawAddress = disassemblySelection.getStartAddress();
if (rawAddress == null) {
return false;
}
final IAddress address = new Addr64(rawAddress);
return runToAddress.canMoveToAddress(address);
}
return false;
}
protected void failed( Throwable e ) {
MultiStatus ms = new MultiStatus(CDIDebugModel.getPluginIdentifier(), IDsfStatusConstants.REQUEST_FAILED, "MoveToLine failed", null); //$NON-NLS-1$
ms.add( new Status(IStatus.ERROR, CDIDebugModel.getPluginIdentifier(), IDsfStatusConstants.REQUEST_FAILED, e.getMessage(), e));
GdbUIPlugin.log(ms);
}
}

View file

@ -60,18 +60,13 @@ public class DisassemblyRunToLineAdapter implements IRunToLineTarget {
if (address != null && target instanceof IAdaptable) {
final IRunToAddress runToAddress = (IRunToAddress)((IAdaptable)target).getAdapter(IRunToAddress.class);
if (runToAddress != null && runToAddress.canRunToAddress(address)) {
// Runnable r = new Runnable() {
// public void run() {
try {
boolean skipBreakpoints = DebugUITools.getPreferenceStore().getBoolean(IDebugUIConstants.PREF_SKIP_BREAKPOINTS_DURING_RUN_TO_LINE);
runToAddress.runToAddress(address, skipBreakpoints);
}
catch( DebugException e ) {
failed( e );
}
// }
// };
// DebugPlugin.getDefault().asyncExec(r);
try {
boolean skipBreakpoints = DebugUITools.getPreferenceStore().getBoolean(IDebugUIConstants.PREF_SKIP_BREAKPOINTS_DURING_RUN_TO_LINE);
runToAddress.runToAddress(address, skipBreakpoints);
}
catch(DebugException e) {
failed(e);
}
}
}
}
@ -108,5 +103,4 @@ public class DisassemblyRunToLineAdapter implements IRunToLineTarget {
ms.add( new Status( IStatus.ERROR, CDIDebugModel.getPluginIdentifier(), IDsfStatusConstants.REQUEST_FAILED, e.getMessage(), e ) );
GdbUIPlugin.log(ms);
}
}

View file

@ -0,0 +1,187 @@
/*******************************************************************************
* Copyright (c) 2010 Ericsson 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:
* Ericsson - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.actions;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.debug.core.model.IMoveToAddress;
import org.eclipse.cdt.debug.core.model.IMoveToLine;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.concurrent.Query;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints;
import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointDMContext;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIRunControl;
import org.eclipse.cdt.dsf.mi.service.MIBreakpointDMData;
import org.eclipse.cdt.dsf.mi.service.MIBreakpoints;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
/**
* Implements the CDT's move to line interface.
*
* @since 3.0
*/
public class GdbMoveToLine implements IMoveToLine, IMoveToAddress {
private final IExecutionDMContext fContext;
public GdbMoveToLine(IExecutionDMContext context) {
fContext = context;
}
public boolean canMoveToLine(String fileName, int lineNumber) {
return canMoveToLocation();
}
public void moveToLine(String fileName, int lineNumber) throws DebugException {
IMIExecutionDMContext threadExecDmc = DMContexts.getAncestorOfType(fContext, IMIExecutionDMContext.class);
if (threadExecDmc == null) {
throw new DebugException(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Invalid thread context", null)); //$NON-NLS-1$
}
// Create the breakpoint attributes
Map<String,Object> attr = new HashMap<String,Object>();
attr.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.BREAKPOINT);
attr.put(MIBreakpoints.FILE_NAME, fileName);
attr.put(MIBreakpoints.LINE_NUMBER, lineNumber);
attr.put(MIBreakpointDMData.IS_TEMPORARY, true);
attr.put(MIBreakpointDMData.THREAD_ID, Integer.toString(threadExecDmc.getThreadId()));
// Now do the operation
moveToLocation(fileName + ":" + lineNumber, attr); //$NON-NLS-1$
}
public boolean canMoveToAddress(IAddress address) {
return canMoveToLocation();
}
public void moveToAddress(IAddress address) throws DebugException {
IMIExecutionDMContext threadExecDmc = DMContexts.getAncestorOfType(fContext, IMIExecutionDMContext.class);
if (threadExecDmc == null) {
throw new DebugException(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Invalid thread context", null)); //$NON-NLS-1$
}
// Create the breakpoint attributes
Map<String,Object> attr = new HashMap<String,Object>();
attr.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.BREAKPOINT);
attr.put(MIBreakpoints.ADDRESS, "0x" + address.toString(16)); //$NON-NLS-1$
attr.put(MIBreakpointDMData.IS_TEMPORARY, true);
attr.put(MIBreakpointDMData.THREAD_ID, Integer.toString(threadExecDmc.getThreadId()));
// Now do the operation
moveToLocation("*0x" + address.toString(16), attr); //$NON-NLS-1$
}
private boolean canMoveToLocation() {
DsfSession session = DsfSession.getSession(fContext.getSessionId());
if (session != null && session.isActive()) {
try {
Query<Boolean> query = new Query<Boolean>() {
@Override
protected void execute(DataRequestMonitor<Boolean> rm) {
DsfServicesTracker tracker =
new DsfServicesTracker(GdbUIPlugin.getBundleContext(), fContext.getSessionId());
IRunControl runControl = tracker.getService(IRunControl.class);
if (runControl != null) {
runControl.canResume(fContext, rm);
} else {
rm.setData(false);
rm.done();
}
tracker.dispose();
}
};
session.getExecutor().execute(query);
return query.get();
} catch (RejectedExecutionException e) {
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}
}
return false;
}
private void moveToLocation(final String location, final Map<String,Object> bpAttributes) throws DebugException {
final DsfSession session = DsfSession.getSession(fContext.getSessionId());
if (session != null && session.isActive()) {
Throwable exception = null;
try {
Query<Object> query = new Query<Object>() {
@Override
protected void execute(final DataRequestMonitor<Object> rm) {
// first create a temporary breakpoint to stop the execution at
// the location we are about to jump to
final DsfServicesTracker tracker =
new DsfServicesTracker(GdbUIPlugin.getBundleContext(), fContext.getSessionId());
IBreakpoints bpService = tracker.getService(IBreakpoints.class);
IBreakpointsTargetDMContext bpDmc = DMContexts.getAncestorOfType(fContext, IBreakpointsTargetDMContext.class);
if (bpService != null && bpDmc != null) {
bpService.insertBreakpoint(
bpDmc, bpAttributes,
new DataRequestMonitor<IBreakpointDMContext>(session.getExecutor(), rm) {
@Override
protected void handleSuccess() {
// Now resume at the proper location
IMIRunControl miRunControl = tracker.getService(IMIRunControl.class);
tracker.dispose();
if (miRunControl != null) {
miRunControl.resumeAtLocation(fContext, location, rm);
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "MIRunControl service not available", null)); //$NON-NLS-1$
rm.done();
}
};
@Override
protected void handleFailure() {
tracker.dispose();
super.handleFailure();
};
});
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Unable to set breakpoint", null)); //$NON-NLS-1$
rm.done();
tracker.dispose();
}
}
};
session.getExecutor().execute(query);
query.get();
} catch (RejectedExecutionException e) {
exception = e;
} catch (InterruptedException e) {
exception = e;
} catch (ExecutionException e) {
exception = e;
}
if (exception != null) {
throw new DebugException(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Faild executing move to line", exception)); //$NON-NLS-1$
}
} else {
throw new DebugException(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Debug session is not active", null)); //$NON-NLS-1$
}
}
}

View file

@ -137,10 +137,10 @@ public class GdbRunToLine implements IRunToLine, IRunToAddress {
exception = e;
}
if (exception != null) {
new DebugException(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Faild executing run to line", exception)); //$NON-NLS-1$
throw new DebugException(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Faild executing run to line", exception)); //$NON-NLS-1$
}
} else {
new DebugException(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Debug session is not active", null)); //$NON-NLS-1$
throw new DebugException(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Debug session is not active", null)); //$NON-NLS-1$
}
}
}

View file

@ -32,9 +32,9 @@ public class RetargettableActionAdapterFactory implements IAdapterFactory {
// if (adapterType == IResumeAtLineTarget.class) {
// return new DisassemblyResumeAtLineAdapter();
// }
// if (adapterType == IMoveToLineTarget.class) {
// return new DisassemblyMoveToLineAdapter();
// }
if (adapterType == IMoveToLineTarget.class) {
return new DisassemblyMoveToLineAdapter();
}
return null;
}

View file

@ -38,6 +38,7 @@ import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
import org.eclipse.cdt.dsf.mi.service.IMIRunControl;
import org.eclipse.cdt.dsf.mi.service.MIRunControl;
import org.eclipse.cdt.dsf.mi.service.MIStack;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIJump;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakDelete;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakInsert;
import org.eclipse.cdt.dsf.mi.service.command.commands.MICommand;
@ -668,6 +669,48 @@ public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunCo
}
// ------------------------------------------------------------------------
// Resume at location
// ------------------------------------------------------------------------
/** @since 3.0 */
public void resumeAtLocation(IExecutionDMContext context, String location, RequestMonitor rm) {
assert context != null;
final IMIExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class);
if (dmc == null) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED,
"Given context: " + context + " is not an MI execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$
rm.done();
return;
}
if (!doCanResume(dmc)) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE,
"Cannot resume context", null)); //$NON-NLS-1$
rm.done();
return;
}
final MIThreadRunState threadState = fThreadRunStates.get(dmc);
if (threadState == null) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE,
"Given context: " + dmc + " is not an MI execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$
rm.done();
return;
}
threadState.fResumePending = true;
fConnection.queueCommand(
new CLIJump(dmc, location),
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
@Override
protected void handleFailure() {
threadState.fResumePending = false;
super.handleFailure();
}
});
}
// ------------------------------------------------------------------------
// Support functions
// ------------------------------------------------------------------------

View file

@ -30,5 +30,15 @@ public interface IMIRunControl extends IRunControl
* @since 3.0
*/
void runToLocation(IExecutionDMContext context, String location, boolean skipBreakpoints, RequestMonitor rm);
/**
* Request to resume the program starting at the specified location.
* The specified location can be anywhere in the program, but proper
* program behavior is not guaranteed after this operation.
*
* @since 3.0
*/
void resumeAtLocation(IExecutionDMContext context, String location, RequestMonitor rm);
}

View file

@ -26,6 +26,7 @@ import org.eclipse.cdt.dsf.debug.service.command.CommandCache;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlShutdownDMEvent;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIJump;
import org.eclipse.cdt.dsf.mi.service.command.commands.MICommand;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecContinue;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecFinish;
@ -706,6 +707,38 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl, I
}
}
/** @since 3.0 */
public void resumeAtLocation(IExecutionDMContext context, String location, RequestMonitor rm) {
assert context != null;
final IMIExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class);
if (dmc == null){
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Given context: " + context + " is not an thread execution context.", null)); //$NON-NLS-1$ //$NON-NLS-2$
rm.done();
return;
}
if (doCanResume(dmc)) {
fResumePending = true;
fMICommandCache.setContextAvailable(dmc, false);
fConnection.queueCommand(
new CLIJump(dmc, location),
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
@Override
protected void handleFailure() {
fResumePending = false;
fMICommandCache.setContextAvailable(dmc, true);
super.handleFailure();
}
});
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED,
"Cannot resume given DMC.", null)); //$NON-NLS-1$
rm.done();
}
}
/**
* {@inheritDoc}
* @since 1.1

View file

@ -0,0 +1,28 @@
/*******************************************************************************
* Copyright (c) 2010 Ericsson 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:
* Ericsson - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
/**
* jump LINESPEC
* jump LOCATION
* Resume execution at line LINESPEC or at address given by LOCATION.
*
* @since 3.0
*/
public class CLIJump extends CLICommand<MIInfo> {
public CLIJump(IExecutionDMContext ctx, String location) {
super(ctx, "jump " + location); //$NON-NLS-1$
}
}