From 4a1aa3517c68f5718b642c0f3362a8f7cc035f22 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Sat, 2 Apr 2011 01:50:49 +0000 Subject: [PATCH] Bug 336890: Allow IBreakpointTargetDMContext to be matched even if the processId is missing. --- .../cdt/dsf/gdb/launching/GdbLaunch.java | 2 +- .../cdt/dsf/gdb/service/GDBProcesses.java | 2 +- .../cdt/dsf/gdb/service/GDBProcesses_7_0.java | 42 +++++++++++++++++-- .../cdt/dsf/gdb/service/GDBProcesses_7_2.java | 12 ++++++ .../cdt/dsf/mi/service/MIProcesses.java | 35 ++++++++++++++-- 5 files changed, 84 insertions(+), 9 deletions(-) diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java index 91f2f88ee1e..50cc957fdfa 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java @@ -135,7 +135,7 @@ public class GdbLaunch extends DsfLaunch GdbLaunchDelegate.GDB_DEBUG_MODEL_ID, getLaunchConfiguration(), fSession); fSession.registerModelAdapter(IMemoryBlockRetrieval.class, fMemRetrieval); - IProcessDMContext procDmc = procService.createProcessContext(commandControl.getContext(), MIProcesses.UNIQUE_GROUP_ID); + IProcessDMContext procDmc = procService.createProcessContext(commandControl.getContext(), MIProcesses.UNKNOWN_PROCESS_ID); IMemoryDMContext memoryDmc = (IMemoryDMContext)procService.createContainerContext(procDmc, MIProcesses.UNIQUE_GROUP_ID); fMemRetrieval.initialize(memoryDmc); } 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 3d9a3398348..1b2eb78c50d 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 @@ -164,7 +164,7 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses { if (fProcId != null) { processDmc = createProcessContext(controlDmc, fProcId); } else { - processDmc = createProcessContext(controlDmc, groupId); + processDmc = createProcessContext(controlDmc, MIProcesses.UNKNOWN_PROCESS_ID); } return createContainerContext(processDmc, groupId); } 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 ce023a16713..0e57d1d2348 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 @@ -301,12 +301,37 @@ public class GDBProcesses_7_0 extends AbstractDsfService @Override public boolean equals(Object obj) { - return baseEquals(obj) && - (((MIProcessDMC)obj).fId == null ? fId == null : ((MIProcessDMC)obj).fId.equals(fId)); + // We treat the UNKNOWN_PROCESS_ID as a wildcard. Any processId (except null) will be considered + // equal to the UNKNOWN_PROCESS_ID. This is important because before starting a process, we don't + // have a pid yet, but we still need to create a process context, and we must use UNKNOWN_PROCESS_ID. + // Bug 336890 + + if (!baseEquals(obj)) { + return false; + } + + MIProcessDMC other = (MIProcessDMC)obj; + if (fId == null || other.fId == null) { + return fId == null && other.fId == null; + } + + // Now that we know neither is null, check for UNKNOWN_PROCESS_ID wildcard + if (fId.equals(MIProcesses.UNKNOWN_PROCESS_ID) || other.fId.equals(MIProcesses.UNKNOWN_PROCESS_ID)) { + return true; + } + + return fId.equals(other.fId); } @Override - public int hashCode() { return baseHashCode() ^ (fId == null ? 0 : fId.hashCode()); } + public int hashCode() { + // We cannot use fId in the hashCode. This is because we support + // the wildCard MIProcesses.UNKNOWN_PROCESS_ID which is equal to any other fId. + // But we also need the hashCode of the wildCard to be the same + // as the one of all other fIds, which is why we need a constant hashCode + // See bug 336890 + return baseHashCode(); + } } /** @@ -549,6 +574,16 @@ public class GDBProcesses_7_0 extends AbstractDsfService return fGroupToPidMap; } + /** @since 4.0 */ + protected int getNumConnected() { + return fNumConnected; + } + + /** @since 4.0 */ + protected void setNumConnected(int num) { + fNumConnected = num; + } + /** @since 4.0 */ protected boolean isInitialProcess() { return fInitialProcess; @@ -631,6 +666,7 @@ public class GDBProcesses_7_0 extends AbstractDsfService String pid = getGroupToPidMap().get(groupId); if (pid == null) { + // For GDB 7.0 and 7.1, the groupId is the pid, so we can use it directly pid = groupId; } IProcessDMContext processDmc = createProcessContext(controlDmc, pid); 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 cb104a5e884..93925c97d8b 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 @@ -28,6 +28,7 @@ import org.eclipse.cdt.dsf.mi.service.IMICommandControl; import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext; import org.eclipse.cdt.dsf.mi.service.IMIProcessDMContext; import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager; +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.MIAddInferiorInfo; import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; @@ -83,6 +84,17 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 { super.shutdown(requestMonitor); } + @Override + public IMIContainerDMContext createContainerContextFromGroupId(ICommandControlDMContext controlDmc, String groupId) { + String pid = getGroupToPidMap().get(groupId); + if (pid == null) { + // For GDB 7.2, the groupId is no longer the pid, so use our wildcard pid instead + pid = MIProcesses.UNKNOWN_PROCESS_ID; + } + IProcessDMContext processDmc = createProcessContext(controlDmc, pid); + return createContainerContext(processDmc, groupId); + } + @Override protected boolean doIsDebuggerAttachSupported() { // Multi-process is not applicable to post-mortem sessions (core) diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIProcesses.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIProcesses.java index 76dbc25e7cc..3262a6967da 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIProcesses.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIProcesses.java @@ -255,12 +255,37 @@ public class MIProcesses extends AbstractDsfService implements IMIProcesses, ICa @Override public boolean equals(Object obj) { - return super.baseEquals(obj) && - (((MIProcessDMC)obj).fId == null ? fId == null : ((MIProcessDMC)obj).fId.equals(fId)); + // We treat the UNKNOWN_PROCESS_ID as a wildcard. Any processId (except null) will be considered + // equal to the UNKNOWN_PROCESS_ID. This is important because before starting a process, we don't + // have a pid yet, but we still need to create a process context, and we must use UNKNOWN_PROCESS_ID. + // Bug 336890 + + if (!baseEquals(obj)) { + return false; + } + + MIProcessDMC other = (MIProcessDMC)obj; + if (fId == null || other.fId == null) { + return fId == null && other.fId == null; + } + + // Now that we know neither is null, check for UNKNOWN_PROCESS_ID wildcard + if (fId.equals(UNKNOWN_PROCESS_ID) || other.fId.equals(UNKNOWN_PROCESS_ID)) { + return true; + } + + return fId.equals(other.fId); } @Override - public int hashCode() { return super.baseHashCode() ^ (fId == null ? 0 : fId.hashCode()); } + public int hashCode() { + // We cannot use fId in the hashCode. This is because we support + // the wildCard MIProcesses.UNKNOWN_PROCESS_ID which is equal to any other fId. + // But we also need the hashCode of the wildCard to be the same + // as the one of all other fIds, which is why we need a constant hashCode + // See bug 336890 + return baseHashCode(); + } } /* @@ -315,6 +340,8 @@ public class MIProcesses extends AbstractDsfService implements IMIProcesses, ICa private static final String FAKE_THREAD_ID = "0"; //$NON-NLS-1$ // The unique id should be an empty string so that the views know not to display the fake id public static final String UNIQUE_GROUP_ID = ""; //$NON-NLS-1$ + /** @since 4.0 */ + public static final String UNKNOWN_PROCESS_ID = UNIQUE_GROUP_ID; public MIProcesses(DsfSession session) { super(session); @@ -420,7 +447,7 @@ public class MIProcesses extends AbstractDsfService implements IMIProcesses, ICa /** @since 4.0 */ public IMIContainerDMContext createContainerContextFromGroupId(ICommandControlDMContext controlDmc, String groupId) { - IProcessDMContext processDmc = createProcessContext(controlDmc, groupId); + IProcessDMContext processDmc = createProcessContext(controlDmc, UNKNOWN_PROCESS_ID); return createContainerContext(processDmc, groupId); }