1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-04 06:45:43 +02:00

Bug 399163 - [reverse] Make use of GDB's new =record-started/stopped MI

events

Change-Id: I168b4734a2971bd71ebd34532bb118aa72ccc70b
Reviewed-on: https://git.eclipse.org/r/9957
Reviewed-by: Marc Khouzam <marc.khouzam@ericsson.com>
IP-Clean: Marc Khouzam <marc.khouzam@ericsson.com>
Tested-by: Marc Khouzam <marc.khouzam@ericsson.com>
This commit is contained in:
Marc Khouzam 2013-01-26 22:53:54 -05:00
parent b4401b6198
commit 35a1eb1832
7 changed files with 373 additions and 5 deletions

View file

@ -124,6 +124,12 @@ public class ReverseToggleCommandHandler extends DebugCommandHandler implements
return adapter; return adapter;
} }
/*
* (non-Javadoc)
* @see org.eclipse.debug.ui.actions.DebugCommandHandler#postExecute(org.eclipse.debug.core.IRequest, java.lang.Object[])
*
* We keep this logic for users that may not do the refresh themselves.
*/
@Override @Override
protected void postExecute(IRequest request, Object[] targets) { protected void postExecute(IRequest request, Object[] targets) {
super.postExecute(request, targets); super.postExecute(request, targets);

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009 Ericsson and others. * Copyright (c) 2009, 2013 Ericsson and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Ericsson - initial API and implementation * Ericsson - initial API and implementation
* Marc Khouzam (Ericsson) - Listen for IReverseModeChangedDMEvent (Bug 399163)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.commands; package org.eclipse.cdt.dsf.gdb.internal.ui.commands;
@ -16,6 +17,7 @@ import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.debug.core.model.IReverseToggleHandler; import org.eclipse.cdt.debug.core.model.IReverseToggleHandler;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor; import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.Query; import org.eclipse.cdt.dsf.concurrent.Query;
import org.eclipse.cdt.dsf.datamodel.DMContexts; import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext; import org.eclipse.cdt.dsf.datamodel.IDMContext;
@ -24,15 +26,23 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin; import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
import org.eclipse.cdt.dsf.gdb.service.IReverseRunControl; import org.eclipse.cdt.dsf.gdb.service.IReverseRunControl;
import org.eclipse.cdt.dsf.gdb.service.IReverseRunControl.IReverseModeChangedDMEvent;
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
import org.eclipse.cdt.dsf.service.DsfServicesTracker; import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.IRequest; import org.eclipse.debug.core.IRequest;
import org.eclipse.debug.core.commands.AbstractDebugCommand; import org.eclipse.debug.core.commands.AbstractDebugCommand;
import org.eclipse.debug.core.commands.IDebugCommandRequest; import org.eclipse.debug.core.commands.IDebugCommandRequest;
import org.eclipse.debug.core.commands.IEnabledStateRequest; import org.eclipse.debug.core.commands.IEnabledStateRequest;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.progress.WorkbenchJob;
import org.eclipse.ui.services.IEvaluationService;
/** /**
* Command that toggles the Reverse Debugging feature * Command that toggles the Reverse Debugging feature
@ -42,13 +52,33 @@ import org.eclipse.debug.core.commands.IEnabledStateRequest;
public class GdbReverseToggleCommand extends AbstractDebugCommand implements IReverseToggleHandler { public class GdbReverseToggleCommand extends AbstractDebugCommand implements IReverseToggleHandler {
private final DsfExecutor fExecutor; private final DsfExecutor fExecutor;
private final DsfServicesTracker fTracker; private final DsfServicesTracker fTracker;
private final DsfSession fSession;
public GdbReverseToggleCommand(DsfSession session) { public GdbReverseToggleCommand(DsfSession session) {
fExecutor = session.getExecutor(); fExecutor = session.getExecutor();
fTracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), session.getId()); fTracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), session.getId());
fSession = session;
try {
fExecutor.execute(new DsfRunnable() {
@Override
public void run() {
fSession.addServiceEventListener(GdbReverseToggleCommand.this, null);
}
});
} catch(RejectedExecutionException e) {}
} }
public void dispose() { public void dispose() {
try {
fExecutor.execute(new DsfRunnable() {
@Override
public void run() {
fSession.removeServiceEventListener(GdbReverseToggleCommand.this);
}
});
} catch (RejectedExecutionException e) {
// Session already gone.
}
fTracker.dispose(); fTracker.dispose();
} }
@ -195,4 +225,30 @@ public class GdbReverseToggleCommand extends AbstractDebugCommand implements IRe
return false; return false;
} }
/**
* @noreference This method is not intended to be referenced by clients.
*/
@DsfServiceEventHandler
public void eventDispatched(IReverseModeChangedDMEvent e) {
new WorkbenchJob("") { //$NON-NLS-1$
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
// Request re-evaluation of property "org.eclipse.cdt.debug.ui.isReverseDebuggingEnabled" to update
// visibility of reverse stepping commands.
IEvaluationService exprService = (IEvaluationService) PlatformUI.getWorkbench().getService(IEvaluationService.class);
if (exprService != null) {
exprService.requestEvaluation("org.eclipse.cdt.debug.ui.isReverseDebuggingEnabled"); //$NON-NLS-1$
}
// Refresh reverse toggle commands with the new state of reverse enabled.
// This is in order to keep multiple toggle actions in UI in sync.
ICommandService commandService = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);
if (commandService != null) {
commandService.refreshElements("org.eclipse.cdt.debug.ui.command.reverseToggle", null); //$NON-NLS-1$
}
return Status.OK_STATUS;
}
}.schedule();
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2008, 2010 Wind River Systems and others. * Copyright (c) 2008, 2013 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -11,6 +11,7 @@
* Ericsson - Version 7.0 * Ericsson - Version 7.0
* Nokia - create and use backend service. * Nokia - create and use backend service.
* Ericsson - Added IReverseControl support * Ericsson - Added IReverseControl support
* Marc Khouzam (Ericsson) - Added IReverseModeChangedDMEvent (Bug 399163)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service; package org.eclipse.cdt.dsf.gdb.service;
@ -21,6 +22,7 @@ import java.util.Hashtable;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor; import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor; import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent;
import org.eclipse.cdt.dsf.datamodel.DMContexts; import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext; import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
@ -52,6 +54,22 @@ import org.eclipse.core.runtime.Status;
public class GDBRunControl_7_0 extends MIRunControl implements IReverseRunControl { public class GDBRunControl_7_0 extends MIRunControl implements IReverseRunControl {
/** @since 4.2 */
protected static class GdbReverseModeChangedDMEvent extends AbstractDMEvent<ICommandControlDMContext>
implements IReverseModeChangedDMEvent {
private boolean fIsEnabled;
public GdbReverseModeChangedDMEvent(ICommandControlDMContext context, boolean enabled) {
super(context);
fIsEnabled = enabled;
}
@Override
public boolean isReverseModeEnabled() {
return fIsEnabled;
}
}
private static class RunToLineActiveOperation { private static class RunToLineActiveOperation {
private IMIExecutionDMContext fThreadContext; private IMIExecutionDMContext fThreadContext;
private int fBpId; private int fBpId;
@ -75,6 +93,7 @@ public class GDBRunControl_7_0 extends MIRunControl implements IReverseRunContro
public boolean shouldSkipBreakpoints() { return fSkipBreakpoints; } public boolean shouldSkipBreakpoints() { return fSkipBreakpoints; }
} }
private IMICommandControl fCommandControl;
private IGDBBackend fGdb; private IGDBBackend fGdb;
private IMIProcesses fProcService; private IMIProcesses fProcService;
private CommandFactory fCommandFactory; private CommandFactory fCommandFactory;
@ -111,7 +130,8 @@ public class GDBRunControl_7_0 extends MIRunControl implements IReverseRunContro
fGdb = getServicesTracker().getService(IGDBBackend.class); fGdb = getServicesTracker().getService(IGDBBackend.class);
fProcService = getServicesTracker().getService(IMIProcesses.class); fProcService = getServicesTracker().getService(IMIProcesses.class);
fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory(); fCommandControl = getServicesTracker().getService(IMICommandControl.class);
fCommandFactory = fCommandControl.getCommandFactory();
if (fGdb.getSessionType() == SessionType.CORE) { if (fGdb.getSessionType() == SessionType.CORE) {
// No execution for core files, so no support for reverse // No execution for core files, so no support for reverse
@ -628,6 +648,10 @@ public class GDBRunControl_7_0 extends MIRunControl implements IReverseRunContro
/** @since 2.0 */ /** @since 2.0 */
public void setReverseModeEnabled(boolean enabled) { public void setReverseModeEnabled(boolean enabled) {
fReverseModeEnabled = enabled; if (fReverseModeEnabled != enabled) {
fReverseModeEnabled = enabled;
getSession().dispatchEvent(new GdbReverseModeChangedDMEvent(fCommandControl.getContext(), fReverseModeEnabled),
getProperties());
}
} }
} }

View file

@ -0,0 +1,104 @@
/*******************************************************************************
* Copyright (c) 2013 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 Khouzam (Ericsson) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
import java.util.Hashtable;
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IRunControl2;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
import org.eclipse.cdt.dsf.debug.service.command.IEventListener;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.mi.service.IMIRunControl;
import org.eclipse.cdt.dsf.mi.service.MIRunControl;
import org.eclipse.cdt.dsf.mi.service.command.output.MINotifyAsyncOutput;
import org.eclipse.cdt.dsf.mi.service.command.output.MIOOBRecord;
import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
/**
* @since 4.2
*/
public class GDBRunControl_7_6 extends GDBRunControl_7_0 implements IEventListener {
private ICommandControl fCommandControl;
public GDBRunControl_7_6(DsfSession session) {
super(session);
}
@Override
public void initialize(final RequestMonitor requestMonitor) {
super.initialize(
new ImmediateRequestMonitor(requestMonitor) {
@Override
public void handleSuccess() {
doInitialize(requestMonitor);
}});
}
private void doInitialize(final RequestMonitor requestMonitor) {
fCommandControl = getServicesTracker().getService(ICommandControl.class);
if (fCommandControl == null) {
requestMonitor.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, "Service is not available")); //$NON-NLS-1$
return;
}
fCommandControl.addEventListener(this);
register(new String[]{IRunControl.class.getName(),
IRunControl2.class.getName(),
IMIRunControl.class.getName(),
MIRunControl.class.getName(),
GDBRunControl_7_0.class.getName(),
GDBRunControl_7_6.class.getName(),
IReverseRunControl.class.getName()},
new Hashtable<String,String>());
requestMonitor.done();
}
@Override
public void shutdown(final RequestMonitor requestMonitor) {
if (fCommandControl != null) {
fCommandControl.removeEventListener(this);
}
unregister();
super.shutdown(requestMonitor);
}
@Override
public void eventReceived(Object output) {
if (output instanceof MIOutput) {
MIOOBRecord[] records = ((MIOutput)output).getMIOOBRecords();
for (MIOOBRecord r : records) {
if (r instanceof MINotifyAsyncOutput) {
MINotifyAsyncOutput notifyOutput = (MINotifyAsyncOutput)r;
String asyncClass = notifyOutput.getAsyncClass();
// These events have been added with GDB 7.6
if ("record-started".equals(asyncClass) || //$NON-NLS-1$
"record-stopped".equals(asyncClass)) { //$NON-NLS-1$
boolean enable = "record-started".equals(asyncClass); //$NON-NLS-1$
setReverseModeEnabled(enable);
}
}
}
}
}
}

View file

@ -215,6 +215,9 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
@Override @Override
protected IRunControl createRunControlService(DsfSession session) { protected IRunControl createRunControlService(DsfSession session) {
if (GDB_7_6_VERSION.compareTo(fVersion) <= 0) {
return new GDBRunControl_7_6(session);
}
if (GDB_7_0_VERSION.compareTo(fVersion) <= 0) { if (GDB_7_0_VERSION.compareTo(fVersion) <= 0) {
return new GDBRunControl_7_0(session); return new GDBRunControl_7_0(session);
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009 Ericsson and others. * Copyright (c) 2009, 2013 Ericsson and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -7,27 +7,94 @@
* *
* Contributors: * Contributors:
* Ericsson - Initial API and implementation * Ericsson - Initial API and implementation
* Marc Khouzam (Ericsson) - Added IReverseModeChangedDMEvent (Bug 399163)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service; package org.eclipse.cdt.dsf.gdb.service;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor; import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.IDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.StepType; import org.eclipse.cdt.dsf.debug.service.IRunControl.StepType;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
/** /**
* This interface provides access to controlling and monitoring the reverse execution
* state of a process being debugged.
*
* @since 2.0 * @since 2.0
*/ */
public interface IReverseRunControl { public interface IReverseRunControl {
/**
* Indicates that the enablement of reverse debugging has changed.
*
* @since 4.2
*/
interface IReverseModeChangedDMEvent extends IDMEvent<ICommandControlDMContext> {
/**
* @return the new state of reverse mode.
*/
boolean isReverseModeEnabled();
};
/**
* Establish if a reverse-resume operation is allowed on the specified context.
*
* @param context The thread or process on which the reverse operation will apply
* @param rm Will contain the result of the operation, true or false, not null.
*/
void canReverseResume(IExecutionDMContext context, DataRequestMonitor<Boolean> rm); void canReverseResume(IExecutionDMContext context, DataRequestMonitor<Boolean> rm);
/**
* Perform a reverse-resume operation on the specified context.
*
* @param context The thread or process on which the reverse operation will apply
*/
void reverseResume(IExecutionDMContext context, RequestMonitor requestMonitor); void reverseResume(IExecutionDMContext context, RequestMonitor requestMonitor);
/**
* Returns whether a reverse-step operation is on-going for the specified context.
*
* @param context The thread or process on which the reverse operation will apply
* @return True if a reverse-steop operation is on-going, false otherwise.
*/
boolean isReverseStepping(IExecutionDMContext context); boolean isReverseStepping(IExecutionDMContext context);
/**
* Establish if a reverse-step operation is allowed on the specified context.
*
* @param context The thread or process on which the reverse operation will apply
* @param rm Will contain the result of the operation, true or false, not null.
*/
void canReverseStep(IExecutionDMContext context, StepType stepType, DataRequestMonitor<Boolean> rm); void canReverseStep(IExecutionDMContext context, StepType stepType, DataRequestMonitor<Boolean> rm);
/**
* Perform a reverse-step operation on the specified context with the specified step type.
*
* @param context The thread or process on which the reverse operation will apply
* @param stepType The step type to be used for the operation
*/
void reverseStep(IExecutionDMContext context, StepType stepType, RequestMonitor requestMonitor); void reverseStep(IExecutionDMContext context, StepType stepType, RequestMonitor requestMonitor);
/**
* Establish if it is possible to enable reverse debugging.
*
* @param rm Will contain the result of the operation, true or false, not null.
*/
void canEnableReverseMode(ICommandControlDMContext context, DataRequestMonitor<Boolean> rm); void canEnableReverseMode(ICommandControlDMContext context, DataRequestMonitor<Boolean> rm);
/**
* Establish if reverse debugging is enabled.
*
* @param rm Will contain the result of the operation, true or false, not null.
*/
void isReverseModeEnabled(ICommandControlDMContext context, DataRequestMonitor<Boolean> rm); void isReverseModeEnabled(ICommandControlDMContext context, DataRequestMonitor<Boolean> rm);
/**
* Enable or disable reverse debugging based on the enable parameter.
*
* @param enable True if reverse debugging should enabled, false for disabled.
*/
void enableReverseMode(ICommandControlDMContext context, boolean enable, RequestMonitor rm); void enableReverseMode(ICommandControlDMContext context, boolean enable, RequestMonitor rm);
} }

View file

@ -12,6 +12,7 @@
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_6; package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_6;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -20,6 +21,7 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.Query; import org.eclipse.cdt.dsf.concurrent.Query;
import org.eclipse.cdt.dsf.datamodel.DMContexts; import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext; import org.eclipse.cdt.dsf.datamodel.IDMContext;
@ -31,7 +33,10 @@ import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
import org.eclipse.cdt.dsf.debug.service.IMemory; import org.eclipse.cdt.dsf.debug.service.IMemory;
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryChangedEvent; import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryChangedEvent;
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext; import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.cdt.dsf.gdb.service.IReverseRunControl;
import org.eclipse.cdt.dsf.gdb.service.IReverseRunControl.IReverseModeChangedDMEvent;
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl; import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
import org.eclipse.cdt.dsf.mi.service.command.events.MIStoppedEvent; import org.eclipse.cdt.dsf.mi.service.command.events.MIStoppedEvent;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
@ -63,6 +68,7 @@ public class GDBConsoleSynchronizingTest_7_6 extends BaseTestCase {
private IGDBControl fCommandControl; private IGDBControl fCommandControl;
private IMemory fMemoryService; private IMemory fMemoryService;
private IExpressions fExprService; private IExpressions fExprService;
private IRunControl fRunControl;
private List<IDMEvent<? extends IDMContext>> fEventsReceived = new ArrayList<IDMEvent<? extends IDMContext>>(); private List<IDMEvent<? extends IDMContext>> fEventsReceived = new ArrayList<IDMEvent<? extends IDMContext>>();
@ -98,6 +104,9 @@ public class GDBConsoleSynchronizingTest_7_6 extends BaseTestCase {
fExprService = fServicesTracker.getService(IExpressions.class); fExprService = fServicesTracker.getService(IExpressions.class);
Assert.assertTrue(fExprService != null); Assert.assertTrue(fExprService != null);
fRunControl = fServicesTracker.getService(IRunControl.class);
Assert.assertTrue(fRunControl != null);
// Register to breakpoint events // Register to breakpoint events
fSession.addServiceEventListener(GDBConsoleSynchronizingTest_7_6.this, null); fSession.addServiceEventListener(GDBConsoleSynchronizingTest_7_6.this, null);
} }
@ -293,6 +302,105 @@ public class GDBConsoleSynchronizingTest_7_6 extends BaseTestCase {
assertEquals(newValue, exprValue); assertEquals(newValue, exprValue);
} }
/**
* This test verifies that enabling reverse debugging from the
* console will properly trigger a DSF event to indicate the change and
* will be processed by the service.
*/
@Test
public void testEnableRecord() throws Throwable {
assertTrue("Reverse debugging is not supported", fRunControl instanceof IReverseRunControl);
final IReverseRunControl reverseService = (IReverseRunControl)fRunControl;
SyncUtil.runToLocation("testMemoryChanges");
// check starting state
Query<Boolean> query = new Query<Boolean>() {
@Override
protected void execute(final DataRequestMonitor<Boolean> rm) {
reverseService.isReverseModeEnabled(fCommandControl.getContext(), rm);
}
};
fSession.getExecutor().execute(query);
Boolean enabled = query.get();
assertTrue("Reverse debugging should not be enabled", !enabled);
fEventsReceived.clear();
queueConsoleCommand("record");
// Wait for the event
IReverseModeChangedDMEvent event = waitForEvent(IReverseModeChangedDMEvent.class);
assertEquals(true, event.isReverseModeEnabled());
// Check the service
query = new Query<Boolean>() {
@Override
protected void execute(final DataRequestMonitor<Boolean> rm) {
reverseService.isReverseModeEnabled(fCommandControl.getContext(), rm);
}
};
fSession.getExecutor().execute(query);
enabled = query.get();
assertTrue("Reverse debugging should be enabled", enabled);
}
/**
* This test verifies that disabling reverse debugging from the
* console will properly trigger a DSF event to indicate the change and
* will be processed by the service.
*/
@Test
public void testDisableRecord() throws Throwable {
assertTrue("Reverse debugging is not supported", fRunControl instanceof IReverseRunControl);
final IReverseRunControl reverseService = (IReverseRunControl)fRunControl;
SyncUtil.runToLocation("testMemoryChanges");
fEventsReceived.clear();
// check starting state
Query<Boolean> query = new Query<Boolean>() {
@Override
protected void execute(final DataRequestMonitor<Boolean> rm) {
reverseService.enableReverseMode(fCommandControl.getContext(), true,
new ImmediateRequestMonitor(rm) {
@Override
protected void handleSuccess() {
reverseService.isReverseModeEnabled(fCommandControl.getContext(), rm);
}
});
}
};
fSession.getExecutor().execute(query);
Boolean enabled = query.get();
assertTrue("Reverse debugging should be enabled", enabled);
// Wait for the event to avoid confusing it with the next one
IReverseModeChangedDMEvent event = waitForEvent(IReverseModeChangedDMEvent.class);
assertEquals(true, event.isReverseModeEnabled());
fEventsReceived.clear();
queueConsoleCommand("record stop");
// Wait for the event
event = waitForEvent(IReverseModeChangedDMEvent.class);
assertEquals(false, event.isReverseModeEnabled());
// Check the service
query = new Query<Boolean>() {
@Override
protected void execute(final DataRequestMonitor<Boolean> rm) {
reverseService.isReverseModeEnabled(fCommandControl.getContext(), rm);
}
};
fSession.getExecutor().execute(query);
enabled = query.get();
assertTrue("Reverse debugging should not be enabled", !enabled);
}
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
// End of tests // End of tests
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////