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:
parent
fce20bcbf6
commit
faae34208e
12 changed files with 510 additions and 111 deletions
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 };
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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$
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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$
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
// ------------------------------------------------------------------------
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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$
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue