1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 09:25:31 +02:00

Bug 392512 - Support GDB breakpoint notifications

Change-Id: I244ba995392806a56a52852e0d0d9ea72f87edfa
Reviewed-on: https://git.eclipse.org/r/8327
Reviewed-by: Marc Khouzam <marc.khouzam@ericsson.com>
IP-Clean: Marc Khouzam <marc.khouzam@ericsson.com>
Tested-by: Marc Khouzam <marc.khouzam@ericsson.com>
Reviewed-by: Mikhail Khodjaiants <mikhailkhod@googlemail.com>
IP-Clean: Mikhail Khodjaiants <mikhailkhod@googlemail.com>
Tested-by: Mikhail Khodjaiants <mikhailkhod@googlemail.com>
This commit is contained in:
Mikhail Khodjaiants 2012-11-28 17:00:30 -05:00
parent db3fa6a01f
commit 12de79d9b0
9 changed files with 1760 additions and 36 deletions

View file

@ -696,6 +696,52 @@ public class CDIDebugModel {
return new CWatchpoint(resource, attributes, register);
}
/**
* Creates and returns a watchpoint for the source defined by the given
* source handle, at the given expression. The marker associated with the
* watchpoint will be created on the specified resource.
*
* @param sourceHandle
* the handle to the watchpoint source
* @param resource
* the resource on which to create the associated watchpoint
* marker
* @param type
* a type constant from ICBreakpointType
* @param writeAccess
* whether this is write watchpoint
* @param readAccess
* whether this is read watchpoint
* @param expression
* the expression on which the watchpoint is set
* @param enabled
* whether to enable or disable this breakpoint
* @param ignoreCount
* the number of times this breakpoint will be ignored
* @param condition
* the breakpoint condition
* @param register
* whether to add this breakpoint to the breakpoint manager
* @return a watchpoint
* @throws CoreException
* if this method fails. Reasons include:
* <ul>
* <li>Failure creating underlying marker. The exception's
* status contains the underlying exception responsible for the
* failure.</li>
* </ul>
*
* @since 7.3
*/
public static ICWatchpoint createWatchpoint(String sourceHandle, IResource resource, int type, boolean writeAccess,
boolean readAccess, String expression, boolean enabled, int ignoreCount, String condition, boolean register)
throws CoreException {
HashMap<String, Object> attributes = new HashMap<String, Object>(10);
setWatchPointAttributes(attributes, sourceHandle, resource, type, writeAccess, readAccess, expression, "", //$NON-NLS-1$
BigInteger.ZERO, enabled, ignoreCount, condition);
return new CWatchpoint(resource, attributes, register);
}
/**
* Creates and returns a watchpoint for the source defined by the given
* source handle, at the given expression. The marker associated with the
@ -850,6 +896,47 @@ public class CDIDebugModel {
attributes.put(ICWatchpoint.WRITE, Boolean.valueOf(writeAccess));
}
/**
* Helper function for setting common watchpoint attributes.
*
* @param attributes
* Map to write the attributes into.
* @param sourceHandle
* the handle to the watchpoint source
* @param resource
* the resource on which to create the associated watchpoint
* marker
* @param type
* a type constant from ICBreakpointType
* @param writeAccess
* whether this is write watchpoint
* @param readAccess
* whether this is read watchpoint
* @param expression
* the expression on which the watchpoint is set
* @param memorySpace
* the memory space in which the watchpoint is set
* @param range
* the range of the watchpoint in addressable units
* @param enabled
* whether to enable or disable this breakpoint
* @param ignoreCount
* the number of times this breakpoint will be ignored
* @param condition
* the breakpoint condition
* @param register
* whether to add this breakpoint to the breakpoint manager
*
* @since 7.3
*/
public static void setWatchPointAttributes(Map<String, Object> attributes, String sourceHandle, IResource resource,
int type, boolean writeAccess, boolean readAccess, String expression, String memorySpace, BigInteger range,
boolean enabled, int ignoreCount, String condition) {
setWatchPointAttributes(attributes, sourceHandle, resource,
writeAccess, readAccess, expression, memorySpace, range, enabled, ignoreCount, condition);
attributes.put(ICBreakpointType.TYPE, type);
}
/**
* Creates and returns a breakpoint for the function defined by the given
* name. The marker associated with the breakpoint will be created on the

View file

@ -357,6 +357,7 @@ public class CDebugUtils {
appendWatchMemorySpace(wp2, label);
appendWatchRange(wp2, label);
}
appendBreakpointType(watchpoint, label);
appendIgnoreCount(watchpoint, label);
appendCondition(watchpoint, label);
return label.toString();

View file

@ -35,6 +35,7 @@ import org.eclipse.cdt.dsf.mi.service.CSourceLookup;
import org.eclipse.cdt.dsf.mi.service.IMIBackend;
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager;
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsSynchronizer;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.IProgressMonitor;
@ -130,6 +131,11 @@ public class ServicesLaunchSequence extends Sequence {
requestMonitor.done();
}
}},
new Step() { @Override
public void execute(final RequestMonitor requestMonitor) {
// Create breakpoint synchronization service.
fLaunch.getServiceFactory().createService(MIBreakpointsSynchronizer.class, fSession).initialize(requestMonitor);
}},
};
DsfSession fSession;

View file

@ -0,0 +1,252 @@
/*******************************************************************************
* Copyright (c) 2012 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Mentor Graphics - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
import java.util.Hashtable;
import java.util.Map;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints;
import org.eclipse.cdt.dsf.debug.service.IBreakpointsExtension;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
import org.eclipse.cdt.dsf.debug.service.command.IEventListener;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
import org.eclipse.cdt.dsf.mi.service.MIBreakpointDMData;
import org.eclipse.cdt.dsf.mi.service.MIBreakpoints;
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsSynchronizer;
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakpoint;
import org.eclipse.cdt.dsf.mi.service.command.output.MIConst;
import org.eclipse.cdt.dsf.mi.service.command.output.MINotifyAsyncOutput;
import org.eclipse.cdt.dsf.mi.service.command.output.MIOOBRecord;
import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
import org.eclipse.cdt.dsf.mi.service.command.output.MIResult;
import org.eclipse.cdt.dsf.mi.service.command.output.MITuple;
import org.eclipse.cdt.dsf.mi.service.command.output.MIValue;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
/**
* Breakpoints service for GDB 7.4.
* Using breakpoint notifications introduced in 7.4 supports synchronization between the breakpoints
* set from the GDB console and the Breakpoints view as well as the tracepoints reported form trace files.
*
* @since 4.2
*/
public class GDBBreakpoints_7_4 extends GDBBreakpoints_7_2 implements IEventListener {
// Breakpoint notifications
private static final String BREAKPOINT_PREFIX = "breakpoint-"; //$NON-NLS-1$
private static final String BREAKPOINT_CREATED = BREAKPOINT_PREFIX + "created"; //$NON-NLS-1$
private static final String BREAKPOINT_MODIFIED = BREAKPOINT_PREFIX + "modified"; //$NON-NLS-1$
private static final String BREAKPOINT_DELETED = BREAKPOINT_PREFIX + "deleted"; //$NON-NLS-1$
private IMICommandControl fConnection;
public GDBBreakpoints_7_4(DsfSession session) {
super(session);
}
@Override
public void initialize(final RequestMonitor rm) {
super.initialize(new ImmediateRequestMonitor(rm) {
@Override
protected void handleSuccess() {
doInitialize(rm);
}
});
}
private void doInitialize(final RequestMonitor rm) {
fConnection = getServicesTracker().getService(IMICommandControl.class);
if (fConnection == null) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, "Service is not available")); //$NON-NLS-1$
rm.done();
return;
}
fConnection.addEventListener(this);
// Register this service
register(new String[] { IBreakpoints.class.getName(),
IBreakpointsExtension.class.getName(),
MIBreakpoints.class.getName(),
GDBBreakpoints_7_0.class.getName(),
GDBBreakpoints_7_2.class.getName(),
GDBBreakpoints_7_4.class.getName() },
new Hashtable<String, String>());
rm.done();
}
@Override
public void shutdown(RequestMonitor requestMonitor) {
ICommandControl control = getCommandControl();
if (control != null) {
control.removeEventListener(this);
}
unregister();
super.shutdown(requestMonitor);
}
@Override
public void eventReceived(Object output) {
if (output instanceof MIOutput) {
MIBreakpointsSynchronizer bs = getServicesTracker().getService(MIBreakpointsSynchronizer.class);
if (bs != null) {
MIOOBRecord[] records = ((MIOutput)output).getMIOOBRecords();
for(MIOOBRecord r : records) {
if (r instanceof MINotifyAsyncOutput) {
MINotifyAsyncOutput notifyOutput = (MINotifyAsyncOutput)r;
String asyncClass = notifyOutput.getAsyncClass();
if (BREAKPOINT_CREATED.equals(asyncClass)) {
MIBreakpoint bpt = getMIBreakpointFromOutput(notifyOutput);
if (bpt != null)
bs.targetBreakpointCreated(bpt);
}
else if (BREAKPOINT_DELETED.equals(asyncClass)) {
int id = getMIBreakpointIdFromOutput(notifyOutput);
if (id != 0)
bs.targetBreakpointDeleted(id);
}
else if (BREAKPOINT_MODIFIED.equals(asyncClass)) {
MIBreakpoint bpt = getMIBreakpointFromOutput(notifyOutput);
if (bpt != null)
bs.targetBreakpointModified(bpt);
}
}
}
}
}
}
private IMICommandControl getCommandControl() {
return fConnection;
}
private MIBreakpoint getMIBreakpointFromOutput(MINotifyAsyncOutput notifyOutput) {
MIBreakpoint bpt = null;
MIResult[] results = notifyOutput.getMIResults();
for(int i = 0; i < results.length; i++) {
String var = results[i].getVariable();
MIValue val = results[i].getMIValue();
if (var.equals("bkpt")) { //$NON-NLS-1$
if (val instanceof MITuple) {
bpt = new MIBreakpoint((MITuple)val);
}
}
}
return bpt;
}
private int getMIBreakpointIdFromOutput(MINotifyAsyncOutput notifyOutput) {
MIResult[] results = notifyOutput.getMIResults();
for(int i = 0; i < results.length; i++) {
String var = results[i].getVariable();
MIValue val = results[i].getMIValue();
if (var.equals("id") && val instanceof MIConst) { //$NON-NLS-1$
try {
return Integer.parseInt(((MIConst)val).getCString().trim());
}
catch(NumberFormatException e) {
GdbPlugin.log(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, "Invalid breakpoint id")); //$NON-NLS-1$
}
}
}
return 0;
}
@Override
protected void addBreakpoint(IBreakpointsTargetDMContext context, Map<String, Object> attributes, DataRequestMonitor<IBreakpointDMContext> finalRm) {
MIBreakpointsSynchronizer bs = getServicesTracker().getService(MIBreakpointsSynchronizer.class);
if (bs != null) {
// Skip the breakpoints set from the console or from outside of Eclipse
// because they are already installed on the target.
MIBreakpoint miBpt = bs.getTargetBreakpoint(context, attributes);
if (miBpt != null) {
bs.removeCreatedTargetBreakpoint(context, miBpt);
MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(miBpt);
getBreakpointMap(context).put(newBreakpoint.getNumber(), newBreakpoint);
IBreakpointDMContext dmc = new MIBreakpointDMContext(this, new IDMContext[] { context }, newBreakpoint.getNumber());
finalRm.setData(dmc);
getSession().dispatchEvent(new BreakpointAddedEvent(dmc), getProperties());
finalRm.done();
return;
}
}
super.addBreakpoint(context, attributes, finalRm);
}
@Override
protected void addTracepoint(IBreakpointsTargetDMContext context, Map<String, Object> attributes, DataRequestMonitor<IBreakpointDMContext> drm) {
MIBreakpointsSynchronizer bs = getServicesTracker().getService(MIBreakpointsSynchronizer.class);
if (bs != null) {
// Skip the breakpoints set from the console or from outside of Eclipse
// because they are already installed on the target.
MIBreakpoint miBpt = bs.getTargetBreakpoint(context, attributes);
if (miBpt != null) {
bs.removeCreatedTargetBreakpoint(context, miBpt);
MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(miBpt);
getBreakpointMap(context).put(newBreakpoint.getNumber(), newBreakpoint);
IBreakpointDMContext dmc = new MIBreakpointDMContext(this, new IDMContext[] { context }, newBreakpoint.getNumber());
drm.setData(dmc);
getSession().dispatchEvent(new BreakpointAddedEvent(dmc), getProperties());
drm.done();
return;
}
}
super.addTracepoint(context, attributes, drm);
}
@Override
protected void addWatchpoint(IBreakpointsTargetDMContext context, Map<String, Object> attributes, DataRequestMonitor<IBreakpointDMContext> drm) {
MIBreakpointsSynchronizer bs = getServicesTracker().getService(MIBreakpointsSynchronizer.class);
if (bs != null) {
// Skip the breakpoints set from the console or from outside of Eclipse
// because they are already installed on the target.
MIBreakpoint miBpt = bs.getTargetBreakpoint(context, attributes);
if (miBpt != null) {
bs.removeCreatedTargetBreakpoint(context, miBpt);
MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(miBpt);
getBreakpointMap(context).put(newBreakpoint.getNumber(), newBreakpoint);
IBreakpointDMContext dmc = new MIBreakpointDMContext(this, new IDMContext[] { context }, newBreakpoint.getNumber());
drm.setData(dmc);
getSession().dispatchEvent(new BreakpointAddedEvent(dmc), getProperties());
drm.done();
return;
}
}
super.addWatchpoint(context, attributes, drm);
}
@Override
protected void deleteBreakpointFromTarget(IBreakpointsTargetDMContext context, int reference, RequestMonitor finalRm) {
MIBreakpointsSynchronizer bs = getServicesTracker().getService(MIBreakpointsSynchronizer.class);
if (bs != null) {
// Do nothing if the breakpoint is deleted from the console.
if (bs.isTargetBreakpointDeleted(context, reference, true)) {
finalRm.done();
return;
}
}
super.deleteBreakpointFromTarget(context, reference, finalRm);
}
}

View file

@ -37,6 +37,7 @@ import org.eclipse.cdt.dsf.mi.service.CSourceLookup;
import org.eclipse.cdt.dsf.mi.service.IMIBackend;
import org.eclipse.cdt.dsf.mi.service.MIBreakpoints;
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager;
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsSynchronizer;
import org.eclipse.cdt.dsf.mi.service.MIDisassembly;
import org.eclipse.cdt.dsf.mi.service.MIExpressions;
import org.eclipse.cdt.dsf.mi.service.MIMemory;
@ -106,6 +107,9 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
}
}
}
else if (MIBreakpointsSynchronizer.class.isAssignableFrom(clazz)) {
return (V)createBreakpointsSynchronizerService(session);
}
return super.createService(clazz, session);
}
@ -116,6 +120,9 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
@Override
protected IBreakpoints createBreakpointService(DsfSession session) {
if (GDB_7_4_VERSION.compareTo(fVersion) <= 0) {
return new GDBBreakpoints_7_4(session);
}
// This service is available for GDB 7.2 but there is a pre-release of GDB that
// supports the same features and has version of 6.8.50.20090414
if (GDB_7_2_VERSION.compareTo(fVersion) <= 0 || "6.8.50.20090414".equals(fVersion)) { //$NON-NLS-1$
@ -237,4 +244,11 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
}
return new GDBHardwareAndOS(session);
}
/**
* @since 4.2
*/
protected MIBreakpointsSynchronizer createBreakpointsSynchronizerService(DsfSession session) {
return new MIBreakpointsSynchronizer(session);
}
}

View file

@ -20,6 +20,7 @@ import java.util.Map;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.Immutable;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
@ -913,26 +914,16 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints, I
return;
}
final Step deleteBreakpointStep = new Step() {
@Override
public void execute(final RequestMonitor rm) {
// Queue the command
fConnection.queueCommand(
fCommandFactory.createMIBreakDelete(context, new int[] { reference }),
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
getSession().dispatchEvent(new BreakpointRemovedEvent(dmc), getProperties());
contextBreakpoints.remove(reference);
}
rm.done();
}
});
}
};
fRunControl.executeWithTargetAvailable(context, new Step[] { deleteBreakpointStep }, finalRm);
deleteBreakpointFromTarget(context, reference, new RequestMonitor(ImmediateExecutor.getInstance(), finalRm) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
getSession().dispatchEvent(new BreakpointRemovedEvent(dmc), getProperties());
contextBreakpoints.remove(reference);
}
finalRm.done();
}
});
}
// -------------------------------------------------------------------------
@ -1279,6 +1270,24 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints, I
fRunControl.executeWithTargetAvailable(context, new Step[] { disableBreakpointStep }, finalRm);
}
/**
* This method deletes the target breakpoint with the given reference number.
* @since 4.2
*/
protected void deleteBreakpointFromTarget(final IBreakpointsTargetDMContext context, final int reference, RequestMonitor finalRm) {
final Step deleteBreakpointStep = new Step() {
@Override
public void execute(final RequestMonitor rm) {
// Queue the command
fConnection.queueCommand(
fCommandFactory.createMIBreakDelete(context, new int[] { reference }),
new DataRequestMonitor<MIInfo>(getExecutor(), rm));
}
};
fRunControl.executeWithTargetAvailable(context, new Step[] { deleteBreakpointStep }, finalRm);
}
/**
* @nooverride This method is not intended to be re-implemented or extended by clients.
* @noreference This method is not intended to be referenced by clients.
@ -1334,5 +1343,18 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints, I
}
fBreakpointHitMap.remove(container);
}
/**
* Returns a breakpoint target context for given breakpoint number.
* @since 4.2
*/
protected IBreakpointsTargetDMContext getBreakpointTargetContext(int reference) {
for (IBreakpointsTargetDMContext context : fBreakpoints.keySet()) {
Map<Integer, MIBreakpointDMData> map = fBreakpoints.get(context);
if (map != null && map.keySet().contains(Integer.valueOf(reference))) {
return context;
}
}
return null;
}
}

View file

@ -34,6 +34,7 @@ import org.eclipse.cdt.debug.core.model.ICBreakpoint;
import org.eclipse.cdt.debug.core.model.ICBreakpointExtension;
import org.eclipse.cdt.debug.core.model.ICBreakpointType;
import org.eclipse.cdt.debug.core.model.ICEventBreakpoint;
import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint;
import org.eclipse.cdt.debug.core.model.ICLineBreakpoint;
import org.eclipse.cdt.debug.core.model.ICTracepoint;
import org.eclipse.cdt.debug.core.model.ICWatchpoint;
@ -41,6 +42,7 @@ import org.eclipse.cdt.debug.internal.core.breakpoints.BreakpointProblems;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
@ -82,6 +84,7 @@ import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
@ -104,7 +107,19 @@ import com.ibm.icu.text.MessageFormat;
*/
public class MIBreakpointsManager extends AbstractDsfService implements IBreakpointManagerListener, IBreakpointListener
{
// Note: Find a way to import this (careful of circular dependencies)
/**
* A listener is notified by {@link MIBreakpointsManager} when
* the breakpoints tracking starts or stops.
* @since 4.2
*/
public interface IMIBreakpointsTrackingListener {
public void breakpointTrackingStarted(IBreakpointsTargetDMContext bpTargetDMC);
public void breakpointTrackingStopped(IBreakpointsTargetDMContext bpTargetDMC);
}
// Note: Find a way to import this (careful of circular dependencies)
public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.cdt.dsf.gdb"; //$NON-NLS-1$
// Extra breakpoint attributes
@ -177,6 +192,8 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
private Map<ICBreakpoint, IMarker> fBreakpointMarkerProblems =
new HashMap<ICBreakpoint, IMarker>();
private ListenerList fTrackingListeners = new ListenerList();
///////////////////////////////////////////////////////////////////////////
// String constants
///////////////////////////////////////////////////////////////////////////
@ -284,6 +301,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
getSession().removeServiceEventListener(this);
fBreakpointManager.removeBreakpointListener(this);
fBreakpointManager.removeBreakpointManagerListener(this);
fTrackingListeners.clear();
// Cleanup the breakpoints that are still installed by the service.
// Use a counting monitor which will call mom to complete the shutdown
@ -369,7 +387,16 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
getExecutor().submit(new Runnable() {
@Override
public void run() {
installInitialBreakpoints(dmc, rm);
installInitialBreakpoints(dmc, new RequestMonitor(ImmediateExecutor.getInstance(), rm) {
@Override
protected void handleSuccess() {
// Notify breakpoints tracking listeners that the tracking is started.
for (Object o : fTrackingListeners.getListeners()) {
((IMIBreakpointsTrackingListener)o).breakpointTrackingStarted(dmc);
}
rm.done();
};
});
}
});
@ -491,6 +518,10 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
fBreakpointIDs.remove(dmc);
fTargetBPs.remove(dmc);
fBreakpointThreads.remove(dmc);
// Notify breakpoints tracking listeners that the tracking is stopped.
for (Object o : fTrackingListeners.getListeners()) {
((IMIBreakpointsTrackingListener)o).breakpointTrackingStopped(dmc);
}
rm.done();
}
};
@ -549,7 +580,9 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
}
// Ensure the breakpoint has a valid debugger source path
if (breakpoint instanceof ICLineBreakpoint && !(breakpoint instanceof ICAddressBreakpoint)) {
if (breakpoint instanceof ICLineBreakpoint
&& !(breakpoint instanceof ICAddressBreakpoint)
&& !(breakpoint instanceof ICFunctionBreakpoint)) {
String debuggerPath = (String) attributes.get(ATTR_DEBUGGER_PATH);
if (debuggerPath == null || debuggerPath == NULL_STRING) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, NO_DEBUGGER_PATH, null));
@ -719,8 +752,10 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
* @param dmc
* @param breakpoint
* @param rm
*
* @since 4.2
*/
private void uninstallBreakpoint(final IBreakpointsTargetDMContext dmc,
public void uninstallBreakpoint(final IBreakpointsTargetDMContext dmc,
final ICBreakpoint breakpoint, final RequestMonitor rm)
{
// Retrieve the breakpoint maps
@ -1809,16 +1844,6 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
properties.put(MIBreakpoints.PASS_COUNT, attributes.get(ICTracepoint.PASS_COUNT));
}
// checks for the breakpoint type, and adds the hardware/temporary flags
Object breakpointType = attributes.get(ICBreakpointType.TYPE);
if(breakpointType != null) {
if(breakpointType instanceof Integer) {
boolean isHardware = ((Integer) breakpointType & ICBreakpointType.HARDWARE) == ICBreakpointType.HARDWARE;
boolean isTemporary = ((Integer) breakpointType & ICBreakpointType.TEMPORARY) == ICBreakpointType.TEMPORARY;
properties.put(MIBreakpointDMData.IS_HARDWARE, isHardware);
properties.put(MIBreakpointDMData.IS_TEMPORARY, isTemporary);
}
}
}
else if (breakpoint instanceof ICEventBreakpoint) {
properties.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.CATCHPOINT);
@ -1845,6 +1870,17 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
properties.put(MIBreakpoints.IS_ENABLED, attributes.get(ICBreakpoint.ENABLED));
properties.put(MIBreakpointDMData.THREAD_ID, attributes.get(ATTR_THREAD_ID));
// checks for the breakpoint type, and adds the hardware/temporary flags
Object breakpointType = attributes.get(ICBreakpointType.TYPE);
if(breakpointType != null) {
if(breakpointType instanceof Integer) {
boolean isHardware = ((Integer) breakpointType & ICBreakpointType.HARDWARE) == ICBreakpointType.HARDWARE;
boolean isTemporary = ((Integer) breakpointType & ICBreakpointType.TEMPORARY) == ICBreakpointType.TEMPORARY;
properties.put(MIBreakpointDMData.IS_HARDWARE, isHardware);
properties.put(MIBreakpointDMData.IS_TEMPORARY, isTemporary);
}
}
// Adjust for "skip-all"
// Tracepoints are not affected by "skip-all"
if (!(breakpoint instanceof ICTracepoint ) && !fBreakpointManager.isEnabled()) {
@ -1928,4 +1964,18 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
}
return true;
}
/**
* @since 4.2
*/
public void addBreakpointsTrackingListener(IMIBreakpointsTrackingListener listener) {
fTrackingListeners.add(listener);
}
/**
* @since 4.2
*/
public void removeBreakpointsTrackingListener(IMIBreakpointsTrackingListener listener) {
fTrackingListeners.remove(listener);
}
}

View file

@ -81,7 +81,8 @@ public class MIBreakpoint {
String threadId = "0"; //$NON-NLS-1$
int ignore = 0;
String commands = ""; //$NON-NLS-1$
String originalLocation = ""; //$NON-NLS-1$
// For tracepoints
int passcount = 0;
@ -145,6 +146,7 @@ public class MIBreakpoint {
isCatchpoint = other.isCatchpoint;
catchpointType = other.catchpointType;
pending = other.pending;
originalLocation = other.originalLocation;
if (other.groupIds != null) {
groupIds = Arrays.copyOf(other.groupIds, other.groupIds.length);
}
@ -292,6 +294,13 @@ public class MIBreakpoint {
return exp;
}
/**
* @since 4.2
*/
public String getOriginalLocation() {
return originalLocation;
}
/**
* If isCatchpoint is true, then this indicates the type of catchpoint
* (event), as reported by gdb in its response to the CLI catch command.
@ -487,6 +496,9 @@ public class MIBreakpoint {
type.startsWith("fast tracepoint")) { //$NON-NLS-1$
isTpt = true;
}
if (type.startsWith("catchpoint")) { //$NON-NLS-1$
isCatchpoint = true;
}
// type="breakpoint"
// default ok.
} else if (var.equals("disp")) { //$NON-NLS-1$
@ -541,6 +553,8 @@ public class MIBreakpoint {
if (value instanceof MIList) {
parseGroups((MIList)value);
}
} else if (var.equals("original-location")) { //$NON-NLS-1$
originalLocation = str;
}
}
}