diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence.java index 0b9649cd8f7..4552d5ed61f 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence.java @@ -19,6 +19,7 @@ * Anton Gorenkov - A preference to use RTTI for variable types determination (Bug 377536) * Xavier Raynaud (Kalray) - Avoid duplicating fields in sub-classes (add protected accessors) * Marc Khouzam (Ericsson) - Output the version of GDB at startup (Bug 455408) + * Jonathan Tousignant (NordiaSoft) - Remote session breakpoint (Bug 528145) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.launching; @@ -38,6 +39,7 @@ import org.eclipse.cdt.dsf.concurrent.RequestMonitor; import org.eclipse.cdt.dsf.concurrent.RequestMonitorWithProgress; import org.eclipse.cdt.dsf.datamodel.DataModelInitializedEvent; import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext; import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext; import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants; @@ -50,6 +52,7 @@ import org.eclipse.cdt.dsf.gdb.service.SessionType; import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl; import org.eclipse.cdt.dsf.mi.service.CSourceLookup; import org.eclipse.cdt.dsf.mi.service.IMIProcesses; +import org.eclipse.cdt.dsf.mi.service.MIProcesses; import org.eclipse.cdt.dsf.mi.service.command.CommandFactory; import org.eclipse.cdt.dsf.mi.service.command.output.MIGDBVersionInfo; import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; @@ -139,6 +142,8 @@ public class FinalLaunchSequence extends ReflectionSequence { "stepNewProcess", //$NON-NLS-1$ // For local attach launch only "stepAttachToProcess", //$NON-NLS-1$ + // For remote attach launch only + "stepAttachRemoteToDebugger", //$NON-NLS-1$ // Global "stepDataModelInitializationComplete", //$NON-NLS-1$ "stepCleanup", //$NON-NLS-1$ @@ -647,6 +652,23 @@ public class FinalLaunchSequence extends ReflectionSequence { } } + /** + * If we are dealing with an remote attach session, perform the attach to debugger. + * Bug 528145 + * @since 6.5 + */ + @Execute + public void stepAttachRemoteToDebugger(final RequestMonitor requestMonitor) { + if (fGDBBackend.getIsAttachSession() && fGDBBackend.getSessionType() == SessionType.REMOTE) { + IProcessDMContext processContext = fProcService.createProcessContext(fCommandControl.getContext(), + MIProcesses.UNKNOWN_PROCESS_ID); + fProcService.attachDebuggerToProcess(processContext, + new DataRequestMonitor(getExecutor(), requestMonitor)); + } else { + requestMonitor.done(); + } + } + /** * Indicate that the Data Model has been filled. This will trigger the Debug view to expand. * @since 4.0 diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_2.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_2.java index eed8286d8e0..b3c471c04c4 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_2.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_2.java @@ -13,6 +13,7 @@ * Marc Khouzam (Ericsson) - Workaround for Bug 352998 * Marc Khouzam (Ericsson) - Update breakpoint handling for GDB >= 7.4 (Bug 389945) * Alvaro Sanchez-Leon (Ericsson) - Breakpoint Enable does not work after restarting the application (Bug 456959) + * Jonathan Tousignant (NordiaSoft) - Remote session breakpoint (Bug 528145) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.service; @@ -265,13 +266,15 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 implements IMultiTerminat @Override protected boolean doIsDebuggerAttachSupported() { + SessionType sessionType = fBackend.getSessionType(); + // Multi-process is not applicable to post-mortem sessions (core) // or to non-attach remote sessions. - if (fBackend.getSessionType() == SessionType.CORE) { + if (sessionType == SessionType.CORE) { return false; } - if (fBackend.getSessionType() == SessionType.REMOTE && !fBackend.getIsAttachSession()) { + if (sessionType == SessionType.REMOTE && !fBackend.getIsAttachSession()) { return false; } @@ -279,9 +282,22 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 implements IMultiTerminat IMIRunControl runControl = getServicesTracker().getService(IMIRunControl.class); if (runControl != null && runControl.getRunMode() == MIRunMode.ALL_STOP) { // Only one process is allowed in all-stop (for now) - return getNumConnected() == 0; // NOTE: when we support multi-process in all-stop mode, // we will need to interrupt the target to when doing the attach. + int numConnected = getNumConnected(); + switch (sessionType) { + case REMOTE: + // In remote session already one process is connected + // Bug 528145 + return numConnected == 1; + case LOCAL: + return numConnected == 0; + + default: + break; + } + + return false; } return true; @@ -315,32 +331,40 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 implements IMultiTerminat new Step() { @Override public void execute(final RequestMonitor rm) { - getProcessesBeingDebugged(procCtx, new ImmediateDataRequestMonitor(rm) { - @Override - protected void handleSuccess() { - assert getData() != null; + // The remote session is already connected to the process + // Bug 528145 + if (fBackend.getSessionType() == SessionType.REMOTE) { + rm.done(); + } else { + getProcessesBeingDebugged(procCtx, + new ImmediateDataRequestMonitor(rm) { + @Override + protected void handleSuccess() { + assert getData() != null; - boolean found = false; - for (IDMContext dmc : getData()) { - IProcessDMContext procDmc = DMContexts.getAncestorOfType(dmc, - IProcessDMContext.class); - if (procCtx.equals(procDmc)) { - found = true; - } - } - if (found) { - // abort the sequence - Status failedStatus = new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, - REQUEST_FAILED, - MessageFormat.format(Messages.Already_connected_process_err, - ((IMIProcessDMContext) procCtx).getProcId()), - null); - rm.done(failedStatus); - return; - } - super.handleSuccess(); - } - }); + boolean found = false; + for (IDMContext dmc : getData()) { + IProcessDMContext procDmc = DMContexts.getAncestorOfType(dmc, + IProcessDMContext.class); + if (procCtx.equals(procDmc)) { + found = true; + } + } + if (found) { + // abort the sequence + Status failedStatus = new Status(IStatus.ERROR, + GdbPlugin.PLUGIN_ID, REQUEST_FAILED, + MessageFormat.format( + Messages.Already_connected_process_err, + ((IMIProcessDMContext) procCtx).getProcId()), + null); + rm.done(failedStatus); + return; + } + super.handleSuccess(); + } + }); + } } }, @@ -451,19 +475,26 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 implements IMultiTerminat new Step() { @Override public void execute(RequestMonitor rm) { - // For non-stop mode, we do a non-interrupting attach - // Bug 333284 - boolean shouldInterrupt = true; - IMIRunControl runControl = getServicesTracker().getService(IMIRunControl.class); - if (runControl != null && runControl.getRunMode() == MIRunMode.NON_STOP) { - shouldInterrupt = false; - } + // This call end the current attach to the gdbserver in remote session + // Bug 528145 + if (fBackend.getSessionType() == SessionType.REMOTE) { + rm.done(); + } else { + // For non-stop mode, we do a non-interrupting attach + // Bug 333284 + boolean shouldInterrupt = true; + IMIRunControl runControl = getServicesTracker().getService(IMIRunControl.class); + if (runControl != null && runControl.getRunMode() == MIRunMode.NON_STOP) { + shouldInterrupt = false; + } - boolean extraNewline = targetAttachRequiresTrailingNewline(); - ICommand miTargetAttach = fCommandFactory.createMITargetAttach(fContainerDmc, - ((IMIProcessDMContext) procCtx).getProcId(), shouldInterrupt, extraNewline); - fCommandControl.queueCommand(miTargetAttach, - new ImmediateDataRequestMonitor(rm)); + boolean extraNewline = targetAttachRequiresTrailingNewline(); + ICommand miTargetAttach = fCommandFactory.createMITargetAttach( + fContainerDmc, ((IMIProcessDMContext) procCtx).getProcId(), shouldInterrupt, + extraNewline); + fCommandControl.queueCommand(miTargetAttach, + new ImmediateDataRequestMonitor(rm)); + } } },