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 1a33469dc30..8317be114bf 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2013 Ericsson and others. + * Copyright (c) 2008, 2014 Ericsson and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -11,6 +11,8 @@ * John Dallaway - GDB 7.x MI thread details field ignored (Bug 325556) * Marc Khouzam (Ericsson) - Make each thread an IDisassemblyDMContext (bug 352748) * Andy Jin (QNX) - Not output thread osId as a string when it is null (Bug 397039) + * Marc Khouzam (Ericsson) - Move IBreakpointsTargetDMContext from MIContainerDMC + * to GDBContainerDMC to ease inheritance (Bug 389945) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.service; @@ -183,8 +185,8 @@ public class GDBProcesses_7_0 extends AbstractDsfService * Context representing a thread group of GDB/MI. */ @Immutable - private static class MIContainerDMC extends AbstractDMContext - implements IMIContainerDMContext, IBreakpointsTargetDMContext, IDisassemblyDMContext + static class MIContainerDMC extends AbstractDMContext + implements IMIContainerDMContext, IDisassemblyDMContext { /** * String ID that is used to identify the thread group in the GDB/MI protocol. @@ -225,7 +227,7 @@ public class GDBProcesses_7_0 extends AbstractDsfService } private static class GDBContainerDMC extends MIContainerDMC - implements IMemoryDMContext + implements IMemoryDMContext, IBreakpointsTargetDMContext { public GDBContainerDMC(String sessionId, IProcessDMContext processDmc, String groupId) { super(sessionId, processDmc, groupId); 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 2816ef6153d..99f2b02c162 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, 2013 TUBITAK BILGEM-ITI and others. + * Copyright (c) 2010, 2014 TUBITAK BILGEM-ITI and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * Onur Akdemir (TUBITAK BILGEM-ITI) - Multi-process debugging (Bug 237306) * Marc Khouzam (Ericsson) - Workaround for Bug 352998 + * Marc Khouzam (Ericsson) - Update breakpoint handling for GDB >= 7.4 (Bug 389945) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.service; @@ -558,11 +559,14 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 { @Override public void eventDispatched(IExitedDMEvent e) { IDMContext dmc = e.getDMContext(); - if (dmc instanceof IContainerDMContext) { + if (dmc instanceof IBreakpointsTargetDMContext) { // A process has died, we should stop tracking its breakpoints, but only if it is not restarting + // We only do this when the process is a breakpointTargetDMC itself (GDB < 7.4); + // we don't want to stop tracking breakpoints when breakpoints are only set once + // for all processes (GDB >= 7.4) if (!fProcRestarting.remove(dmc)) { if (fBackend.getSessionType() != SessionType.CORE) { - IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(dmc, IBreakpointsTargetDMContext.class); + IBreakpointsTargetDMContext bpTargetDmc = (IBreakpointsTargetDMContext)dmc; MIBreakpointsManager bpmService = getServicesTracker().getService(MIBreakpointsManager.class); if (bpmService != null) { bpmService.stopTrackingBreakpoints(bpTargetDmc, new ImmediateRequestMonitor() { diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_4.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_4.java new file mode 100644 index 00000000000..4d149ac89e3 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_4.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc Khouzam (Ericsson) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.service; + +import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext; +import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext; +import org.eclipse.cdt.dsf.service.DsfSession; + +/** + * Adapt to GDB 7.4 where breakpoints are for all inferiors at once. + * + * @since 4.4 + */ +public class GDBProcesses_7_4 extends GDBProcesses_7_2_1 { + + public GDBProcesses_7_4(DsfSession session) { + super(session); + } + + /** + * A container context that is not an IBreakpointsTargetDMContext. + */ + private static class GDBContainerDMC_7_4 extends MIContainerDMC + implements IMemoryDMContext + { + public GDBContainerDMC_7_4(String sessionId, IProcessDMContext processDmc, String groupId) { + super(sessionId, processDmc, groupId); + } + } + + @Override + public IMIContainerDMContext createContainerContext(IProcessDMContext processDmc, + String groupId) { + return new GDBContainerDMC_7_4(getSession().getId(), processDmc, groupId); + } + + +} + diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java index 303eb3fa4b2..1b362cf7013 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java @@ -15,6 +15,7 @@ * Marc Khouzam (Ericsson) - Support for GDB 7.6 memory service * Marc Khouzam (Ericsson) - Support for GDB 7.4 trace control service * William Riley (Renesas) - Support for GDB 7.3 disassembly service (Bug 357270) + * Marc Khouzam (Ericsson) - Support for GDB 7.4 processes service (Bug 389945) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.service; @@ -200,6 +201,9 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory { @Override protected IProcesses createProcessesService(DsfSession session) { + if (GDB_7_4_VERSION.compareTo(fVersion) <= 0) { + return new GDBProcesses_7_4(session); + } if (GDB_7_2_1_VERSION.compareTo(fVersion) <= 0) { return new GDBProcesses_7_2_1(session); } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl.java index f658639e69f..1e0607dd39b 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl.java @@ -16,6 +16,7 @@ * Mikhail Khodjaiants (Mentor Graphics) - Terminate should cancel the initialization sequence * if it is still running (bug 373845) * Marc Khouzam (Ericsson) - Terminate the session if we lose the connection to the remote target (bug 422586) + * Marc Khouzam (Ericsson) - Allow to override the creation of the ControlDMC (Bug 389945) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.service.command; @@ -185,7 +186,7 @@ public class GDBControl extends AbstractMIControl implements IGDBControl { } } - private GDBControlDMContext fControlDmc; + private ICommandControlDMContext fControlDmc; private IGDBBackend fMIBackend; @@ -250,9 +251,9 @@ public class GDBControl extends AbstractMIControl implements IGDBControl { fMIBackend = getServicesTracker().getService(IGDBBackend.class); - // getId uses the MIBackend service, which is why we must wait until we - // have it, before we can create this context. - fControlDmc = new GDBControlDMContext(getSession().getId(), getId()); + // getId, called to create this context, uses the MIBackend service, + // which is why we must wait until we have MIBackend, before we can create the below context. + fControlDmc = createComandControlContext(); getExecutor().execute(getStartupSequence(requestMonitor)); } @@ -273,9 +274,23 @@ public class GDBControl extends AbstractMIControl implements IGDBControl { return fMIBackend.getId(); } + /** + * Create the commandControl context. + * This method can be overridden to provide a different context. + * @since 4.4 + */ + protected ICommandControlDMContext createComandControlContext() { + return new GDBControlDMContext(getSession().getId(), getId()); + } + + @Deprecated @Override public MIControlDMContext getControlDMContext() { - return fControlDmc; + assert fControlDmc instanceof MIControlDMContext; + if (fControlDmc instanceof MIControlDMContext) { + return (MIControlDMContext)fControlDmc; + } + return null; } @Override @@ -325,7 +340,7 @@ public class GDBControl extends AbstractMIControl implements IGDBControl { getGDBExitWaitTime(), TimeUnit.SECONDS); queueCommand( - getCommandFactory().createMIGDBExit(fControlDmc), + getCommandFactory().createMIGDBExit(getContext()), new DataRequestMonitor(getExecutor(), rm) { @Override public void handleCompleted() { @@ -437,7 +452,7 @@ public class GDBControl extends AbstractMIControl implements IGDBControl { // Before GDB 7.0, we have to send the containerExited event ourselves IGDBProcesses procService = getServicesTracker().getService(IGDBProcesses.class); if (procService != null) { - IContainerDMContext processContainerDmc = procService.createContainerContextFromGroupId(fControlDmc, MIProcesses.UNIQUE_GROUP_ID); + IContainerDMContext processContainerDmc = procService.createContainerContextFromGroupId(getContext(), MIProcesses.UNIQUE_GROUP_ID); getSession().dispatchEvent( new ContainerExitedDMEvent(processContainerDmc), getProperties()); } @@ -447,7 +462,7 @@ public class GDBControl extends AbstractMIControl implements IGDBControl { public void eventDispatched(BackendStateChangedEvent e) { if (e.getState() == IMIBackend.State.TERMINATED && e.getBackendId().equals(fMIBackend.getId())) { // Handle "GDB Exited" event, just relay to following event. - getSession().dispatchEvent(new GDBControlShutdownDMEvent(fControlDmc), getProperties()); + getSession().dispatchEvent(new GDBControlShutdownDMEvent(getContext()), getProperties()); } } @@ -518,8 +533,8 @@ public class GDBControl extends AbstractMIControl implements IGDBControl { return; } - fCLICommandProcessor = createCLIEventProcessor(GDBControl.this, fControlDmc); - fMIEventProcessor = createMIRunControlEventProcessor(GDBControl.this, fControlDmc); + fCLICommandProcessor = createCLIEventProcessor(GDBControl.this, getContext()); + fMIEventProcessor = createMIRunControlEventProcessor(GDBControl.this, getContext()); fControlEventProcessor = createControlEventProcessor(); requestMonitor.done(); @@ -575,7 +590,7 @@ public class GDBControl extends AbstractMIControl implements IGDBControl { AbstractMIControl.class.getName(), IGDBControl.class.getName() }, new Hashtable()); - getSession().dispatchEvent(new GDBControlInitializedDMEvent(fControlDmc), getProperties()); + getSession().dispatchEvent(new GDBControlInitializedDMEvent(getContext()), getProperties()); requestMonitor.done(); } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_0.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_0.java index 55f4aa15860..d85cbc75bab 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_0.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_0.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2012 Wind River Systems and others. + * Copyright (c) 2006, 2014 Wind River Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -183,7 +183,7 @@ public class GDBControl_7_0 extends GDBControl { private void listFeatures(final RequestMonitor requestMonitor) { queueCommand( - getCommandFactory().createMIListFeatures(getControlDMContext()), + getCommandFactory().createMIListFeatures(getContext()), new DataRequestMonitor(getExecutor(), requestMonitor) { @Override public void handleSuccess() { @@ -235,7 +235,7 @@ public class GDBControl_7_0 extends GDBControl { @Override public void enablePrettyPrintingForMIVariableObjects(RequestMonitor rm) { queueCommand( - getCommandFactory().createMIEnablePrettyPrinting(getControlDMContext()), + getCommandFactory().createMIEnablePrettyPrinting(getContext()), new DataRequestMonitor(getExecutor(), rm)); } @@ -248,7 +248,7 @@ public class GDBControl_7_0 extends GDBControl { String subCommand = "set python print-stack " + (enabled ? "on" : "off"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ queueCommand( - getCommandFactory().createCLIMaintenance(getControlDMContext(), subCommand), + getCommandFactory().createCLIMaintenance(getContext(), subCommand), new DataRequestMonitor(getExecutor(), rm)); } } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_4.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_4.java index 44308952aaf..a1e94016a46 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_4.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_4.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 Ericsson and others. + * Copyright (c) 2012, 2014 Ericsson and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,11 +7,13 @@ * * Contributors: * Marc Khouzam (Ericsson) - initial API and implementation + * Marc Khouzam (Ericsson) - Update breakpoint handling for GDB >= 7.4 (Bug 389945) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.service.command; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; import org.eclipse.cdt.dsf.mi.service.command.CommandFactory; import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; import org.eclipse.cdt.dsf.service.DsfSession; @@ -20,12 +22,32 @@ import org.eclipse.debug.core.ILaunchConfiguration; /** * With GDB 7.4, the command 'maintenance set python print-stack' is not supported. * The new command "set python print-stack none|full|message" has replaced it. + * + * With GDB 7.4, breakpoints are handled globally for all of GDB, so our + * IBreakpointsTargetDMContext becomes the GDBControlContext. + * * @since 4.1 */ public class GDBControl_7_4 extends GDBControl_7_2 implements IGDBControl { + + /** + * A command control context that is also a IBreakpointsTargetDMContext + */ + private class GDBControlDMContext_7_4 extends GDBControlDMContext implements IBreakpointsTargetDMContext { + public GDBControlDMContext_7_4(String sessionId, String commandControlId) { + super(sessionId, commandControlId); + } + } + public GDBControl_7_4(DsfSession session, ILaunchConfiguration config, CommandFactory factory) { super(session, config, factory); } + + /** @since 4.4 */ + @Override + protected ICommandControlDMContext createComandControlContext() { + return new GDBControlDMContext_7_4(getSession().getId(), getId()); + } @Override public void setPrintPythonErrors(boolean enabled, RequestMonitor rm) { diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java index 5d2bfdd9498..c68701f71d5 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java @@ -13,6 +13,7 @@ * Ericsson - Added Action support * Marc Khouzam (Ericsson) - Fix support for thread filter (Bug 355833) * Marc Khouzam (Ericsson) - Generalize thread filtering logic (Bug 431986) + * Marc Khouzam (Ericsson) - Accept multiple calls to startTrackingBreakpoints (Bug 389945) *******************************************************************************/ package org.eclipse.cdt.dsf.mi.service; @@ -367,13 +368,14 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo return; } - // Make sure a mapping for this execution context does not already exist Map> platformBPs = fPlatformBPs.get(dmc); Map> breakpointIDs = fBreakpointIDs.get(dmc); Map targetIDs = fTargetBPs.get(dmc); Map> threadIDs = fBreakpointThreads.get(dmc); if ((platformBPs != null) || (breakpointIDs != null) || (targetIDs != null) || (threadIDs != null)) { - rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, CONTEXT_ALREADY_INITIALIZED, null)); + // If the maps already contains this context we can simply ignore this request. + // This happens when we start or attach to another process with GDB >= 7.4 + assert platformBPs != null && breakpointIDs != null && targetIDs != null && threadIDs != null; rm.done(); return; } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsSynchronizer.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsSynchronizer.java index 9bde163befb..c1ae7f6b003 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsSynchronizer.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsSynchronizer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 Mentor Graphics and others. + * Copyright (c) 2012, 2014 Mentor Graphics and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * Mentor Graphics - Initial API and implementation * Salvatore Culcasi (ST) - Bug 407163 - GDB Console: breakpoint not added with MinGW and gdb + * Marc Khouzam (Ericsson) - Update breakpoint handling for GDB >= 7.4 (Bug 389945) *******************************************************************************/ package org.eclipse.cdt.dsf.mi.service; @@ -294,9 +295,6 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI if (breakpointsService == null || bm == null) return; final IBreakpointsTargetDMContext bpTargetDMC = breakpointsService.getBreakpointTargetContext(id); - final IContainerDMContext contDMC = DMContexts.getAncestorOfType(bpTargetDMC, IContainerDMContext.class); - if (contDMC == null) - return; if (bpTargetDMC != null){ final MIBreakpointDMContext bpDMC = new MIBreakpointDMContext(breakpointsService, new IDMContext[] { bpTargetDMC }, id); @@ -327,6 +325,17 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI IDsfBreakpointExtension bpExtension = (IDsfBreakpointExtension)((ICBreakpoint)plBpt).getExtension( MIBreakpointsManager.GDB_DEBUG_MODEL_ID, ICBreakpointExtension.class); + + IMIProcesses processes = getServicesTracker().getService(IMIProcesses.class); + if (processes == null) { + return; + } + + IContainerDMContext contDMC = processes.createContainerContextFromThreadId(getCommandControl().getContext(), data.getThreadId()); + if (contDMC == null) { + return; + } + IExecutionDMContext[] execDMCs = bpExtension.getThreadFilters(contDMC); List list = new ArrayList(execDMCs.length); for (IExecutionDMContext c : execDMCs) { @@ -453,7 +462,12 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI MIBreakpoint miBpt) { try { - IContainerDMContext contDMC = DMContexts.getAncestorOfType(bpTargetDMC, IContainerDMContext.class); + IMIProcesses processes = getServicesTracker().getService(IMIProcesses.class); + if (processes == null) { + return; + } + String threadId = miBpt.getThreadId(); + IContainerDMContext contDMC = processes.createContainerContextFromThreadId(getCommandControl().getContext(), threadId); if (contDMC == null) { return; } @@ -462,20 +476,16 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI if (procDmc == null) { return; } - IMIProcesses processes = getServicesTracker().getService(IMIProcesses.class); - if (processes == null) { - return; - } IDsfBreakpointExtension bpExtension = (IDsfBreakpointExtension)plBpt.getExtension( MIBreakpointsManager.GDB_DEBUG_MODEL_ID, ICBreakpointExtension.class); IExecutionDMContext[] execDMCs = bpExtension.getThreadFilters(contDMC); if (execDMCs == null) { execDMCs = new IExecutionDMContext[0]; } - int threadId = Integer.parseInt(miBpt.getThreadId()); + int threadNum = Integer.parseInt(threadId); for (IExecutionDMContext execDMC : execDMCs) { if (execDMC instanceof IMIExecutionDMContext - && ((IMIExecutionDMContext)execDMC).getThreadId() == threadId) { + && ((IMIExecutionDMContext)execDMC).getThreadId() == threadNum) { // The platform breakpoint is already restricted to the given thread. return; } @@ -484,8 +494,8 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI System.arraycopy(execDMCs, 0, newExecDMCs, 0, execDMCs.length); newExecDMCs[execDMCs.length] = processes.createExecutionContext( contDMC, - processes.createThreadContext(procDmc, miBpt.getThreadId()), - miBpt.getThreadId()); + processes.createThreadContext(procDmc, threadId), + threadId); bpExtension.setThreadFilters(newExecDMCs); } catch(NumberFormatException e) { @@ -723,6 +733,9 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI if (processes == null) { return null; } + + // For GDB < 7.4, each process is its own breakpointTargetDMC so we need to find a the proper process + // based on the threadId. For GDB >= 7.4, this does not matter as we'll always end up with the global bpTargetDMC String threadId = (miBpt != null) ? miBpt.getThreadId() : null; IContainerDMContext contContext = processes.createContainerContextFromThreadId(commandControl.getContext(), threadId); if (contContext == null) { @@ -1231,10 +1244,11 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI @DsfServiceEventHandler public void eventDispatched(IExitedDMEvent e) { - if (e.getDMContext() instanceof IContainerDMContext) { - IBreakpointsTargetDMContext bpTargetDMContext = - DMContexts.getAncestorOfType(e.getDMContext(), IBreakpointsTargetDMContext.class); - if (bpTargetDMContext != null) { + if (e.getDMContext() instanceof IBreakpointsTargetDMContext) { + // Remove breakpoint entries when a breakpoint target is removed. + // This will happen for GDB < 7.4 where the container is the breakpoint target. + // For GDB >= 7.4, GDB is the breakpoint target and will not be removed. + IBreakpointsTargetDMContext bpTargetDMContext = (IBreakpointsTargetDMContext)e.getDMContext(); Map createdBreakpoints = fCreatedTargetBreakpoints.remove(bpTargetDMContext); if (createdBreakpoints != null) createdBreakpoints.clear(); @@ -1244,7 +1258,6 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI Set deletedBreakpoints = fDeletedTargetBreakpoints.remove(bpTargetDMContext); if (deletedBreakpoints != null) deletedBreakpoints.clear(); - } } }