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

Bug 365776 - [breakpoints] Add breakpoint action to toggle reverse

debugging.


Change-Id: I065297685fefba76df7ad40c578a0ce5d0c40fba
Reviewed-on: https://git.eclipse.org/r/8982
IP-Clean: Marc Khouzam <marc.khouzam@ericsson.com>
Tested-by: Marc Khouzam <marc.khouzam@ericsson.com>
Reviewed-by: Marc Khouzam <marc.khouzam@ericsson.com>
This commit is contained in:
Marc Dumais 2012-12-13 13:21:13 -05:00 committed by Marc Khouzam
parent e58a3323c8
commit c2605537bc
9 changed files with 454 additions and 2 deletions

View file

@ -0,0 +1,37 @@
/*******************************************************************************
* Copyright (c) 2007, 2012 Nokia 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:
* Marc Dumais (Ericsson) - initial implementation
*******************************************************************************/
package org.eclipse.cdt.debug.core.breakpointactions;
/**
* @since 7.3
*/
public interface IReverseDebugEnabler {
/**
* Toggles the state of the reverse debugging mode.
* @throws Exception
*/
void toggle() throws Exception;
/**
* Enables the reverse debugging mode. No effect if already enabled.
* @throws Exception
*/
void enable() throws Exception;
/**
* Disables the reverse debugging mode. No effect if it's not enabled.
* @throws Exception
*/
void disable() throws Exception;
}

View file

@ -11,6 +11,7 @@
# Patrick Chuong (Texas Instruments) - Pin and Clone Supports (Bug 331781)
# Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 336876)
# Marc Khouzam (Ericsson) - Added support for connect command (Bug 365601)
# Marc Dumais (Ericsson) - Added support for reverse debug action (Bug 365776)
###############################################################################
pluginName=C/C++ Development Tools Debugger UI
@ -157,6 +158,7 @@ SoundAction.name=Sound Action
LogAction.name=Log Action
ResumeAction.name=Resume Action
ExternalToolAction.name=External Tool Action
ReverseDebugAction.name=Reverse Debug Action
# Breakpoint Types
breapointType.label=Type

View file

@ -1710,6 +1710,14 @@
class="org.eclipse.cdt.debug.ui.breakpointactions.ExternalToolAction"
id="org.eclipse.cdt.debug.ui.breakpointactions.ExternalToolAction"/>
</extension>
<extension
point="org.eclipse.cdt.debug.core.BreakpointActionType">
<actionType
class="org.eclipse.cdt.debug.ui.breakpointactions.ReverseDebugAction"
id="org.eclipse.cdt.debug.ui.breakpointactions.ReverseDebugAction"
name="%ReverseDebugAction.name">
</actionType>
</extension>
<extension
point="org.eclipse.cdt.debug.ui.BreakpointActionPage">
<actionPage
@ -1740,6 +1748,14 @@
id="org.eclipse.cdt.debug.ui.breakpointactions.ExternalToolActionPage"
actionType="org.eclipse.cdt.debug.ui.breakpointactions.ExternalToolAction"/>
</extension>
<extension
point="org.eclipse.cdt.debug.ui.BreakpointActionPage">
<actionPage
actionType="org.eclipse.cdt.debug.ui.breakpointactions.ReverseDebugAction"
class="org.eclipse.cdt.debug.ui.breakpointactions.ReverseDebugActionPage"
id="org.eclipse.cdt.debug.ui.breakpointactions.ReverseDebugActionPage">
</actionPage>
</extension>
<extension point="org.eclipse.debug.ui.detailPaneFactories">
<detailFactories

View file

@ -0,0 +1,193 @@
/*******************************************************************************
* Copyright (c) 2007, 2012 Nokia 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 implementation
*******************************************************************************/
package org.eclipse.cdt.debug.ui.breakpointactions;
import java.io.ByteArrayOutputStream;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.eclipse.cdt.debug.core.CDIDebugModel;
import org.eclipse.cdt.debug.core.breakpointactions.AbstractBreakpointAction;
import org.eclipse.cdt.debug.core.breakpointactions.IReverseDebugEnabler;
import org.eclipse.cdt.debug.internal.core.ICDebugInternalConstants;
import org.eclipse.cdt.debug.internal.ui.IInternalCDebugUIConstants;
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.model.IBreakpoint;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.helpers.DefaultHandler;
/**
* Implements the reverse debug breakpoint action
*
*@since 7.3
*/
public class ReverseDebugAction extends AbstractBreakpointAction{
/**
* The available reverse debug action modes: enable, disable and toggle.
*/
public static enum REVERSE_DEBUG_ACTIONS_ENUM {
ENABLE, DISABLE, TOGGLE;
/**
* @param index
* @return the enum value for the given index
*/
public static REVERSE_DEBUG_ACTIONS_ENUM getValue(int index) {
return REVERSE_DEBUG_ACTIONS_ENUM.values()[index];
}
};
private REVERSE_DEBUG_ACTIONS_ENUM fOperation;
/**
* @return the currently configured reverse debug mode, for this BP action
*/
public REVERSE_DEBUG_ACTIONS_ENUM getOperation() {
return fOperation;
}
/**
* Sets the currently configured reverse debug mode, for this BP action
* @param operation
*/
public void setOperation(REVERSE_DEBUG_ACTIONS_ENUM operation) {
this.fOperation = operation;
}
@Override
public IStatus execute(IBreakpoint breakpoint, IAdaptable context, IProgressMonitor monitor) {
IStatus errorStatus = null;
IReverseDebugEnabler enabler = (IReverseDebugEnabler) context.getAdapter(IReverseDebugEnabler.class);
if (enabler != null) {
try {
switch (fOperation) {
case TOGGLE:
enabler.toggle();
break;
case ENABLE:
enabler.enable();
break;
case DISABLE:
enabler.disable();
break;
}
} catch (Exception e) {
errorStatus = new Status( IStatus.ERROR, CDIDebugModel.getPluginIdentifier(), ICDebugInternalConstants.STATUS_CODE_ERROR, e.getMessage(), e );
}
}
else
errorStatus = new Status( IStatus.ERROR, CDebugUIPlugin.getUniqueIdentifier(), IInternalCDebugUIConstants.INTERNAL_ERROR, Messages.getString("ReverseDebugAction.error.0"), null ); //$NON-NLS-1$
if (errorStatus != null) {
MultiStatus ms = new MultiStatus( CDIDebugModel.getPluginIdentifier(), ICDebugInternalConstants.STATUS_CODE_ERROR, Messages.getString("ReverseDebugAction.error.1"), null ); //$NON-NLS-1$
ms.add( errorStatus);
errorStatus = ms;
} else {
errorStatus = monitor.isCanceled() ? Status.CANCEL_STATUS : Status.OK_STATUS;
}
return errorStatus;
}
@Override
public String getMemento() {
String reverseDebugData = ""; //$NON-NLS-1$
DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = null;
try {
docBuilder = dfactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("reverseDebugData"); //$NON-NLS-1$
rootElement.setAttribute("operation", fOperation.toString()); //$NON-NLS-1$
doc.appendChild(rootElement);
ByteArrayOutputStream s = new ByteArrayOutputStream();
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
DOMSource source = new DOMSource(doc);
StreamResult outputTarget = new StreamResult(s);
transformer.transform(source, outputTarget);
reverseDebugData = s.toString("UTF8"); //$NON-NLS-1$
} catch (Exception e) {
e.printStackTrace();
}
return reverseDebugData;
}
@Override
public void initializeFromMemento(String data) {
Element root = null;
DocumentBuilder parser;
try {
parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
parser.setErrorHandler(new DefaultHandler());
root = parser.parse(new InputSource(new StringReader(data))).getDocumentElement();
String value = root.getAttribute("operation"); //$NON-NLS-1$
if (value == null)
throw new Exception();
fOperation = REVERSE_DEBUG_ACTIONS_ENUM.valueOf(value);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public String getDefaultName() {
return Messages.getString("ReverseDebugAction.UntitledName"); //$NON-NLS-1$
}
@Override
public String getSummary() {
// get translated operation
String operation = Messages.getString("ReverseDebugAction."+fOperation.toString().toLowerCase()); //$NON-NLS-1$
return operation + " " + Messages.getString("ReverseDebugAction.Summary"); //$NON-NLS-1$ //$NON-NLS-2$
}
@Override
public String getTypeName() {
return Messages.getString("ReverseDebugAction.TypeName"); //$NON-NLS-1$
}
@Override
public String getIdentifier() {
return "org.eclipse.cdt.debug.ui.breakpointactions.ReverseDebugAction"; //$NON-NLS-1$
}
}

View file

@ -0,0 +1,58 @@
/*******************************************************************************
* Copyright (c) 2007, 2012 Nokia 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 implementation
*******************************************************************************/
package org.eclipse.cdt.debug.ui.breakpointactions;
import org.eclipse.cdt.debug.ui.breakpointactions.ReverseDebugAction.REVERSE_DEBUG_ACTIONS_ENUM;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
/**
* @since 7.3
*/
public class ReverseDebugActionComposite extends Composite {
private Combo combo;
public ReverseDebugActionComposite(Composite parent, int style, ReverseDebugActionPage page) {
super(parent, style);
final GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 3;
setLayout(gridLayout);
final Label reverseDebugActionLabel = new Label(this, SWT.NONE);
reverseDebugActionLabel.setText(Messages.getString("ReverseDebugActionComposite.label")); //$NON-NLS-1$
// combo widget that lets the user select which reverse debug action to set
combo = new Combo(this, SWT.READ_ONLY);
combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
// add the available reverse debug actions to the combo drop-down list
for(REVERSE_DEBUG_ACTIONS_ENUM elem : REVERSE_DEBUG_ACTIONS_ENUM.values()) {
String option = elem.toString().toLowerCase();
combo.add(Messages.getString("ReverseDebugAction."+option)); //$NON-NLS-1$
}
combo.select(0);
}
/**
* @return The currently selected reverse debug action
*/
public REVERSE_DEBUG_ACTIONS_ENUM getOperation() {
int index = combo.getSelectionIndex();
return REVERSE_DEBUG_ACTIONS_ENUM.getValue(index);
}
}

View file

@ -0,0 +1,42 @@
/*******************************************************************************
* Copyright (c) 2007, 2012 Nokia 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 implementation
*******************************************************************************/
package org.eclipse.cdt.debug.ui.breakpointactions;
import org.eclipse.cdt.debug.core.breakpointactions.IBreakpointAction;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.swt.widgets.Composite;
/**
*@since 7.3
*/
public class ReverseDebugActionPage extends PlatformObject implements IBreakpointActionPage{
private ReverseDebugActionComposite reverseDebugActionComposite;
private ReverseDebugAction reverseDebugAction;
@Override
public void actionDialogCanceled() {
}
@Override
public void actionDialogOK() {
reverseDebugAction.setOperation(reverseDebugActionComposite.getOperation());
}
@Override
public Composite createComposite(IBreakpointAction action,
Composite composite, int style) {
reverseDebugAction = (ReverseDebugAction) action;
reverseDebugActionComposite = new ReverseDebugActionComposite(composite, style, this);
return reverseDebugActionComposite;
}
}

View file

@ -1,5 +1,5 @@
###############################################################################
# Copyright (c) 2005, 2007 Nokia
# Copyright (c) 2005, 2012 Nokia
# 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
@ -60,3 +60,13 @@ ResumeActionComposite.Seconds=seconds
ResumeAction.TypeName=Resume Action
ResumeAction.error.0=IResumeActionEnabler not registered in context.
ResumeAction.error.1=Could not resume.
ReverseDebugAction.UntitledName=Untitled Rev Debug Action
ReverseDebugAction.TypeName=Rev Debug Action
ReverseDebugActionComposite.label=Select Reverse Debugging Action
ReverseDebugAction.Summary= reverse debugging
ReverseDebugAction.error.0=IReverseToggleEnabler not registered in context.
ReverseDebugAction.error.1=Could not do reverse debug operation
ReverseDebugAction.enable=Enable
ReverseDebugAction.disable=Disable
ReverseDebugAction.toggle=Toggle

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2010 Ericsson and others.
* Copyright (c) 2008, 2012 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
@ -7,12 +7,14 @@
*
* Contributors:
* Ericsson - Initial API and implementation
* Marc Dumais (Ericsson) - Added support for reverse debug action (Bug 365776)
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.breakpoint.actions;
import org.eclipse.cdt.debug.core.breakpointactions.ILogActionEnabler;
import org.eclipse.cdt.debug.core.breakpointactions.IResumeActionEnabler;
import org.eclipse.cdt.debug.core.breakpointactions.IReverseDebugEnabler;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
@ -42,6 +44,9 @@ public class BreakpointActionAdapter implements IAdaptable {
if (adapter.equals(IResumeActionEnabler.class)) {
return new MIResumeActionEnabler(fExecutor, fServiceTracker, fContext);
}
if (adapter.equals(IReverseDebugEnabler.class)) {
return new MIReverseDebugEnabler(fExecutor, fServiceTracker, fContext);
}
return null;
}

View file

@ -0,0 +1,89 @@
/*******************************************************************************
* Copyright (c) 2012 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:
* Marc Dumais (Ericsson) - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.breakpoint.actions;
import org.eclipse.cdt.debug.core.breakpointactions.IReverseDebugEnabler;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
import org.eclipse.cdt.dsf.gdb.service.IReverseRunControl;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
/**
*
* This class permits to enable, disable or toggle the reverse
* debugging mode.
*
* @since 4.2
*/
public class MIReverseDebugEnabler implements IReverseDebugEnabler {
private final DsfExecutor fExecutor;
private final DsfServicesTracker fServiceTracker;
private final ICommandControlDMContext fContext;
private static enum REVERSE_DEBUG_MODE {ENABLE, DISABLE, TOGGLE};
/**
* @param executor
* @param serviceTracker
* @param context
*/
public MIReverseDebugEnabler(DsfExecutor executor, DsfServicesTracker serviceTracker, IDMContext context) {
fExecutor = executor;
fServiceTracker = serviceTracker;
fContext = DMContexts.getAncestorOfType(context, ICommandControlDMContext.class);
assert fContext != null;
}
@Override
public void enable() throws Exception {
setMode(REVERSE_DEBUG_MODE.ENABLE);
}
@Override
public void disable() throws Exception {
setMode(REVERSE_DEBUG_MODE.DISABLE);
}
@Override
public void toggle() throws Exception {
setMode(REVERSE_DEBUG_MODE.TOGGLE);
}
private void setMode(final REVERSE_DEBUG_MODE mode) throws Exception {
fExecutor.execute(new DsfRunnable() {
@Override
public void run() {
final IReverseRunControl runControl = fServiceTracker.getService(IReverseRunControl.class);
if (runControl != null) {
runControl.isReverseModeEnabled(fContext, new DataRequestMonitor<Boolean>(fExecutor, null) {
@Override
public void handleSuccess() {
Boolean enabled = getData();
if ( (enabled.equals(false) && mode.equals(REVERSE_DEBUG_MODE.ENABLE) ) ||
(enabled.equals(true) && mode.equals(REVERSE_DEBUG_MODE.DISABLE) ) ||
(mode.equals(REVERSE_DEBUG_MODE.TOGGLE)) )
{
runControl.enableReverseMode(fContext, !enabled, new RequestMonitor(fExecutor, null));
}
}
});
}
}
});
}
}