1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-09-10 12:03:16 +02:00

[228703] - [breakpoints] Add a breakpoint hit event to IBreakpoints service.

This commit is contained in:
Pawel Piech 2010-03-05 19:03:48 +00:00
parent e23f43553a
commit 7bdb38f1b0
6 changed files with 250 additions and 15 deletions

View file

@ -35,6 +35,7 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IRunControl2;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointDMContext;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
import org.eclipse.cdt.dsf.debug.service.IBreakpointsExtension.IBreakpointHitDMEvent;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext;
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
@ -51,6 +52,7 @@ import org.eclipse.cdt.dsf.mi.service.MIBreakpointDMData;
import org.eclipse.cdt.dsf.mi.service.MIBreakpoints;
import org.eclipse.cdt.dsf.mi.service.MIRunControl;
import org.eclipse.cdt.dsf.mi.service.MIStack;
import org.eclipse.cdt.dsf.mi.service.MIBreakpoints.MIBreakpointDMContext;
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
import org.eclipse.cdt.dsf.mi.service.command.events.IMIDMEvent;
import org.eclipse.cdt.dsf.mi.service.command.events.MIBreakpointHitEvent;
@ -150,6 +152,27 @@ public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunCo
}
}
/**
* Indicates that the given thread has been suspended on a breakpoint.
* @since 3.0
*/
@Immutable
private static class BreakpointHitEvent extends SuspendedEvent
implements IBreakpointHitDMEvent
{
final private MIBreakpointDMContext[] fBreakpoints;
BreakpointHitEvent(IExecutionDMContext ctx, MIStoppedEvent miInfo, MIBreakpointDMContext bpCtx) {
super(ctx, miInfo);
fBreakpoints = new MIBreakpointDMContext[] { bpCtx };
}
public IBreakpointDMContext[] getBreakpoints() {
return fBreakpoints;
}
}
@Immutable
private static class ResumedEvent extends RunControlEvent<IExecutionDMContext, MIRunningEvent>
implements IResumedDMEvent
@ -1026,7 +1049,23 @@ public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunCo
// Don't broadcast the stopped event
return;
}
getSession().dispatchEvent(new SuspendedEvent(e.getDMContext(), e), getProperties());
MIBreakpointDMContext bp = null;
if (e instanceof MIBreakpointHitEvent) {
int bpId = ((MIBreakpointHitEvent)e).getNumber();
IBreakpointsTargetDMContext bpsTarget = DMContexts.getAncestorOfType(e.getDMContext(), IBreakpointsTargetDMContext.class);
if (bpsTarget != null && bpId >= 0) {
bp = new MIBreakpointDMContext(getSession().getId(), new IDMContext[] {bpsTarget}, bpId);
}
}
IDMEvent<?> event = null;
if (bp != null) {
event = new BreakpointHitEvent(e.getDMContext(), e, bp);
} else {
event = new SuspendedEvent(e.getDMContext(), e);
}
getSession().dispatchEvent(event, getProperties());
}

View file

@ -13,6 +13,7 @@ package org.eclipse.cdt.dsf.mi.service;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
@ -26,10 +27,15 @@ import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
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.IProcesses;
import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerResumedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IResumedDMEvent;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlShutdownDMEvent;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
@ -50,7 +56,7 @@ import org.osgi.framework.BundleContext;
* Initial breakpoint service implementation.
* Implements the IBreakpoints interface.
*/
public class MIBreakpoints extends AbstractDsfService implements IBreakpoints
public class MIBreakpoints extends AbstractDsfService implements IBreakpoints, IBreakpointsExtension
{
/**
* Breakpoint attributes markers used in the map parameters of insert/updateBreakpoint().
@ -96,6 +102,13 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints
private Map<IBreakpointsTargetDMContext, Map<Integer, MIBreakpointDMData>> fBreakpoints =
new HashMap<IBreakpointsTargetDMContext, Map<Integer, MIBreakpointDMData>>();
/**
* Map tracking which threads are currently suspended on a breakpoint.
* @since 3.0
*/
private Map<IExecutionDMContext, IBreakpointDMContext[]> fBreakpointHitMap =
new HashMap<IExecutionDMContext, IBreakpointDMContext[]>();
/**
* Returns a map of existing breakpoints for the specified context
*
@ -192,7 +205,18 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints
* @param reference the DsfMIBreakpoint reference
*/
public MIBreakpointDMContext(MIBreakpoints service, IDMContext[] parents, int reference) {
super(service.getSession().getId(), parents);
this(service.getSession().getId(), parents, reference);
}
/**
* @param sessionId session ID
* @param parents the parent contexts
* @param reference the DsfMIBreakpoint reference
*
* @since 3.0
*/
public MIBreakpointDMContext(String sessionId, IDMContext[] parents, int reference) {
super(sessionId, parents);
fReference = reference;
}
@ -269,7 +293,7 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints
getSession().addServiceEventListener(this, null);
// Register this service
register(new String[] { IBreakpoints.class.getName(), MIBreakpoints.class.getName() },
register(new String[] { IBreakpoints.class.getName(), IBreakpointsExtension.class.getName(), MIBreakpoints.class.getName() },
new Hashtable<String, String>());
rm.done();
@ -471,6 +495,15 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints
}
}
/**
* @since 3.0
*/
public void getExecutionContextBreakpoints(IExecutionDMContext ctx, DataRequestMonitor<IBreakpointDMContext[]> rm) {
IBreakpointDMContext[] bps = fBreakpointHitMap.get(ctx);
rm.setData(bps != null ? bps : new IBreakpointDMContext[0]);
rm.done();
}
/**
* @param map
* @param key
@ -1237,4 +1270,57 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints
}
}
};
/**
* @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.
*/
@DsfServiceEventHandler
public void eventDispatched(IBreakpointHitDMEvent e) {
if (e instanceof IContainerSuspendedDMEvent) {
IExecutionDMContext[] triggeringContexts = ((IContainerSuspendedDMEvent)e).getTriggeringContexts();
for (IExecutionDMContext ctx : triggeringContexts) {
fBreakpointHitMap.put(ctx, e.getBreakpoints());
}
} else {
fBreakpointHitMap.put(e.getDMContext(), e.getBreakpoints());
}
}
/**
* @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.
*/
@DsfServiceEventHandler
public void eventDispatched(IResumedDMEvent e) {
if (e instanceof IContainerResumedDMEvent) {
clearBreakpointHitForContainer(((IContainerResumedDMEvent)e).getDMContext());
} else {
fBreakpointHitMap.remove(e.getDMContext());
}
}
/**
* Event handler when a thread is destroyed
* @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.
*/
@DsfServiceEventHandler
public void eventDispatched(IExitedDMEvent e) {
if (e.getDMContext() instanceof IContainerDMContext) {
clearBreakpointHitForContainer(e.getDMContext());
} else {
fBreakpointHitMap.remove(e.getDMContext());
}
}
private void clearBreakpointHitForContainer(IDMContext container) {
for (Iterator<Map.Entry<IExecutionDMContext, IBreakpointDMContext[]>> itr = fBreakpointHitMap.entrySet().iterator(); itr.hasNext();) {
if (DMContexts.isAncestorOf(itr.next().getKey(), container)) {
itr.remove();
}
}
}
}

View file

@ -1277,6 +1277,18 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
return null;
}
/**
* Returns a platform breakpoint corresponding to a given target breakpoint.
*
* @since 3.0
*/
public IBreakpoint findPlatformBreakpoint(IBreakpointDMContext bpContext) {
if (bpContext instanceof MIBreakpointDMContext) {
return findPlatformBreakpoint(((MIBreakpointDMContext)bpContext).getReference());
}
return null;
}
//-------------------------------------------------------------------------
// Session exit
//-------------------------------------------------------------------------

View file

@ -32,6 +32,7 @@ import org.eclipse.cdt.dsf.debug.service.ICachingService;
import org.eclipse.cdt.dsf.debug.service.IProcesses;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointDMContext;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
import org.eclipse.cdt.dsf.debug.service.IBreakpointsExtension.IBreakpointHitDMEvent;
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.cdt.dsf.debug.service.command.BufferedCommandControl;
import org.eclipse.cdt.dsf.debug.service.command.CommandCache;
@ -39,6 +40,7 @@ import org.eclipse.cdt.dsf.debug.service.command.ICommand;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlShutdownDMEvent;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.mi.service.MIBreakpoints.MIBreakpointDMContext;
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
import org.eclipse.cdt.dsf.mi.service.command.events.IMIDMEvent;
import org.eclipse.cdt.dsf.mi.service.command.events.MIBreakpointHitEvent;
@ -187,6 +189,28 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl, I
}
}
/**
* Indicates that the given thread has been suspended on a breakpoint.
* @since 3.0
*/
@Immutable
protected static class BreakpointHitEvent extends SuspendedEvent
implements IBreakpointHitDMEvent
{
final private MIBreakpointDMContext[] fBreakpoints;
BreakpointHitEvent(IExecutionDMContext ctx, MIStoppedEvent miInfo, MIBreakpointDMContext bpCtx) {
super(ctx, miInfo);
fBreakpoints = new MIBreakpointDMContext[] { bpCtx };
}
public IBreakpointDMContext[] getBreakpoints() {
return fBreakpoints;
}
}
@Immutable
protected static class ContainerSuspendedEvent extends SuspendedEvent
implements IContainerSuspendedDMEvent
@ -203,6 +227,27 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl, I
}
}
/**
* Indicates that the given container has been suspended on a breakpoint.
* @since 3.0
*/
@Immutable
protected static class ContainerBreakpointHitEvent extends ContainerSuspendedEvent
implements IBreakpointHitDMEvent
{
final private MIBreakpointDMContext[] fBreakpoints;
ContainerBreakpointHitEvent(IContainerDMContext containerDmc, MIStoppedEvent miInfo, IExecutionDMContext triggeringDmc, MIBreakpointDMContext bpCtx) {
super(containerDmc, miInfo, triggeringDmc);
fBreakpoints = new MIBreakpointDMContext[] { bpCtx };
}
public IBreakpointDMContext[] getBreakpoints() {
return fBreakpoints;
}
}
@Immutable
protected static class ResumedEvent extends RunControlEvent<IExecutionDMContext, MIRunningEvent>
implements IResumedDMEvent
@ -382,6 +427,15 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl, I
return;
}
MIBreakpointDMContext bp = null;
if (e instanceof MIBreakpointHitEvent) {
int bpId = ((MIBreakpointHitEvent)e).getNumber();
IBreakpointsTargetDMContext bpsTarget = DMContexts.getAncestorOfType(e.getDMContext(), IBreakpointsTargetDMContext.class);
if (bpsTarget != null && bpId >= 0) {
bp = new MIBreakpointDMContext(getSession().getId(), new IDMContext[] {bpsTarget}, bpId);
}
}
IDMEvent<?> event = null;
// Find the container context, which is used in multi-threaded debugging.
final IContainerDMContext containerDmc = DMContexts.getAncestorOfType(e.getDMContext(), IContainerDMContext.class);
@ -407,9 +461,17 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl, I
});
return;
}
event = new ContainerSuspendedEvent(containerDmc, e, triggeringCtx);
if (bp != null) {
event = new ContainerBreakpointHitEvent(containerDmc, e, triggeringCtx, bp);
} else {
event = new ContainerSuspendedEvent(containerDmc, e, triggeringCtx);
}
} else {
event = new SuspendedEvent(e.getDMContext(), e);
if (bp != null) {
event = new BreakpointHitEvent(e.getDMContext(), e, bp);
} else {
event = new SuspendedEvent(e.getDMContext(), e);
}
}
getSession().dispatchEvent(event, getProperties());
}

View file

@ -732,15 +732,6 @@ public class MIStack extends AbstractDsfService
}
}
/**
* This method is left for API compatibility only.
* @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.
*/
@DsfServiceEventHandler
public void eventDispatched(MIRunControl.ContainerSuspendedEvent e) {
}
/**
* {@inheritDoc}
* @since 1.1

View file

@ -0,0 +1,45 @@
/*******************************************************************************
* Copyright (c) 2008 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.service;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
/**
* Extension to the Breakpoints service which adds support for corollating
* breakpoints and execution contexts.
* @since 2.1
*/
public interface IBreakpointsExtension extends IBreakpoints {
/**
* Event indicating that a given thread or container was suspended
* by the given breakpoint(s).
*/
public interface IBreakpointHitDMEvent extends ISuspendedDMEvent {
/**
* Returs the breakpoints that suspended the thread.
*/
IBreakpointDMContext[] getBreakpoints();
}
/**
* If a given execution context was suspended due hitting a breakpoint,
* this method should return the breakpoints which caused the thread or
* container to suspend.
*
* @param ctx Thread or container to get breakpoints for.
* @param rm Breakpoints that the thread suspended on.
*/
public void getExecutionContextBreakpoints(IExecutionDMContext ctx, DataRequestMonitor<IBreakpointDMContext[]> rm);
}