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 721434516c9..3473cdf966e 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 @@ -994,6 +994,11 @@ public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunCo rm.done(); } } + @Override + public void rollBack(RequestMonitor rm) { + Sequence.Step restoreStep = new RestoreTargetStateStep(); + restoreStep.execute(rm); + } }; /** 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 e907dcb7e37..303e041ce4b 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 @@ -28,7 +28,7 @@ public interface IMIRunControl extends IRunControl2 * to receive commands. Once the specified steps are executed, the target should be * returned to its original availability. * - * This can is of value for breakpoints commands; e.g., breakpoints need to be inserted + * This is of value for breakpoints commands; e.g., breakpoints need to be inserted * even when the target is running, so this call would suspend the target, insert the * breakpoint, and resume the target again. * 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 d34416a92c6..162df681aff 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 @@ -1012,6 +1012,11 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl, I rm.done(); } } + @Override + public void rollBack(RequestMonitor rm) { + Sequence.Step restoreStep = new RestoreTargetStateStep(); + restoreStep.execute(rm); + } }; /** diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIBreakpointsTest.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIBreakpointsTest.java index fadc3ae887d..ebf1c075c6a 100644 --- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIBreakpointsTest.java +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIBreakpointsTest.java @@ -1238,6 +1238,54 @@ public class MIBreakpointsTest extends BaseTestCase { ((MIBreakpointHitEvent)event).getNumber() == ref.getReference()); } + // ------------------------------------------------------------------------ + // insertInvalidBreakpoint_WhileTargetRunning + // Set an invalid breakpoint while the target is running, then set a valid + // breakpoint and make sure the second breakpoints eventually gets hit. + // + // We had a problem where an invalid breakpoint set when the target was running + // would leave us in a bad state (Bug 314628) + // ------------------------------------------------------------------------ + @Test + public void insertInvalidBreakpoint_WhileTargetRunning() throws Throwable { + + // Create a line breakpoint + Map breakpoint = new HashMap(); + breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG); + breakpoint.put(FILE_NAME_TAG, "Bad file name"); + breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_5); + + // Run the program. It will make a two second sleep() call, during which time... + SyncUtil.resume(); + + // ...we install the bad breakpoint and check that it failed + insertBreakpoint(fBreakpointsDmc, breakpoint); + assertTrue(fWait.getMessage(), !fWait.isOK()); + + // Now install a proper breakpoint an see that it hits without having to resume + // the target. This will show that the target was still properly running. + breakpoint.put(FILE_NAME_TAG, SOURCE_FILE); + MIBreakpointDMContext ref = (MIBreakpointDMContext) insertBreakpoint(fBreakpointsDmc, breakpoint); + + // Wait for breakpoint to hit. + MIStoppedEvent event = waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(true, 2); + + // Ensure the correct BreakpointEvent was received + MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref); + assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received " + + fBreakpointEventCount, fBreakpointEventCount == 2); + assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_HIT event(s), received " + + getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1); + assertTrue("BreakpointService problem: breakpoint mismatch", + fBreakpointRef == breakpoint1.getNumber()); + clearEventCounters(); + + assertTrue("Did not stop because of breakpoint, but stopped because of: " + + event.getClass().getCanonicalName(), event instanceof MIBreakpointHitEvent); + assertTrue("Did not stop because of the correct breakpoint at line " + LINE_NUMBER_5, + ((MIBreakpointHitEvent)event).getNumber() == ref.getReference()); + } + /////////////////////////////////////////////////////////////////////////// // Add Watchpoint tests ///////////////////////////////////////////////////////////////////////////