1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 17:05:26 +02:00

[249165] Support for ResumeAtLine in both CEditor and DSF Disassembly view

This commit is contained in:
Marc Khouzam 2010-02-11 20:57:17 +00:00
parent e2cc17c5cb
commit 88cea3fb22
8 changed files with 265 additions and 23 deletions

View file

@ -45,7 +45,7 @@ import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.texteditor.ITextEditor;
/**
* Move to line target adapter for the CDI debugger
* Move to line target adapter for the CDI and DSF-GDB debuggers
*/
public class MoveToLineAdapter implements IMoveToLineTarget {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2007 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
@ -45,7 +45,7 @@ import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.texteditor.ITextEditor;
/**
* Resume at line target adapter for the CDI debugger
* Resume at line target adapter for the CDI and DSF-GDB debuggers
*/
public class ResumeAtLineAdapter implements IResumeAtLineTarget {
@ -68,7 +68,7 @@ public class ResumeAtLineAdapter implements IResumeAtLineTarget {
else {
final String fileName = getFileName( input ); // actually, absolute path, not just file name
IDebugTarget debugTarget = null;
if ( target instanceof CDebugElement ) { // should always be, but just in case
if ( target instanceof CDebugElement ) {
debugTarget = ((CDebugElement)target).getDebugTarget();
}
final IPath path = convertPath( fileName, debugTarget );
@ -161,12 +161,10 @@ public class ResumeAtLineAdapter implements IResumeAtLineTarget {
return false;
}
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;
int lineNumber = textSelection.getStartLine() + 1;

View file

@ -15,6 +15,7 @@ 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.GdbResumeAtLine;
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;
@ -23,9 +24,10 @@ import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.ISuspendResume;
/**
* Adapter factory for Run-To-Line and Move-To-Line
* Adapter factory for Run-To-Line, Move-To-Line
* and Resume-At-Line
*
* @since 3.0
* @since 2.1
*/
public class GdbSuspendResumeAdapterFactory implements IAdapterFactory {
@ -33,10 +35,12 @@ public class GdbSuspendResumeAdapterFactory implements IAdapterFactory {
private final GdbRunToLine fRunToLine;
private final GdbMoveToLine fMoveToLine;
private final GdbResumeAtLine fResumeAtLine;
GdbSuspendResume(IExecutionDMContext execCtx) {
fRunToLine = new GdbRunToLine(execCtx);
fMoveToLine = new GdbMoveToLine(execCtx);
fResumeAtLine = new GdbResumeAtLine(execCtx);
}
public Object getAdapter(Class adapter) {
@ -46,6 +50,9 @@ public class GdbSuspendResumeAdapterFactory implements IAdapterFactory {
if (adapter.isInstance(fMoveToLine)) {
return fMoveToLine;
}
if (adapter.isInstance(fResumeAtLine)) {
return fResumeAtLine;
}
return null;
}
@ -62,8 +69,8 @@ public class GdbSuspendResumeAdapterFactory implements IAdapterFactory {
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
// It only makes sense to RunToLine, MoveToLine or
// ResumeAtLine if we are dealing with a thread, not a container
if (execDmc != null && !(execDmc instanceof IContainerDMContext)) {
return new GdbSuspendResume(execDmc);
}

View file

@ -53,10 +53,10 @@ public class DisassemblyMoveToLineAdapter implements IMoveToLineTarget {
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)) {
final IMoveToAddress moveToAddress = (IMoveToAddress)((IAdaptable)target).getAdapter(IMoveToAddress.class);
if (moveToAddress != null && moveToAddress.canMoveToAddress(address)) {
try {
runToAddress.moveToAddress(address);
moveToAddress.moveToAddress(address);
}
catch(DebugException e) {
failed(e);
@ -68,8 +68,8 @@ public class DisassemblyMoveToLineAdapter implements IMoveToLineTarget {
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) {
IMoveToAddress moveToAddress = (IMoveToAddress)((IAdaptable)target).getAdapter(IMoveToAddress.class);
if (moveToAddress == null) {
return false;
}
@ -83,7 +83,7 @@ public class DisassemblyMoveToLineAdapter implements IMoveToLineTarget {
}
final IAddress address = new Addr64(rawAddress);
return runToAddress.canMoveToAddress(address);
return moveToAddress.canMoveToAddress(address);
}
return false;

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.IResumeAtAddress;
import org.eclipse.cdt.debug.internal.ui.actions.IResumeAtLineTarget;
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;
/**
* Resume at line target adapter for the DSF Disassembly view
*
* @since 2.1
*/
public class DisassemblyResumeAtLineAdapter implements IResumeAtLineTarget {
public void resumeAtLine(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 IResumeAtAddress resumeAtAddress = (IResumeAtAddress)((IAdaptable)target).getAdapter(IResumeAtAddress.class);
if (resumeAtAddress != null && resumeAtAddress.canResumeAtAddress(address)) {
try {
resumeAtAddress.resumeAtAddress(address);
}
catch(DebugException e) {
failed(e);
}
}
}
}
}
public boolean canResumeAtLine(IWorkbenchPart part, ISelection selection, ISuspendResume target) {
if (target instanceof IAdaptable && part instanceof IDisassemblyPart && selection instanceof ITextSelection) {
IResumeAtAddress resumeAtAddress = (IResumeAtAddress)((IAdaptable)target).getAdapter(IResumeAtAddress.class);
if (resumeAtAddress == 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 resumeAtAddress.canResumeAtAddress(address);
}
return false;
}
protected void failed( Throwable e ) {
MultiStatus ms = new MultiStatus(CDIDebugModel.getPluginIdentifier(), IDsfStatusConstants.REQUEST_FAILED, "Resume At Line failed", null); //$NON-NLS-1$
ms.add( new Status(IStatus.ERROR, CDIDebugModel.getPluginIdentifier(), IDsfStatusConstants.REQUEST_FAILED, e.getMessage(), e));
GdbUIPlugin.log(ms);
}
}

View file

@ -41,7 +41,7 @@ import org.eclipse.debug.core.DebugException;
/**
* Implements the CDT's move to line interface.
*
* @since 3.0
* @since 2.1
*/
public class GdbMoveToLine implements IMoveToLine, IMoveToAddress {
@ -105,13 +105,13 @@ public class GdbMoveToLine implements IMoveToLine, IMoveToAddress {
new DsfServicesTracker(GdbUIPlugin.getBundleContext(), fContext.getSessionId());
IRunControl runControl = tracker.getService(IRunControl.class);
tracker.dispose();
if (runControl != null) {
runControl.canResume(fContext, rm);
} else {
rm.setData(false);
rm.done();
}
tracker.dispose();
}
};
session.getExecutor().execute(query);

View file

@ -0,0 +1,140 @@
/*******************************************************************************
* 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.concurrent.ExecutionException;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.debug.core.model.IResumeAtAddress;
import org.eclipse.cdt.debug.core.model.IResumeAtLine;
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.debug.service.IRunControl;
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.IMIRunControl;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
/**
* Implements the CDT's resume at line interface.
*
* @since 2.1
*/
public class GdbResumeAtLine implements IResumeAtLine, IResumeAtAddress {
private final IExecutionDMContext fContext;
public GdbResumeAtLine(IExecutionDMContext context) {
fContext = context;
}
public boolean canResumeAtLine(IFile file, int lineNumber) {
return canResumeAtLocation();
}
public boolean canResumeAtLine(String fileName, int lineNumber) {
return canResumeAtLocation();
}
public void resumeAtLine(IFile file, int lineNumber) throws DebugException {
resumeAtLine(file.getLocation().makeAbsolute().toOSString(), lineNumber);
}
public void resumeAtLine(String fileName, int lineNumber) throws DebugException {
resumeAtLocation(fileName + ":" + lineNumber); //$NON-NLS-1$
}
public boolean canResumeAtAddress(IAddress address) {
return canResumeAtLocation();
}
public void resumeAtAddress(IAddress address) throws DebugException {
resumeAtLocation("*0x" + address.toString(16)); //$NON-NLS-1$
}
private boolean canResumeAtLocation() {
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);
tracker.dispose();
if (runControl != null) {
runControl.canResume(fContext, rm);
} else {
rm.setData(false);
rm.done();
}
}
};
session.getExecutor().execute(query);
return query.get();
} catch (RejectedExecutionException e) {
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}
}
return false;
}
private void resumeAtLocation(final String location) 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) {
final DsfServicesTracker tracker =
new DsfServicesTracker(GdbUIPlugin.getBundleContext(), fContext.getSessionId());
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();
}
}
};
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 resume at 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

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