From 5f8fa75f1fc80299954c6cb9d3524ed471c6ebf2 Mon Sep 17 00:00:00 2001 From: Muhammad Bilal Date: Thu, 17 Dec 2020 19:57:04 +0500 Subject: [PATCH] Bug 516371: Enable GDB target async support for Windows remote debugging Traditionally CDT used sync debug support all the time. However there are cases where using target async is better because of GDB missing interrupt. This patch expands the cases that use target async to be all remote targets when using Windows host. That is in addition to cases when the full GDB Console is supported (new-ui). Signed-off-by: Muhammad Bilal Change-Id: I1309d20319a24e4f23543d4ed22735044fd5b811 --- .../.settings/.api_filters | 11 ++++++++++ .../META-INF/MANIFEST.MF | 2 +- .../launching/FinalLaunchSequence_7_12.java | 6 +++--- .../cdt/dsf/gdb/service/GDBBackend_7_12.java | 11 ++++++++++ .../dsf/gdb/service/GDBProcesses_7_12.java | 8 ++++---- .../dsf/gdb/service/GDBRunControl_7_12.java | 12 +++-------- .../cdt/dsf/gdb/service/IGDBBackend.java | 8 ++++++++ .../GDBJtagDSFFinalLaunchSequence_7_12.java | 20 +++++++++---------- 8 files changed, 50 insertions(+), 28 deletions(-) create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/.settings/.api_filters diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/.settings/.api_filters b/dsf-gdb/org.eclipse.cdt.dsf.gdb/.settings/.api_filters new file mode 100644 index 00000000000..989277b68f2 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/.settings/.api_filters @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF b/dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF index b96d89727bb..4f1996970cf 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-SymbolicName: org.eclipse.cdt.dsf.gdb;singleton:=true -Bundle-Version: 6.1.0.qualifier +Bundle-Version: 6.2.0.qualifier Bundle-Activator: org.eclipse.cdt.dsf.gdb.internal.GdbPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime, diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence_7_12.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence_7_12.java index 3cd02b138e2..6e53e683bd4 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence_7_12.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence_7_12.java @@ -107,11 +107,11 @@ public class FinalLaunchSequence_7_12 extends FinalLaunchSequence_7_7 { return; } - // Use target async for non-stop mode or when the - // Full GDB CLI console is being used. + // Use target async for non-stop mode or when + // it is specifically enabled by backend in all-stop mode // Otherwise Explicitly set target-async to off boolean asyncOn = false; - if (isNonStop() || fGdbBackEnd.isFullGdbConsoleSupported()) { + if (isNonStop() || fGdbBackEnd.useTargetAsync()) { asyncOn = true; } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend_7_12.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend_7_12.java index a1255e2d357..5c2b57162c5 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend_7_12.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend_7_12.java @@ -63,6 +63,17 @@ public class GDBBackend_7_12 extends GDBBackend { && !fPtyFailure; } + /** + * @since 6.2 + */ + @Override + public boolean useTargetAsync() { + // Enable target asynchronously if there is Full GDB console as Full GDB Console requires async target or + // If Windows remote debugging as remote debugging in GDB has lots of issues with handling Ctrl-C (See Bug 516371) + return isFullGdbConsoleSupported() + || (Platform.getOS().equals(Platform.OS_WIN32) && getSessionType() == SessionType.REMOTE); + } + protected void createPty() { if (!isFullGdbConsoleSupported()) { return; diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_12.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_12.java index ce585b07ce8..c69c86d7091 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_12.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_12.java @@ -47,12 +47,12 @@ public class GDBProcesses_7_12 extends GDBProcesses_7_11 { @Override public void terminate(IThreadDMContext thread, RequestMonitor rm) { IGDBBackend backend = getServicesTracker().getService(IGDBBackend.class); - if (!backend.isFullGdbConsoleSupported()) { + if (!backend.useTargetAsync()) { super.terminate(thread, rm); return; } - // If we are running the full GDB console, there is a bug with GDB 7.12 + // If we are running the target-async support, there is a bug with GDB 7.12 // where after we terminate the process, the GDB prompt does not come // back in the console. As a workaround, we first interrupt the process // to get the prompt back, and only then kill the process. @@ -93,12 +93,12 @@ public class GDBProcesses_7_12 extends GDBProcesses_7_11 { } IGDBBackend backend = getServicesTracker().getService(IGDBBackend.class); - if (!backend.isFullGdbConsoleSupported()) { + if (!backend.useTargetAsync()) { super.detachDebuggerFromProcess(dmc, rm); return; } - // If we are running the full GDB console, there is a bug with GDB 7.12 + // If we are running the target-async support, there is a bug with GDB 7.12 // where after we detach the process, the GDB prompt does not come // back in the console. As a workaround, we first interrupt the process // to get the prompt back, and only then detach the process. diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_12.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_12.java index b578bb90b5f..ac548b6d92e 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_12.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_12.java @@ -92,10 +92,7 @@ public class GDBRunControl_7_12 extends GDBRunControl_7_10 { private void doSuspend(IExecutionDMContext context, final RequestMonitor rm) { // We use the MI interrupt command when working in async mode. - // Since this run control service is specifically for all-stop mode, - // the only possibility to be running asynchronously is if the Full GDB console - // is being used. - if (fGDBBackEnd.isFullGdbConsoleSupported()) { + if (fGDBBackEnd.useTargetAsync()) { // Start the job before sending the interrupt command // to make sure we don't miss the *stopped event final MonitorSuspendJob monitorJob = new MonitorSuspendJob(0, rm); @@ -124,11 +121,8 @@ public class GDBRunControl_7_12 extends GDBRunControl_7_10 { @Override public boolean isTargetAcceptingCommands() { - // We shall directly return true if the async mode is ON, - // Since this run control service is specifically for all-stop mode, - // The only possibility to be running asynchronously is if the Full GDB console - // is being used. - if (fGDBBackEnd.isFullGdbConsoleSupported()) { + // We shall directly return true if the async mode is ON. + if (fGDBBackEnd.useTargetAsync()) { return true; } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBBackend.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBBackend.java index e283b628d65..96d39dfd0d9 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBBackend.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBBackend.java @@ -170,6 +170,14 @@ public interface IGDBBackend extends IMIBackend { return false; } + /** + * @return True if CDT should use target async in all-stop mode. + * @since 6.2 + */ + default boolean useTargetAsync() { + return false; + } + /** * @return The real GDB process that was started for the debug session * @since 5.2 diff --git a/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/GDBJtagDSFFinalLaunchSequence_7_12.java b/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/GDBJtagDSFFinalLaunchSequence_7_12.java index 07906b652f4..9ba9aab526c 100644 --- a/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/GDBJtagDSFFinalLaunchSequence_7_12.java +++ b/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/GDBJtagDSFFinalLaunchSequence_7_12.java @@ -64,17 +64,15 @@ public class GDBJtagDSFFinalLaunchSequence_7_12 extends GDBJtagDSFFinalLaunchSeq if (commandControl != null && gdbBackEnd != null) { // Use target async when interfacing with the full GDB console (i.e. minimum GDB version 7.12) // otherwise explicitly set it to off. - commandControl - .queueCommand( - commandControl.getCommandFactory().createMIGDBSetTargetAsync(commandControl.getContext(), - gdbBackEnd.isFullGdbConsoleSupported()), - new DataRequestMonitor(getExecutor(), rm) { - @Override - protected void handleError() { - // Accept errors for older GDBs - rm.done(); - } - }); + commandControl.queueCommand(commandControl.getCommandFactory() + .createMIGDBSetTargetAsync(commandControl.getContext(), gdbBackEnd.useTargetAsync()), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleError() { + // Accept errors for older GDBs + rm.done(); + } + }); } else { // Should not happen rm.done();