Skip to content

Commit bd3f3ca

Browse files
committed
Bug 528145 - Breakpoints are not working with remote attach launch
Looking at the logs, it seems that the regression is caused at 8bec791 where support for multi-process was added. We removed breakpoints tracking support from final launch sequence and moved it to debug new process and attach to process logic but none of these are run for remote attach launch, hence breakpoint tracking is not started for remote attach launch. To fix the problem, IGDBProcesses.attachDebuggerToProcess(..) is updated to handle remote attach launch as well instead of final launch sequence handling it. This commit is created after reverting 7bddb5f and 96839a0 which is the older fix done to fix this issue and the other commit was to fix the regression caused by the old fix. The problem with older fix was that for non-stop mode, attach to process was not working for remote launches when there is already a process being debugged. Note that to use this feature, gdbserver should be started with --multi option.
1 parent 5d86225 commit bd3f3ca

File tree

11 files changed

+449
-123
lines changed

11 files changed

+449
-123
lines changed

NewAndNoteworthy/CDT-11.2.md

+4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ This is the New & Noteworthy page for CDT 11.2 which is part of Eclipse 2023-06
1212

1313
Please see [CHANGELOG-API](CHANGELOG-API.md) for details on the breaking API changes in this release as well as future planned API changes.
1414

15+
## `FinalLaunchSequence.stepRemoteConnection()` and `FinalLaunchSequence.stepAttachRemoteToDebugger()` are deprecated and no more called
16+
17+
The remote connection for attach launch is now handled in the implementation of `IGDBProcesses.attachDebuggerToProcess()`
18+
1519
# Noteworthy Issues and Pull Requests
1620

1721
See [Noteworthy issues and PRs](https://github.com/eclipse-cdt/cdt/issues?q=is%3Aclosed+label%3Anoteworthy+milestone%3A11.2.0) for this release in the issue/PR tracker.

NewAndNoteworthy/CHANGELOG-API.md

+8
Original file line numberDiff line numberDiff line change
@@ -665,3 +665,11 @@ The class BuiltinDetctionArgsGeneric will be removed. Use the correctly
665665
spelled BuiltinDetectionArgsGeneric instead.
666666

667667
- org.eclipse.cdt.jsoncdb.core.participant.Arglets.BuiltinDetctionArgsGeneric
668+
669+
## API Removals after June 2025
670+
671+
### <span id="FinalLaunchSequence">FinalLaunchSequence.stepRemoteConnection() and FinalLaunchSequence.stepAttachRemoteToDebugger() will be removed</span>
672+
673+
These APIs will be removed as they are no more used.
674+
675+
See https://github.com/eclipse-cdt/cdt/pull/336

dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2
33
Bundle-Name: %pluginName
44
Bundle-Vendor: %providerName
55
Bundle-SymbolicName: org.eclipse.cdt.dsf.gdb;singleton:=true
6-
Bundle-Version: 7.0.0.qualifier
6+
Bundle-Version: 7.1.0.qualifier
77
Bundle-Activator: org.eclipse.cdt.dsf.gdb.internal.GdbPlugin
88
Bundle-Localization: plugin
99
Require-Bundle: org.eclipse.core.runtime,

dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence.java

+44-46
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,12 @@
4545
import org.eclipse.cdt.dsf.gdb.actions.IConnect;
4646
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
4747
import org.eclipse.cdt.dsf.gdb.service.IGDBBackend;
48+
import org.eclipse.cdt.dsf.gdb.service.IGDBProcesses;
4849
import org.eclipse.cdt.dsf.gdb.service.IGDBSourceLookup;
4950
import org.eclipse.cdt.dsf.gdb.service.SessionType;
5051
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
5152
import org.eclipse.cdt.dsf.mi.service.CSourceLookup;
52-
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
53+
import org.eclipse.cdt.dsf.mi.service.MIProcesses;
5354
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
5455
import org.eclipse.cdt.dsf.mi.service.command.output.MIGDBVersionInfo;
5556
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
@@ -74,7 +75,7 @@ public class FinalLaunchSequence extends ReflectionSequence {
7475

7576
private IGDBControl fCommandControl;
7677
private IGDBBackend fGDBBackend;
77-
private IMIProcesses fProcService;
78+
private IGDBProcesses fProcService;
7879
private CommandFactory fCommandFactory;
7980

8081
private DsfServicesTracker fTracker;
@@ -133,11 +134,9 @@ protected String[] getExecutionOrder(String group) {
133134
//
134135
// "stepSetSourceLookupPath", //$NON-NLS-1$
135136

136-
// For remote-attach launch only
137-
"stepRemoteConnection", //$NON-NLS-1$
138137
// For all launches except attach ones
139138
"stepNewProcess", //$NON-NLS-1$
140-
// For local attach launch only
139+
// For all attach launch only
141140
"stepAttachToProcess", //$NON-NLS-1$
142141
// Global
143142
"stepDataModelInitializationComplete", //$NON-NLS-1$
@@ -173,7 +172,7 @@ public void stepInitializeFinalLaunchSequence(RequestMonitor requestMonitor) {
173172

174173
fCommandFactory = fCommandControl.getCommandFactory();
175174

176-
fProcService = fTracker.getService(IMIProcesses.class);
175+
fProcService = fTracker.getService(IGDBProcesses.class);
177176
if (fProcService == null) {
178177
requestMonitor.setStatus(
179178
new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot obtain process service", null)); //$NON-NLS-1$
@@ -547,37 +546,15 @@ protected void handleError() {
547546
rm.done();
548547
}
549548

550-
private static final String INVALID = "invalid"; //$NON-NLS-1$
551-
552549
/**
553550
* If we are dealing with a remote-attach debugging session, connect to the target.
554551
* @since 4.0
552+
* this is no more added in execution steps
555553
*/
556554
@Execute
555+
@Deprecated(forRemoval = true)
557556
public void stepRemoteConnection(final RequestMonitor rm) {
558-
if (fGDBBackend.getSessionType() == SessionType.REMOTE && fGDBBackend.getIsAttachSession()) {
559-
boolean isTcpConnection = CDebugUtils.getAttribute(fAttributes,
560-
IGDBLaunchConfigurationConstants.ATTR_REMOTE_TCP, false);
561-
562-
if (isTcpConnection) {
563-
String remoteTcpHost = CDebugUtils.getAttribute(fAttributes, IGDBLaunchConfigurationConstants.ATTR_HOST,
564-
INVALID);
565-
String remoteTcpPort = CDebugUtils.getAttribute(fAttributes, IGDBLaunchConfigurationConstants.ATTR_PORT,
566-
INVALID);
567-
568-
fCommandControl.queueCommand(fCommandFactory.createMITargetSelect(fCommandControl.getContext(),
569-
remoteTcpHost, remoteTcpPort, true), new ImmediateDataRequestMonitor<MIInfo>(rm));
570-
} else {
571-
String serialDevice = CDebugUtils.getAttribute(fAttributes, IGDBLaunchConfigurationConstants.ATTR_DEV,
572-
INVALID);
573-
574-
fCommandControl.queueCommand(
575-
fCommandFactory.createMITargetSelect(fCommandControl.getContext(), serialDevice, true),
576-
new ImmediateDataRequestMonitor<MIInfo>(rm));
577-
}
578-
} else {
579-
rm.done();
580-
}
557+
rm.done();
581558
}
582559

583560
/**
@@ -588,19 +565,9 @@ public void stepRemoteConnection(final RequestMonitor rm) {
588565
@Execute
589566
public void stepNewProcess(final RequestMonitor rm) {
590567
if (!fGDBBackend.getIsAttachSession()) {
591-
boolean noBinarySpecified = CDebugUtils.getAttribute(fAttributes,
592-
IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_USE_SOLIB_SYMBOLS_FOR_APP,
593-
IGDBLaunchConfigurationConstants.DEBUGGER_USE_SOLIB_SYMBOLS_FOR_APP_DEFAULT);
594-
595-
String binary = null;
596-
final IPath execPath = fGDBBackend.getProgramPath();
597-
if (!noBinarySpecified && execPath != null && !execPath.isEmpty()) {
598-
binary = execPath.toString();
599-
}
600-
601568
// Even if binary is null, we must call this to do all the other steps
602569
// necessary to create a process. It is possible that the binary is not needed
603-
fProcService.debugNewProcess(fCommandControl.getContext(), binary, fAttributes,
570+
fProcService.debugNewProcess(fCommandControl.getContext(), getBinary(), fAttributes,
604571
new DataRequestMonitor<IDMContext>(getExecutor(), rm) {
605572
@Override
606573
protected void handleCancel() {
@@ -618,14 +585,28 @@ protected void handleCancel() {
618585
}
619586

620587
/**
621-
* If we are dealing with an local attach session, perform the attach.
622-
* For a remote attach session, we don't attach during the launch; instead
623-
* we wait for the user to manually do the attach.
588+
* @since 7.1
589+
*/
590+
protected String getBinary() {
591+
boolean noBinarySpecified = CDebugUtils.getAttribute(fAttributes,
592+
IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_USE_SOLIB_SYMBOLS_FOR_APP,
593+
IGDBLaunchConfigurationConstants.DEBUGGER_USE_SOLIB_SYMBOLS_FOR_APP_DEFAULT);
594+
595+
String binary = null;
596+
final IPath execPath = fGDBBackend.getProgramPath();
597+
if (!noBinarySpecified && execPath != null && !execPath.isEmpty()) {
598+
binary = execPath.toString();
599+
}
600+
return binary;
601+
}
602+
603+
/**
604+
* If we are dealing with an attach session, perform the attach.
624605
* @since 4.0
625606
*/
626607
@Execute
627608
public void stepAttachToProcess(final RequestMonitor requestMonitor) {
628-
if (fGDBBackend.getIsAttachSession() && fGDBBackend.getSessionType() != SessionType.REMOTE) {
609+
if (fGDBBackend.getIsAttachSession()) {
629610
// Is the process id already stored in the launch?
630611
int pid = CDebugUtils.getAttribute(fAttributes, ICDTLaunchConfigurationConstants.ATTR_ATTACH_PROCESS_ID,
631612
-1);
@@ -634,6 +615,10 @@ public void stepAttachToProcess(final RequestMonitor requestMonitor) {
634615
fProcService.attachDebuggerToProcess(
635616
fProcService.createProcessContext(fCommandControl.getContext(), Integer.toString(pid)),
636617
new DataRequestMonitor<IDMContext>(getExecutor(), requestMonitor));
618+
} else if (fGDBBackend.getSessionType() == SessionType.REMOTE) {
619+
fProcService.attachDebuggerToProcess(
620+
fProcService.createProcessContext(fCommandControl.getContext(), MIProcesses.UNKNOWN_PROCESS_ID),
621+
getBinary(), new DataRequestMonitor<IDMContext>(getExecutor(), requestMonitor));
637622
} else {
638623
IConnectHandler connectCommand = (IConnectHandler) fSession.getModelAdapter(IConnectHandler.class);
639624
if (connectCommand instanceof IConnect) {
@@ -647,6 +632,19 @@ public void stepAttachToProcess(final RequestMonitor requestMonitor) {
647632
}
648633
}
649634

635+
/**
636+
* If we are dealing with an remote attach session, perform the attach to debugger.
637+
* Bug 528145
638+
* @since 6.6
639+
*
640+
* this is no more added in execution steps
641+
*/
642+
@Execute
643+
@Deprecated(forRemoval = true)
644+
public void stepAttachRemoteToDebugger(final RequestMonitor requestMonitor) {
645+
requestMonitor.done();
646+
}
647+
650648
/**
651649
* Indicate that the Data Model has been filled. This will trigger the Debug view to expand.
652650
* @since 4.0

dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_0.java

+65-7
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.eclipse.cdt.core.CCorePlugin;
4040
import org.eclipse.cdt.core.IProcessInfo;
4141
import org.eclipse.cdt.core.IProcessList;
42+
import org.eclipse.cdt.debug.core.CDebugUtils;
4243
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
4344
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
4445
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
@@ -75,6 +76,7 @@
7576
import org.eclipse.cdt.dsf.gdb.IGdbDebugConstants;
7677
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
7778
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
79+
import org.eclipse.cdt.dsf.gdb.launching.GDBRemoteTCPLaunchTargetProvider;
7880
import org.eclipse.cdt.dsf.gdb.launching.InferiorRuntimeProcess;
7981
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
8082
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
@@ -113,6 +115,8 @@
113115
import org.eclipse.debug.core.DebugPlugin;
114116
import org.eclipse.debug.core.ILaunch;
115117
import org.eclipse.debug.core.model.IProcess;
118+
import org.eclipse.launchbar.core.target.ILaunchTarget;
119+
import org.eclipse.launchbar.core.target.launch.ITargetedLaunch;
116120
import org.osgi.framework.BundleContext;
117121

118122
/**
@@ -126,6 +130,7 @@ public class GDBProcesses_7_0 extends AbstractDsfService implements IGDBProcesse
126130
* Each one is shown in the debug view.
127131
*/
128132
private final static int MAX_NUMBER_EXITED_PROCESS = 5;
133+
private final static String INVALID = "invalid"; //$NON-NLS-1$
129134

130135
// Below is the context hierarchy that is implemented between the
131136
// MIProcesses service and the MIRunControl service for the MI
@@ -1216,13 +1221,6 @@ public void attachDebuggerToProcess(final IProcessDMContext procCtx, final Strin
12161221
new Step() {
12171222
@Override
12181223
public void execute(RequestMonitor rm) {
1219-
1220-
if (isInitialProcess()) {
1221-
// To be proper, set the initialProcess variable to false
1222-
// it may be necessary for a class that extends this class
1223-
setIsInitialProcess(false);
1224-
}
1225-
12261224
// There is no groupId until we attach, so we can use the default groupId
12271225
fContainerDmc = createContainerContext(procCtx, MIProcesses.UNIQUE_GROUP_ID);
12281226

@@ -1240,6 +1238,10 @@ public void execute(RequestMonitor rm) {
12401238
new Step() {
12411239
@Override
12421240
public void execute(RequestMonitor rm) {
1241+
if (fBackend.getSessionType() == SessionType.REMOTE && isInitialProcess()) {
1242+
connectToTarget(procCtx, rm);
1243+
return;
1244+
}
12431245
// For non-stop mode, we do a non-interrupting attach
12441246
// Bug 333284
12451247
boolean shouldInterrupt = true;
@@ -1262,6 +1264,7 @@ public void execute(RequestMonitor rm) {
12621264

12631265
// Store the fully formed container context so it can be returned to the caller.
12641266
dataRm.setData(fContainerDmc);
1267+
setIsInitialProcess(false);
12651268

12661269
// Initialize memory data for this process.
12671270
IGDBMemory memory = getServicesTracker().getService(IGDBMemory.class);
@@ -1302,6 +1305,61 @@ public Step[] getSteps() {
13021305
}
13031306
}
13041307

1308+
/**
1309+
* @since 7.1
1310+
*/
1311+
protected void connectToTarget(IProcessDMContext procCtx, RequestMonitor rm) {
1312+
ILaunch launch = procCtx.getAdapter(ILaunch.class);
1313+
assert launch != null;
1314+
if (launch != null) {
1315+
Map<String, Object> attributes = new HashMap<>();
1316+
try {
1317+
attributes.putAll(launch.getLaunchConfiguration().getAttributes());
1318+
} catch (CoreException e) {
1319+
rm.done(e.getStatus());
1320+
return;
1321+
}
1322+
1323+
if (launch instanceof ITargetedLaunch) {
1324+
ILaunchTarget target = ((ITargetedLaunch) launch).getLaunchTarget();
1325+
if (target != null) {
1326+
attributes.putAll(target.getAttributes());
1327+
String tcp = target.getAttribute(IGDBLaunchConfigurationConstants.ATTR_REMOTE_TCP, ""); //$NON-NLS-1$
1328+
if (!tcp.isEmpty()) {
1329+
attributes.put(IGDBLaunchConfigurationConstants.ATTR_REMOTE_TCP, Boolean.parseBoolean(tcp));
1330+
} else {
1331+
attributes.put(IGDBLaunchConfigurationConstants.ATTR_REMOTE_TCP,
1332+
target.getTypeId().equals(GDBRemoteTCPLaunchTargetProvider.TYPE_ID));
1333+
}
1334+
}
1335+
}
1336+
1337+
boolean isTcpConnection = CDebugUtils.getAttribute(attributes,
1338+
IGDBLaunchConfigurationConstants.ATTR_REMOTE_TCP, false);
1339+
1340+
if (isTcpConnection) {
1341+
String remoteTcpHost = CDebugUtils.getAttribute(attributes, IGDBLaunchConfigurationConstants.ATTR_HOST,
1342+
INVALID);
1343+
String remoteTcpPort = CDebugUtils.getAttribute(attributes, IGDBLaunchConfigurationConstants.ATTR_PORT,
1344+
INVALID);
1345+
1346+
fCommandControl.queueCommand(fCommandFactory.createMITargetSelect(fCommandControl.getContext(),
1347+
remoteTcpHost, remoteTcpPort, true), new ImmediateDataRequestMonitor<MIInfo>(rm));
1348+
} else {
1349+
String serialDevice = CDebugUtils.getAttribute(attributes, IGDBLaunchConfigurationConstants.ATTR_DEV,
1350+
INVALID);
1351+
1352+
fCommandControl.queueCommand(
1353+
fCommandFactory.createMITargetSelect(fCommandControl.getContext(), serialDevice, true),
1354+
new ImmediateDataRequestMonitor<MIInfo>(rm));
1355+
}
1356+
} else {
1357+
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Cannot reconnect to target.", //$NON-NLS-1$
1358+
null));
1359+
rm.done();
1360+
}
1361+
}
1362+
13051363
/** @since 5.0 */
13061364
protected void doReverseDebugStep(final IProcessDMContext procCtx, RequestMonitor rm) {
13071365
// Turn on reverse debugging if it was enabled as a launch option

0 commit comments

Comments
 (0)