From f83c63c05fb42eafbbc83aa575aadc5acab705da Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Mon, 9 May 2011 01:43:13 +0000 Subject: [PATCH] Bug 246740: Restart action does not work when the program is running --- .../cdt/dsf/gdb/service/GDBProcesses.java | 9 ++++ .../cdt/dsf/gdb/service/GDBProcesses_7_0.java | 47 +++++++++++++++---- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses.java index 4f1a6aebb52..fec0ee877f9 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses.java @@ -437,6 +437,15 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses { /** @since 4.0 */ public void restart(IContainerDMContext containerDmc, Map attributes, DataRequestMonitor rm) { + // Before performing the restart, check if the process is properly suspended. + // Don't need to worry about non-stop before GDB 7.0, so we can simply + // interrupt the backend, if needed + // Bug 246740 + IMIRunControl runControl = getServicesTracker().getService(IMIRunControl.class); + if (runControl != null && !runControl.isTargetAcceptingCommands()) { + fBackend.interrupt(); + } + startOrRestart(containerDmc, attributes, true, rm); } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_0.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_0.java index e4a72e26793..c3d0b7ab721 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_0.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_0.java @@ -38,6 +38,7 @@ import org.eclipse.cdt.dsf.debug.service.ICachingService; import org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext; import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext; import org.eclipse.cdt.dsf.debug.service.IProcesses; +import org.eclipse.cdt.dsf.debug.service.IRunControl; import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerResumedDMEvent; import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent; @@ -1244,18 +1245,46 @@ public class GDBProcesses_7_0 extends AbstractDsfService } /** @since 4.0 */ - public void restart(IContainerDMContext containerDmc, Map attributes, DataRequestMonitor rm) { + public void restart(final IContainerDMContext containerDmc, final Map attributes, final DataRequestMonitor rm) { fProcRestarting = true; - startOrRestart(containerDmc, attributes, true, new DataRequestMonitor(ImmediateExecutor.getInstance(), rm) { + + // Before performing the restart, check if the process is properly suspended. + // For such a case, we usually use IMIRunControl.isTargetAcceptingCommands(). + // However, in non-stop, although the target is accepting command, a restart + // won't work because it needs to be able to set breakpoints. So, to allow + // for breakpoints to be set, we make sure process is actually suspended. + // + // The other way to make this work is to have the restart code set the breakpoints + // using the breakpoint service, instead of sending the breakpoint command directly. + // This required more changes than suspending the process, so it was not done + // just yet. + // Bug 246740 + + // This request monitor actually performs the restart + RequestMonitor restartRm = new RequestMonitor(ImmediateExecutor.getInstance(), rm) { @Override - protected void handleCompleted() { - if (!isSuccess()) { - fProcRestarting = false; - } - setData(getData()); - super.handleCompleted(); + protected void handleSuccess() { + startOrRestart(containerDmc, attributes, true, new DataRequestMonitor(ImmediateExecutor.getInstance(), rm) { + @Override + protected void handleCompleted() { + if (!isSuccess()) { + fProcRestarting = false; + } + setData(getData()); + super.handleCompleted(); + }; + }); }; - }); + }; + + IRunControl runControl = getServicesTracker().getService(IRunControl.class); + if (runControl != null && !runControl.isSuspended(containerDmc)) { + // The process is running. Let's suspended it before doing the restart + runControl.suspend(containerDmc, restartRm); + } else { + // The process is already suspended, we can just trigger the restart + restartRm.done(); + } } /** @since 4.0 */