diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/MoveToLineAdapter.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/MoveToLineAdapter.java index 7f534c1bfad..60d20566284 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/MoveToLineAdapter.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/MoveToLineAdapter.java @@ -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; diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml index 9d26c5623fc..7da9aefff36 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml @@ -163,7 +163,7 @@ diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbRunToLineAdapterFactory.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbSuspendResumeAdapterFactory.java similarity index 77% rename from dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbRunToLineAdapterFactory.java rename to dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbSuspendResumeAdapterFactory.java index 577fe1927fe..359fee67f8e 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbRunToLineAdapterFactory.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbSuspendResumeAdapterFactory.java @@ -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 }; + } } \ No newline at end of file diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/DisassemblyMoveToLineAdapter.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/DisassemblyMoveToLineAdapter.java new file mode 100644 index 00000000000..f6ac646e5ec --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/DisassemblyMoveToLineAdapter.java @@ -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); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/DisassemblyRunToLineAdapter.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/DisassemblyRunToLineAdapter.java index d71dc11f2aa..8d52e698cf3 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/DisassemblyRunToLineAdapter.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/DisassemblyRunToLineAdapter.java @@ -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); } - } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbMoveToLine.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbMoveToLine.java new file mode 100644 index 00000000000..4e951dce759 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbMoveToLine.java @@ -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 attr = new HashMap(); + 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 attr = new HashMap(); + 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 query = new Query() { + @Override + protected void execute(DataRequestMonitor 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 bpAttributes) throws DebugException { + final DsfSession session = DsfSession.getSession(fContext.getSessionId()); + if (session != null && session.isActive()) { + Throwable exception = null; + try { + Query query = new Query() { + @Override + protected void execute(final DataRequestMonitor 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(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$ + } + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbRunToLine.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbRunToLine.java index d2b24caf26b..bac32feb781 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbRunToLine.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbRunToLine.java @@ -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$ } } } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/RetargettableActionAdapterFactory.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/RetargettableActionAdapterFactory.java index 4f2936dbd56..f9cc74eb0d9 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/RetargettableActionAdapterFactory.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/RetargettableActionAdapterFactory.java @@ -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; } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0_NS.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0_NS.java index 67120104903..28bc6eac504 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0_NS.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0_NS.java @@ -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(getExecutor(), rm) { + @Override + protected void handleFailure() { + threadState.fResumePending = false; + super.handleFailure(); + } + }); + } // ------------------------------------------------------------------------ // Support functions // ------------------------------------------------------------------------ diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/IMIRunControl.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/IMIRunControl.java index 3b896aec08a..7ebc54cc971 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/IMIRunControl.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/IMIRunControl.java @@ -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); + } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIRunControl.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIRunControl.java index ab9dd0eec78..bfaec9a9556 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIRunControl.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIRunControl.java @@ -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(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 diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/CLIJump.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/CLIJump.java new file mode 100644 index 00000000000..c6c02a7c310 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/CLIJump.java @@ -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 { + + public CLIJump(IExecutionDMContext ctx, String location) { + super(ctx, "jump " + location); //$NON-NLS-1$ + } +}