mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 14:12:10 +02:00
Bug 435144: Fix bp for GDB 7.0 and 7.1
Change-Id: Ia84bc47ff1b5711f2e27700c5b3356b73a704256
This commit is contained in:
parent
8a349b840a
commit
9f27d7cc20
4 changed files with 286 additions and 56 deletions
|
@ -0,0 +1,134 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2015 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 java.util.Hashtable;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.debug.core.model.ICBreakpoint;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IDsfBreakpointExtension;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IRunControl.IStartedDMEvent;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager;
|
||||||
|
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
|
||||||
|
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.debug.core.DebugPlugin;
|
||||||
|
import org.eclipse.debug.core.model.IBreakpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version of BreakpointsManager for GDB version starting with 7.0.
|
||||||
|
*
|
||||||
|
* @since 4.7
|
||||||
|
*/
|
||||||
|
public class GDBBreakpointsManager_7_0 extends MIBreakpointsManager {
|
||||||
|
private String fDebugModelId;
|
||||||
|
|
||||||
|
public GDBBreakpointsManager_7_0(DsfSession session, String debugModelId) {
|
||||||
|
super(session, debugModelId);
|
||||||
|
fDebugModelId = debugModelId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(final RequestMonitor rm) {
|
||||||
|
super.initialize(new ImmediateRequestMonitor(rm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
doInitialize(rm);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doInitialize(final RequestMonitor rm) {
|
||||||
|
register(new String[] { GDBBreakpointsManager_7_0.class.getName() },
|
||||||
|
new Hashtable<String, String>());
|
||||||
|
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
@DsfServiceEventHandler
|
||||||
|
public void eventDispatched_7_0(IStartedDMEvent e) {
|
||||||
|
// With GDB 7.0 and 7.1, the pid of the process is used by GDB
|
||||||
|
// as the thread-group id. This is a problem because the pid does
|
||||||
|
// not exist when we create breakpoints.
|
||||||
|
// We are then having a problem when we try to compare a context
|
||||||
|
// where the pid was set with the ones stored in this service which
|
||||||
|
// don't have the pid.
|
||||||
|
// What we do here is update all local contexts with the newly created
|
||||||
|
// pid when we get the start event for the process.
|
||||||
|
// Note that we don't support multi-process for GDB 7.0 and 7.1, so it
|
||||||
|
// simplifies things.
|
||||||
|
updateContextOnStartEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateContextOnStartEvent(IStartedDMEvent e) {
|
||||||
|
if (e.getDMContext() instanceof IContainerDMContext) {
|
||||||
|
// Process created.
|
||||||
|
IContainerDMContext containerWithPid = (IContainerDMContext)e.getDMContext();
|
||||||
|
|
||||||
|
assert getPlatformToAttributesMaps().keySet().size() == 1; // Only one process for GDB 7.0 and 7.1
|
||||||
|
for (IBreakpointsTargetDMContext oldBpTarget : getPlatformToAttributesMaps().keySet()) {
|
||||||
|
assert oldBpTarget instanceof IContainerDMContext;
|
||||||
|
assert !containerWithPid.equals(oldBpTarget); // BpTarget does not have pid, while new container does
|
||||||
|
|
||||||
|
// Replace all BpTarget entries with the new container context containing the pid
|
||||||
|
IBreakpointsTargetDMContext newBpTarget = (IBreakpointsTargetDMContext)containerWithPid;
|
||||||
|
updateBpManagerMaps(newBpTarget, oldBpTarget);
|
||||||
|
|
||||||
|
// Replace all target filters of this session with the new container context containing the pid
|
||||||
|
updateTargetFilters(containerWithPid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates all the maps of the MIBreakpointsManager to replace the old IBreakpointsTargetDMContext which
|
||||||
|
* does not have the pid, with the new one with does have the pid.
|
||||||
|
*/
|
||||||
|
private void updateBpManagerMaps(IBreakpointsTargetDMContext newBpTarget, IBreakpointsTargetDMContext oldBpTarget) {
|
||||||
|
getPlatformToAttributesMaps().put(newBpTarget, getPlatformToAttributesMaps().remove(oldBpTarget));
|
||||||
|
getPlatformToBPsMaps().put(newBpTarget, getPlatformToBPsMaps().get(oldBpTarget));
|
||||||
|
getBPToPlatformMaps().put(newBpTarget, getBPToPlatformMaps().get(oldBpTarget));
|
||||||
|
getPlatformToBPThreadsMaps().put(newBpTarget, getPlatformToBPThreadsMaps().get(oldBpTarget));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates all the target filter for this session to replace the old IBreakpointsTargetDMContext which
|
||||||
|
* does not have the pid, with the new one with does have the pid.
|
||||||
|
*/
|
||||||
|
private void updateTargetFilters(IContainerDMContext newContainer) {
|
||||||
|
IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(fDebugModelId);
|
||||||
|
for (IBreakpoint breakpoint : breakpoints) {
|
||||||
|
if (breakpoint instanceof ICBreakpoint && supportsBreakpoint(breakpoint)) {
|
||||||
|
try {
|
||||||
|
IDsfBreakpointExtension filterExt = getFilterExtension((ICBreakpoint)breakpoint);
|
||||||
|
|
||||||
|
IContainerDMContext[] filterContainers = filterExt.getTargetFilters();
|
||||||
|
for (IContainerDMContext oldContainer : filterContainers) {
|
||||||
|
// For each target filter, replace it if it is from our session
|
||||||
|
ICommandControlDMContext controldForOld = DMContexts.getAncestorOfType(oldContainer, ICommandControlDMContext.class);
|
||||||
|
ICommandControlDMContext controlForNew = DMContexts.getAncestorOfType(newContainer, ICommandControlDMContext.class);
|
||||||
|
|
||||||
|
if (controldForOld.equals(controlForNew)) {
|
||||||
|
filterExt.removeTargetFilter(oldContainer);
|
||||||
|
filterExt.setTargetFilter(newContainer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (CoreException exception) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2015 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 java.util.Hashtable;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IRunControl.IStartedDMEvent;
|
||||||
|
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version of BreakpointsManager for GDB version starting with 7.2.
|
||||||
|
* @since 4.7
|
||||||
|
*/
|
||||||
|
public class GDBBreakpointsManager_7_2 extends GDBBreakpointsManager_7_0 {
|
||||||
|
public GDBBreakpointsManager_7_2(DsfSession session, String debugModelId) {
|
||||||
|
super(session, debugModelId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(final RequestMonitor rm) {
|
||||||
|
super.initialize(new ImmediateRequestMonitor(rm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
doInitialize(rm);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doInitialize(final RequestMonitor rm) {
|
||||||
|
register(new String[] { GDBBreakpointsManager_7_2.class.getName() },
|
||||||
|
new Hashtable<String, String>());
|
||||||
|
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateContextOnStartEvent(IStartedDMEvent e) {
|
||||||
|
// No longer need to update the context as the logic
|
||||||
|
// of the base class was to work around an issue with
|
||||||
|
// GDB 7.0 and 7.1
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008, 2014 Ericsson and others.
|
* Copyright (c) 2008, 2015 Ericsson and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -125,6 +125,12 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MIBreakpointsManager createBreakpointManagerService(DsfSession session) {
|
protected MIBreakpointsManager createBreakpointManagerService(DsfSession session) {
|
||||||
|
if (GDB_7_2_VERSION.compareTo(fVersion) <= 0) {
|
||||||
|
return new GDBBreakpointsManager_7_2(session, CDebugCorePlugin.PLUGIN_ID);
|
||||||
|
}
|
||||||
|
if (GDB_7_0_VERSION.compareTo(fVersion) <= 0) {
|
||||||
|
return new GDBBreakpointsManager_7_0(session, CDebugCorePlugin.PLUGIN_ID);
|
||||||
|
}
|
||||||
return new MIBreakpointsManager(session, CDebugCorePlugin.PLUGIN_ID);
|
return new MIBreakpointsManager(session, CDebugCorePlugin.PLUGIN_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -158,7 +158,16 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
// - Augmented on breakpointAdded()
|
// - Augmented on breakpointAdded()
|
||||||
// - Modified on breakpointChanged()
|
// - Modified on breakpointChanged()
|
||||||
// - Diminished on breakpointRemoved()
|
// - Diminished on breakpointRemoved()
|
||||||
private Map<IBreakpointsTargetDMContext, Map<ICBreakpoint, Map<String, Object>>> fPlatformBPs = new HashMap<>();
|
private Map<IBreakpointsTargetDMContext, Map<ICBreakpoint, Map<String, Object>>> fPlatformToAttributesMaps = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the structure that maps each breakpoint target to a map of platform breakpoints
|
||||||
|
* and their corresponding back-end attributes.
|
||||||
|
* @since 4.7
|
||||||
|
*/
|
||||||
|
protected Map<IBreakpointsTargetDMContext, Map<ICBreakpoint, Map<String, Object>>> getPlatformToAttributesMaps() {
|
||||||
|
return fPlatformToAttributesMaps;
|
||||||
|
}
|
||||||
|
|
||||||
// Holds the set of target breakpoints, per execution context, and their
|
// Holds the set of target breakpoints, per execution context, and their
|
||||||
// mapping to the corresponding platform breakpoint. In a given execution
|
// mapping to the corresponding platform breakpoint. In a given execution
|
||||||
|
@ -169,7 +178,16 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
// - We start/stop tracking an execution context
|
// - We start/stop tracking an execution context
|
||||||
// - A platform breakpoint is added/removed
|
// - A platform breakpoint is added/removed
|
||||||
// - A thread filter is applied/removed
|
// - A thread filter is applied/removed
|
||||||
private Map<IBreakpointsTargetDMContext, Map<IBreakpointDMContext, ICBreakpoint>> fTargetBPs = new HashMap<>();
|
private Map<IBreakpointsTargetDMContext, Map<IBreakpointDMContext, ICBreakpoint>> fBPToPlatformMaps = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the structure that maps each breakpoint target to a map of back-end breakpoints
|
||||||
|
* and their corresponding platform breakpoint.
|
||||||
|
* @since 4.7
|
||||||
|
*/
|
||||||
|
protected Map<IBreakpointsTargetDMContext, Map<IBreakpointDMContext, ICBreakpoint>> getBPToPlatformMaps() {
|
||||||
|
return fBPToPlatformMaps;
|
||||||
|
}
|
||||||
|
|
||||||
// Holds the mapping from platform breakpoint to the corresponding target
|
// Holds the mapping from platform breakpoint to the corresponding target
|
||||||
// breakpoint(s), per context. There can be multiple back-end BPs for a
|
// breakpoint(s), per context. There can be multiple back-end BPs for a
|
||||||
|
@ -179,7 +197,16 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
// - We start/stop tracking an execution context
|
// - We start/stop tracking an execution context
|
||||||
// - A platform breakpoint is added/removed
|
// - A platform breakpoint is added/removed
|
||||||
// - A thread filter is applied/removed
|
// - A thread filter is applied/removed
|
||||||
private Map<IBreakpointsTargetDMContext, Map<ICBreakpoint, Vector<IBreakpointDMContext>>> fBreakpointIDs = new HashMap<>();
|
private Map<IBreakpointsTargetDMContext, Map<ICBreakpoint, Vector<IBreakpointDMContext>>> fPlatformToBPsMaps = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the structure that maps each breakpoint target to a map of platform breakpoints
|
||||||
|
* and their corresponding vector of back-end breakpoints.
|
||||||
|
* @since 4.7
|
||||||
|
*/
|
||||||
|
protected Map<IBreakpointsTargetDMContext, Map<ICBreakpoint, Vector<IBreakpointDMContext>>> getPlatformToBPsMaps() {
|
||||||
|
return fPlatformToBPsMaps;
|
||||||
|
}
|
||||||
|
|
||||||
// Holds the mapping from platform breakpoint to the corresponding target
|
// Holds the mapping from platform breakpoint to the corresponding target
|
||||||
// breakpoint threads, per context.
|
// breakpoint threads, per context.
|
||||||
|
@ -187,7 +214,16 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
// - We start/stop tracking an execution context
|
// - We start/stop tracking an execution context
|
||||||
// - A platform breakpoint is added/removed
|
// - A platform breakpoint is added/removed
|
||||||
// - A thread filter is applied/removed
|
// - A thread filter is applied/removed
|
||||||
private Map<IBreakpointsTargetDMContext, Map<ICBreakpoint, Set<String>>> fBreakpointThreads = new HashMap<>();
|
private Map<IBreakpointsTargetDMContext, Map<ICBreakpoint, Set<String>>> fPlatformToBPThreadsMaps = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the structure that maps each breakpoint target to a map of platform breakpoints
|
||||||
|
* and their corresponding back-end breakpoint thread ids.
|
||||||
|
* @since 4.7
|
||||||
|
*/
|
||||||
|
protected Map<IBreakpointsTargetDMContext, Map<ICBreakpoint, Set<String>>> getPlatformToBPThreadsMaps() {
|
||||||
|
return fPlatformToBPThreadsMaps;
|
||||||
|
}
|
||||||
|
|
||||||
// Due to the very asynchronous nature of DSF, a new breakpoint request can
|
// Due to the very asynchronous nature of DSF, a new breakpoint request can
|
||||||
// pop up at any time before an ongoing one is completed. The following set
|
// pop up at any time before an ongoing one is completed. The following set
|
||||||
|
@ -319,8 +355,8 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
List<IBreakpointsTargetDMContext> targetBPKeys = new ArrayList<>(fTargetBPs.size());
|
List<IBreakpointsTargetDMContext> targetBPKeys = new ArrayList<>(fBPToPlatformMaps.size());
|
||||||
targetBPKeys.addAll(0, fTargetBPs.keySet());
|
targetBPKeys.addAll(0, fBPToPlatformMaps.keySet());
|
||||||
for (IBreakpointsTargetDMContext dmc : targetBPKeys) {
|
for (IBreakpointsTargetDMContext dmc : targetBPKeys) {
|
||||||
stopTrackingBreakpoints(dmc, countingRm);
|
stopTrackingBreakpoints(dmc, countingRm);
|
||||||
}
|
}
|
||||||
|
@ -357,7 +393,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
final IBreakpointsTargetDMContext targetBpDmc = DMContexts.getAncestorOfType(containerDmc,
|
final IBreakpointsTargetDMContext targetBpDmc = DMContexts.getAncestorOfType(containerDmc,
|
||||||
IBreakpointsTargetDMContext.class);
|
IBreakpointsTargetDMContext.class);
|
||||||
|
|
||||||
IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(fDebugModelId);
|
IBreakpoint[] breakpoints = fBreakpointManager.getBreakpoints(fDebugModelId);
|
||||||
for (IBreakpoint breakpoint : breakpoints) {
|
for (IBreakpoint breakpoint : breakpoints) {
|
||||||
if (breakpoint instanceof ICBreakpoint && supportsBreakpoint(breakpoint)) {
|
if (breakpoint instanceof ICBreakpoint && supportsBreakpoint(breakpoint)) {
|
||||||
setTargetFilter((ICBreakpoint) breakpoint, containerDmc);
|
setTargetFilter((ICBreakpoint) breakpoint, containerDmc);
|
||||||
|
@ -390,10 +426,10 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<ICBreakpoint,Map<String, Object>> platformBPs = fPlatformBPs.get(dmc);
|
Map<ICBreakpoint,Map<String, Object>> platformBPs = fPlatformToAttributesMaps.get(dmc);
|
||||||
Map<ICBreakpoint, Vector<IBreakpointDMContext>> breakpointIDs = fBreakpointIDs.get(dmc);
|
Map<ICBreakpoint, Vector<IBreakpointDMContext>> breakpointIDs = fPlatformToBPsMaps.get(dmc);
|
||||||
Map<IBreakpointDMContext, ICBreakpoint> targetIDs = fTargetBPs.get(dmc);
|
Map<IBreakpointDMContext, ICBreakpoint> targetIDs = fBPToPlatformMaps.get(dmc);
|
||||||
Map<ICBreakpoint, Set<String>> threadIDs = fBreakpointThreads.get(dmc);
|
Map<ICBreakpoint, Set<String>> threadIDs = fPlatformToBPThreadsMaps.get(dmc);
|
||||||
if ((platformBPs != null) || (breakpointIDs != null) || (targetIDs != null) || (threadIDs != null)) {
|
if ((platformBPs != null) || (breakpointIDs != null) || (targetIDs != null) || (threadIDs != null)) {
|
||||||
// If the maps already contains this context we can simply ignore this request.
|
// 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
|
// This happens when we start or attach to another process with GDB >= 7.4
|
||||||
|
@ -404,10 +440,10 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
|
|
||||||
// Create entries in the breakpoint tables for the new context. These entries should only
|
// Create entries in the breakpoint tables for the new context. These entries should only
|
||||||
// be removed when this service stops tracking breakpoints for the given context.
|
// be removed when this service stops tracking breakpoints for the given context.
|
||||||
fPlatformBPs.put(dmc, new HashMap<ICBreakpoint, Map<String, Object>>());
|
fPlatformToAttributesMaps.put(dmc, new HashMap<ICBreakpoint, Map<String, Object>>());
|
||||||
fBreakpointIDs.put(dmc, new HashMap<ICBreakpoint, Vector<IBreakpointDMContext>>());
|
fPlatformToBPsMaps.put(dmc, new HashMap<ICBreakpoint, Vector<IBreakpointDMContext>>());
|
||||||
fTargetBPs.put(dmc, new HashMap<IBreakpointDMContext, ICBreakpoint>());
|
fBPToPlatformMaps.put(dmc, new HashMap<IBreakpointDMContext, ICBreakpoint>());
|
||||||
fBreakpointThreads.put(dmc, new HashMap<ICBreakpoint, Set<String>>());
|
fPlatformToBPThreadsMaps.put(dmc, new HashMap<ICBreakpoint, Set<String>>());
|
||||||
|
|
||||||
// Install the platform breakpoints (stored in fPlatformBPs) on the target.
|
// Install the platform breakpoints (stored in fPlatformBPs) on the target.
|
||||||
new Job("DSF BreakpointsManager: Install initial breakpoints on target") { //$NON-NLS-1$
|
new Job("DSF BreakpointsManager: Install initial breakpoints on target") { //$NON-NLS-1$
|
||||||
|
@ -446,7 +482,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
private void installInitialBreakpoints(final IBreakpointsTargetDMContext dmc, final RequestMonitor rm)
|
private void installInitialBreakpoints(final IBreakpointsTargetDMContext dmc, final RequestMonitor rm)
|
||||||
{
|
{
|
||||||
// Retrieve the set of platform breakpoints for this context
|
// Retrieve the set of platform breakpoints for this context
|
||||||
final Map<ICBreakpoint,Map<String, Object>> platformBPs = fPlatformBPs.get(dmc);
|
final Map<ICBreakpoint,Map<String, Object>> platformBPs = fPlatformToAttributesMaps.get(dmc);
|
||||||
if (platformBPs == null) {
|
if (platformBPs == null) {
|
||||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, INVALID_CONTEXT, null));
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, INVALID_CONTEXT, null));
|
||||||
rm.done();
|
rm.done();
|
||||||
|
@ -456,7 +492,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
// Read current breakpoints from platform and copy their augmented
|
// Read current breakpoints from platform and copy their augmented
|
||||||
// attributes into the local reference map
|
// attributes into the local reference map
|
||||||
try {
|
try {
|
||||||
IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(fDebugModelId);
|
IBreakpoint[] breakpoints = fBreakpointManager.getBreakpoints(fDebugModelId);
|
||||||
for (IBreakpoint breakpoint : breakpoints) {
|
for (IBreakpoint breakpoint : breakpoints) {
|
||||||
if (supportsBreakpoint(breakpoint)) {
|
if (supportsBreakpoint(breakpoint)) {
|
||||||
Map<String, Object> attributes = breakpoint.getMarker().getAttributes();
|
Map<String, Object> attributes = breakpoint.getMarker().getAttributes();
|
||||||
|
@ -514,7 +550,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the set of platform breakpoints for this context
|
// Retrieve the set of platform breakpoints for this context
|
||||||
final Map<ICBreakpoint,Map<String, Object>> platformBPs = fPlatformBPs.get(dmc);
|
final Map<ICBreakpoint,Map<String, Object>> platformBPs = fPlatformToAttributesMaps.get(dmc);
|
||||||
if (platformBPs == null) {
|
if (platformBPs == null) {
|
||||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, INVALID_CONTEXT, null));
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, INVALID_CONTEXT, null));
|
||||||
rm.done();
|
rm.done();
|
||||||
|
@ -527,10 +563,10 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) {
|
final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) {
|
||||||
@Override
|
@Override
|
||||||
protected void handleCompleted() {
|
protected void handleCompleted() {
|
||||||
fPlatformBPs.remove(dmc);
|
fPlatformToAttributesMaps.remove(dmc);
|
||||||
fBreakpointIDs.remove(dmc);
|
fPlatformToBPsMaps.remove(dmc);
|
||||||
fTargetBPs.remove(dmc);
|
fBPToPlatformMaps.remove(dmc);
|
||||||
fBreakpointThreads.remove(dmc);
|
fPlatformToBPThreadsMaps.remove(dmc);
|
||||||
// Notify breakpoints tracking listeners that the tracking is stopped.
|
// Notify breakpoints tracking listeners that the tracking is stopped.
|
||||||
for (Object o : fTrackingListeners.getListeners()) {
|
for (Object o : fTrackingListeners.getListeners()) {
|
||||||
((IMIBreakpointsTrackingListener)o).breakpointTrackingStopped(dmc);
|
((IMIBreakpointsTrackingListener)o).breakpointTrackingStopped(dmc);
|
||||||
|
@ -574,16 +610,16 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
final Map<String, Object> attributes, final RequestMonitor rm)
|
final Map<String, Object> attributes, final RequestMonitor rm)
|
||||||
{
|
{
|
||||||
// Retrieve the breakpoint maps
|
// Retrieve the breakpoint maps
|
||||||
final Map<ICBreakpoint,Map<String,Object>> platformBPs = fPlatformBPs.get(dmc);
|
final Map<ICBreakpoint,Map<String,Object>> platformBPs = fPlatformToAttributesMaps.get(dmc);
|
||||||
assert platformBPs != null;
|
assert platformBPs != null;
|
||||||
|
|
||||||
final Map<ICBreakpoint, Vector<IBreakpointDMContext>> breakpointIDs = fBreakpointIDs.get(dmc);
|
final Map<ICBreakpoint, Vector<IBreakpointDMContext>> breakpointIDs = fPlatformToBPsMaps.get(dmc);
|
||||||
assert breakpointIDs != null;
|
assert breakpointIDs != null;
|
||||||
|
|
||||||
final Map<IBreakpointDMContext, ICBreakpoint> targetBPs = fTargetBPs.get(dmc);
|
final Map<IBreakpointDMContext, ICBreakpoint> targetBPs = fBPToPlatformMaps.get(dmc);
|
||||||
assert targetBPs != null;
|
assert targetBPs != null;
|
||||||
|
|
||||||
final Map<ICBreakpoint, Set<String>> threadsIDs = fBreakpointThreads.get(dmc);
|
final Map<ICBreakpoint, Set<String>> threadsIDs = fPlatformToBPThreadsMaps.get(dmc);
|
||||||
assert threadsIDs != null;
|
assert threadsIDs != null;
|
||||||
|
|
||||||
// Ensure the breakpoint has a valid debugger source path
|
// Ensure the breakpoint has a valid debugger source path
|
||||||
|
@ -774,16 +810,16 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
final ICBreakpoint breakpoint, final RequestMonitor rm)
|
final ICBreakpoint breakpoint, final RequestMonitor rm)
|
||||||
{
|
{
|
||||||
// Retrieve the breakpoint maps
|
// Retrieve the breakpoint maps
|
||||||
final Map<ICBreakpoint,Map<String,Object>> platformBPs = fPlatformBPs.get(dmc);
|
final Map<ICBreakpoint,Map<String,Object>> platformBPs = fPlatformToAttributesMaps.get(dmc);
|
||||||
assert platformBPs != null;
|
assert platformBPs != null;
|
||||||
|
|
||||||
final Map<ICBreakpoint, Vector<IBreakpointDMContext>> breakpointIDs = fBreakpointIDs.get(dmc);
|
final Map<ICBreakpoint, Vector<IBreakpointDMContext>> breakpointIDs = fPlatformToBPsMaps.get(dmc);
|
||||||
assert breakpointIDs != null;
|
assert breakpointIDs != null;
|
||||||
|
|
||||||
final Map<IBreakpointDMContext, ICBreakpoint> targetBPs = fTargetBPs.get(dmc);
|
final Map<IBreakpointDMContext, ICBreakpoint> targetBPs = fBPToPlatformMaps.get(dmc);
|
||||||
assert targetBPs != null;
|
assert targetBPs != null;
|
||||||
|
|
||||||
final Map<ICBreakpoint, Set<String>> threadsIDs = fBreakpointThreads.get(dmc);
|
final Map<ICBreakpoint, Set<String>> threadsIDs = fPlatformToBPThreadsMaps.get(dmc);
|
||||||
assert threadsIDs != null;
|
assert threadsIDs != null;
|
||||||
|
|
||||||
// Remove all relevant target filters
|
// Remove all relevant target filters
|
||||||
|
@ -880,16 +916,16 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
final Map<String,Object> attributes, final IMarkerDelta oldValues, final RequestMonitor rm)
|
final Map<String,Object> attributes, final IMarkerDelta oldValues, final RequestMonitor rm)
|
||||||
{
|
{
|
||||||
// Retrieve the breakpoint maps
|
// Retrieve the breakpoint maps
|
||||||
final Map<ICBreakpoint,Map<String,Object>> platformBPs = fPlatformBPs.get(dmc);
|
final Map<ICBreakpoint,Map<String,Object>> platformBPs = fPlatformToAttributesMaps.get(dmc);
|
||||||
assert platformBPs != null;
|
assert platformBPs != null;
|
||||||
|
|
||||||
final Map<ICBreakpoint, Vector<IBreakpointDMContext>> breakpointIDs = fBreakpointIDs.get(dmc);
|
final Map<ICBreakpoint, Vector<IBreakpointDMContext>> breakpointIDs = fPlatformToBPsMaps.get(dmc);
|
||||||
assert breakpointIDs != null;
|
assert breakpointIDs != null;
|
||||||
|
|
||||||
final Map<IBreakpointDMContext, ICBreakpoint> targetBPs = fTargetBPs.get(dmc);
|
final Map<IBreakpointDMContext, ICBreakpoint> targetBPs = fBPToPlatformMaps.get(dmc);
|
||||||
assert targetBPs != null;
|
assert targetBPs != null;
|
||||||
|
|
||||||
final Map<ICBreakpoint, Set<String>> threadsIDs = fBreakpointThreads.get(dmc);
|
final Map<ICBreakpoint, Set<String>> threadsIDs = fPlatformToBPThreadsMaps.get(dmc);
|
||||||
assert threadsIDs != null;
|
assert threadsIDs != null;
|
||||||
|
|
||||||
boolean filtered = isBreakpointEntirelyFiltered(dmc, breakpoint);
|
boolean filtered = isBreakpointEntirelyFiltered(dmc, breakpoint);
|
||||||
|
@ -998,7 +1034,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
@Override
|
@Override
|
||||||
protected void handleSuccess() {
|
protected void handleSuccess() {
|
||||||
// All right! Save the new list and perform the final update
|
// All right! Save the new list and perform the final update
|
||||||
Map<ICBreakpoint, Vector<IBreakpointDMContext>> breakpointIDs = fBreakpointIDs.get(dmc);
|
Map<ICBreakpoint, Vector<IBreakpointDMContext>> breakpointIDs = fPlatformToBPsMaps.get(dmc);
|
||||||
if (breakpointIDs == null) {
|
if (breakpointIDs == null) {
|
||||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, INVALID_BREAKPOINT, null));
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, INVALID_BREAKPOINT, null));
|
||||||
rm.done();
|
rm.done();
|
||||||
|
@ -1155,13 +1191,13 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
public void breakpointManagerEnablementChanged(boolean enabled) {
|
public void breakpointManagerEnablementChanged(boolean enabled) {
|
||||||
|
|
||||||
// Only modify enabled breakpoints
|
// Only modify enabled breakpoints
|
||||||
for (IBreakpointsTargetDMContext context : fBreakpointIDs.keySet()) {
|
for (IBreakpointsTargetDMContext context : fPlatformToBPsMaps.keySet()) {
|
||||||
for (ICBreakpoint breakpoint : fBreakpointIDs.get(context).keySet()) {
|
for (ICBreakpoint breakpoint : fPlatformToBPsMaps.get(context).keySet()) {
|
||||||
try {
|
try {
|
||||||
// Note that Tracepoints and dynamic printf are not affected by "skip-all"
|
// Note that Tracepoints and dynamic printf are not affected by "skip-all"
|
||||||
if (!(breakpoint instanceof ICTracepoint) && !(breakpoint instanceof ICDynamicPrintf)
|
if (!(breakpoint instanceof ICTracepoint) && !(breakpoint instanceof ICDynamicPrintf)
|
||||||
&& breakpoint.isEnabled()) {
|
&& breakpoint.isEnabled()) {
|
||||||
for (IBreakpointDMContext ref : fBreakpointIDs.get(context).get(breakpoint)) {
|
for (IBreakpointDMContext ref : fPlatformToBPsMaps.get(context).get(breakpoint)) {
|
||||||
Map<String,Object> delta = new HashMap<>();
|
Map<String,Object> delta = new HashMap<>();
|
||||||
delta.put(MIBreakpoints.IS_ENABLED, enabled);
|
delta.put(MIBreakpoints.IS_ENABLED, enabled);
|
||||||
fBreakpoints.updateBreakpoint(ref, delta, new RequestMonitor(getExecutor(), null));
|
fBreakpoints.updateBreakpoint(ref, delta, new RequestMonitor(getExecutor(), null));
|
||||||
|
@ -1231,9 +1267,9 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
countingRm.setDoneCount(fPlatformBPs.size());
|
countingRm.setDoneCount(fPlatformToAttributesMaps.size());
|
||||||
|
|
||||||
for (final IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) {
|
for (final IBreakpointsTargetDMContext dmc : fPlatformToAttributesMaps.keySet()) {
|
||||||
determineDebuggerPath(dmc, attrs,
|
determineDebuggerPath(dmc, attrs,
|
||||||
new RequestMonitor(getExecutor(), countingRm) {
|
new RequestMonitor(getExecutor(), countingRm) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -1258,8 +1294,9 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
* @param bp
|
* @param bp
|
||||||
* @return
|
* @return
|
||||||
* @throws CoreException
|
* @throws CoreException
|
||||||
|
* @since 4.7
|
||||||
*/
|
*/
|
||||||
private IDsfBreakpointExtension getFilterExtension(ICBreakpoint bp) throws CoreException {
|
protected IDsfBreakpointExtension getFilterExtension(ICBreakpoint bp) throws CoreException {
|
||||||
return (IDsfBreakpointExtension) bp.getExtension(GDB_DEBUG_MODEL_ID, ICBreakpointExtension.class);
|
return (IDsfBreakpointExtension) bp.getExtension(GDB_DEBUG_MODEL_ID, ICBreakpointExtension.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1312,13 +1349,13 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
countingRm.setDoneCount(fPlatformBPs.size());
|
countingRm.setDoneCount(fPlatformToAttributesMaps.size());
|
||||||
|
|
||||||
// Mark the breakpoint as being updated and go
|
// Mark the breakpoint as being updated and go
|
||||||
fPendingRequests.add(breakpoint);
|
fPendingRequests.add(breakpoint);
|
||||||
|
|
||||||
// Modify the breakpoint in all the execution contexts
|
// Modify the breakpoint in all the execution contexts
|
||||||
for (final IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) {
|
for (final IBreakpointsTargetDMContext dmc : fPlatformToAttributesMaps.keySet()) {
|
||||||
determineDebuggerPath(dmc, attrs,
|
determineDebuggerPath(dmc, attrs,
|
||||||
new RequestMonitor(getExecutor(), countingRm) {
|
new RequestMonitor(getExecutor(), countingRm) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -1354,11 +1391,11 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
countingRm.setDoneCount(fPlatformBPs.size());
|
countingRm.setDoneCount(fPlatformToAttributesMaps.size());
|
||||||
|
|
||||||
// Remove the breakpoint in all the execution contexts
|
// Remove the breakpoint in all the execution contexts
|
||||||
for (IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) {
|
for (IBreakpointsTargetDMContext dmc : fPlatformToAttributesMaps.keySet()) {
|
||||||
if (fPlatformBPs.get(dmc).containsKey(breakpoint)) {
|
if (fPlatformToAttributesMaps.get(dmc).containsKey(breakpoint)) {
|
||||||
uninstallBreakpoint(dmc, (ICBreakpoint) breakpoint, countingRm);
|
uninstallBreakpoint(dmc, (ICBreakpoint) breakpoint, countingRm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1458,9 +1495,9 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
|
|
||||||
// FIXME: (Bug228703) Need a way to identify the correct context where the BP was hit
|
// FIXME: (Bug228703) Need a way to identify the correct context where the BP was hit
|
||||||
private ICBreakpoint findPlatformBreakpoint(int targetBreakpointID) {
|
private ICBreakpoint findPlatformBreakpoint(int targetBreakpointID) {
|
||||||
Set<IBreakpointsTargetDMContext> targets = fTargetBPs.keySet();
|
Set<IBreakpointsTargetDMContext> targets = fBPToPlatformMaps.keySet();
|
||||||
for (IBreakpointsTargetDMContext target : targets) {
|
for (IBreakpointsTargetDMContext target : targets) {
|
||||||
Map<IBreakpointDMContext, ICBreakpoint> bps = fTargetBPs.get(target);
|
Map<IBreakpointDMContext, ICBreakpoint> bps = fBPToPlatformMaps.get(target);
|
||||||
Set<IBreakpointDMContext> contexts = bps.keySet();
|
Set<IBreakpointDMContext> contexts = bps.keySet();
|
||||||
for (IBreakpointDMContext context : contexts) {
|
for (IBreakpointDMContext context : contexts) {
|
||||||
if (context instanceof MIBreakpointDMContext) {
|
if (context instanceof MIBreakpointDMContext) {
|
||||||
|
@ -1483,7 +1520,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
if (bpContext instanceof MIBreakpointDMContext) {
|
if (bpContext instanceof MIBreakpointDMContext) {
|
||||||
IBreakpointsTargetDMContext targetCtx = DMContexts.getAncestorOfType(bpContext, IBreakpointsTargetDMContext.class);
|
IBreakpointsTargetDMContext targetCtx = DMContexts.getAncestorOfType(bpContext, IBreakpointsTargetDMContext.class);
|
||||||
if (targetCtx != null) {
|
if (targetCtx != null) {
|
||||||
Map<IBreakpointDMContext, ICBreakpoint> bps = fTargetBPs.get(targetCtx);
|
Map<IBreakpointDMContext, ICBreakpoint> bps = fBPToPlatformMaps.get(targetCtx);
|
||||||
if (bps != null)
|
if (bps != null)
|
||||||
return bps.get(bpContext);
|
return bps.get(bpContext);
|
||||||
}
|
}
|
||||||
|
@ -1535,7 +1572,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
public void removeTargetFilter(IContainerDMContext containerDMC) {
|
public void removeTargetFilter(IContainerDMContext containerDMC) {
|
||||||
// We must get the list of breakpoints from the platform because our different
|
// We must get the list of breakpoints from the platform because our different
|
||||||
// maps might already have been cleaned up
|
// maps might already have been cleaned up
|
||||||
IBreakpoint[] allBreakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(fDebugModelId);
|
IBreakpoint[] allBreakpoints = fBreakpointManager.getBreakpoints(fDebugModelId);
|
||||||
for (IBreakpoint bp : allBreakpoints) {
|
for (IBreakpoint bp : allBreakpoints) {
|
||||||
if (supportsBreakpoint(bp)) {
|
if (supportsBreakpoint(bp)) {
|
||||||
removeTargetFilter((ICBreakpoint) bp, containerDMC);
|
removeTargetFilter((ICBreakpoint) bp, containerDMC);
|
||||||
|
@ -1580,13 +1617,13 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
|
|
||||||
private void terminated() {
|
private void terminated() {
|
||||||
// Reset the breakpoint install count
|
// Reset the breakpoint install count
|
||||||
for (IBreakpointsTargetDMContext ctx : fPlatformBPs.keySet()) {
|
for (IBreakpointsTargetDMContext ctx : fPlatformToAttributesMaps.keySet()) {
|
||||||
Map<ICBreakpoint, Map<String, Object>> breakpoints = fPlatformBPs.get(ctx);
|
Map<ICBreakpoint, Map<String, Object>> breakpoints = fPlatformToAttributesMaps.get(ctx);
|
||||||
clearBreakpointStatus(breakpoints.keySet().toArray(new ICBreakpoint[breakpoints.size()]), ctx);
|
clearBreakpointStatus(breakpoints.keySet().toArray(new ICBreakpoint[breakpoints.size()]), ctx);
|
||||||
}
|
}
|
||||||
// This will prevent Shutdown() from trying to remove bps from a
|
// This will prevent Shutdown() from trying to remove bps from a
|
||||||
// backend that has already shutdown
|
// backend that has already shutdown
|
||||||
fPlatformBPs.clear();
|
fPlatformToAttributesMaps.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1601,7 +1638,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
// we must decrement the install count, for every target breakpoint.
|
// we must decrement the install count, for every target breakpoint.
|
||||||
// Note that we cannot simply call resetInstallCount() because another
|
// Note that we cannot simply call resetInstallCount() because another
|
||||||
// launch may be using the same platform breakpoint.
|
// launch may be using the same platform breakpoint.
|
||||||
Map<ICBreakpoint, Vector<IBreakpointDMContext>> breakpoints = fBreakpointIDs.get(ctx);
|
Map<ICBreakpoint, Vector<IBreakpointDMContext>> breakpoints = fPlatformToBPsMaps.get(ctx);
|
||||||
for (ICBreakpoint breakpoint : breakpoints.keySet()) {
|
for (ICBreakpoint breakpoint : breakpoints.keySet()) {
|
||||||
Vector<IBreakpointDMContext> targetBps = breakpoints.get(breakpoint);
|
Vector<IBreakpointDMContext> targetBps = breakpoints.get(breakpoint);
|
||||||
for (IBreakpointDMContext targetBp : targetBps) {
|
for (IBreakpointDMContext targetBp : targetBps) {
|
||||||
|
@ -1671,8 +1708,9 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
*
|
*
|
||||||
* @param bp the platform breakpoint
|
* @param bp the platform breakpoint
|
||||||
* @return true if we support it; false otherwise
|
* @return true if we support it; false otherwise
|
||||||
|
* @since 4.7
|
||||||
*/
|
*/
|
||||||
private boolean supportsBreakpoint(IBreakpoint bp) {
|
protected boolean supportsBreakpoint(IBreakpoint bp) {
|
||||||
if (bp instanceof ICBreakpoint && bp.getModelIdentifier().equals(fDebugModelId)) {
|
if (bp instanceof ICBreakpoint && bp.getModelIdentifier().equals(fDebugModelId)) {
|
||||||
IMarker marker = bp.getMarker();
|
IMarker marker = bp.getMarker();
|
||||||
if (marker != null) {
|
if (marker != null) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue