mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
[248587] Fixed reporting of catchpoint hit in gdb >= 7.0
This commit is contained in:
parent
d7216843f2
commit
c6035901f5
4 changed files with 57 additions and 20 deletions
|
@ -14,6 +14,7 @@ package org.eclipse.cdt.dsf.mi.service.command;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
|
||||
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.IRunControl;
|
||||
|
@ -220,6 +221,7 @@ public class MIRunControlEventProcessor
|
|||
* a catchpoint hit.
|
||||
* @since 3.0
|
||||
*/
|
||||
@ConfinedToDsfExecutor("")
|
||||
protected MIEvent<?> createEvent(String reason, MIExecAsyncOutput exec, MIStreamRecord[] miStreamRecords) {
|
||||
IExecutionDMContext execDmc = getExecutionContext(exec);
|
||||
MIEvent<?> event = null;
|
||||
|
|
|
@ -14,6 +14,7 @@ package org.eclipse.cdt.dsf.mi.service.command;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
|
||||
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext;
|
||||
|
@ -252,6 +253,7 @@ public class MIRunControlEventProcessor_7_0
|
|||
* However, gdb also sends a stream record that reveals that it's
|
||||
* a catchpoint hit.
|
||||
*/
|
||||
@ConfinedToDsfExecutor("")
|
||||
protected MIEvent<?> createEvent(String reason, MIExecAsyncOutput exec, MIStreamRecord[] miStreamRecords) {
|
||||
MIEvent<?> event = null;
|
||||
|
||||
|
|
|
@ -12,13 +12,25 @@
|
|||
|
||||
package org.eclipse.cdt.dsf.mi.service.command.events;
|
||||
|
||||
import org.eclipse.cdt.debug.internal.core.breakpoints.CEventBreakpoint;
|
||||
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
|
||||
import org.eclipse.cdt.dsf.concurrent.Immutable;
|
||||
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.cdt.dsf.mi.service.MIBreakpoints.MIBreakpointDMContext;
|
||||
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIConst;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIFrame;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIResult;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIStreamRecord;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIValue;
|
||||
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.cdt.gdb.internal.eventbkpts.GdbCatchpoints;
|
||||
import org.eclipse.debug.core.DebugException;
|
||||
import org.eclipse.debug.core.model.IBreakpoint;
|
||||
|
||||
/**
|
||||
* Conveys that gdb reported the target stopped because of a breakpoint. This
|
||||
|
@ -47,8 +59,8 @@ public class MIBreakpointHitEvent extends MIStoppedEvent {
|
|||
* @param miStreamRecords
|
||||
* @since 3.0
|
||||
*/
|
||||
public static MIBreakpointHitEvent parse(IExecutionDMContext dmc, int token, MIResult[] results, MIStreamRecord[] miStreamRecords)
|
||||
{
|
||||
@ConfinedToDsfExecutor("")
|
||||
public static MIBreakpointHitEvent parse(IExecutionDMContext dmc, int token, MIResult[] results, MIStreamRecord[] miStreamRecords) {
|
||||
int bkptno = -1;
|
||||
|
||||
for (int i = 0; i < results.length; i++) {
|
||||
|
@ -71,19 +83,24 @@ public class MIBreakpointHitEvent extends MIStoppedEvent {
|
|||
// We might be here because of a catchpoint hit; in gdb >= 7.0,
|
||||
// catchpoints are reported as breakpoints. Unfortunately, there's
|
||||
// nothing in the stopped event indicating it's a catchpoint, and unlike
|
||||
// gdb < 7.0, there are no stream records that reveal it's a catchpoint.
|
||||
// The only way to determine it's a catchpoint is to map the gdb breakpoint
|
||||
// number back to the CBreakpoint (platform) instance, and that *will* reveal
|
||||
// whether it's a catchpoint or not, and even which kind of catchpoint
|
||||
// TODO:
|
||||
/*
|
||||
CBreakpoint cbkpt = FromSomewhere.getCBreakpointForGdbBreakpoint(bkptno); <== this method doesn't exist yet
|
||||
if (cbkpt instanceof CEventBreakpoint) {
|
||||
String eventTypeID = ((CEventBreakpoint)cbkpt).getEventType();
|
||||
String gdbKeyword = GdbCatchpoints.eventToGdbCatchpointKeyword(eventTypeID)
|
||||
return MICatchpointHitEvent.parse(stoppedEvent.getDMContext(), token, results, gdbKeyword);
|
||||
// gdb < 7.0, there are no stream records that tell us so. The only way
|
||||
// to determine it's a catchpoint is to map the gdb breakpoint number
|
||||
// back to the CBreakpoint (platform) object.
|
||||
IBreakpointsTargetDMContext bpsTarget = DMContexts.getAncestorOfType(dmc, IBreakpointsTargetDMContext.class);
|
||||
if (bpsTarget != null) {
|
||||
MIBreakpointDMContext bkpt = new MIBreakpointDMContext(dmc.getSessionId(), new IDMContext[] {bpsTarget}, bkptno);
|
||||
DsfServicesTracker tracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), dmc.getSessionId());
|
||||
MIBreakpointsManager bkptMgr = tracker.getService(MIBreakpointsManager.class);
|
||||
IBreakpoint platformBkpt = bkptMgr.findPlatformBreakpoint(bkpt);
|
||||
if (platformBkpt instanceof CEventBreakpoint) {
|
||||
try {
|
||||
String eventTypeID = ((CEventBreakpoint)platformBkpt).getEventType();
|
||||
String gdbKeyword = GdbCatchpoints.eventToGdbCatchpointKeyword(eventTypeID);
|
||||
return MICatchpointHitEvent.parse(stoppedEvent.getDMContext(), token, results, bkptno, gdbKeyword);
|
||||
} catch (DebugException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return new MIBreakpointHitEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), bkptno);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ public class MICatchpointHitEvent extends MIBreakpointHitEvent {
|
|||
* Returns the event the cachpoint caught. E.g., a C++ exception was thrown.
|
||||
* This string comes either from gdb when the catchpoint is hit, or it's the
|
||||
* gdb catchpoint keyword ('catch', 'throw', 'fork', etc) that was used to
|
||||
* set the catchpoint (to be done for gdb >= 7.0)
|
||||
* set the catchpoint
|
||||
*/
|
||||
public String getReason() {
|
||||
return fReason;
|
||||
|
@ -40,7 +40,8 @@ public class MICatchpointHitEvent extends MIBreakpointHitEvent {
|
|||
* catchpoint was hit, but what its breakpoint number is.
|
||||
*
|
||||
* @param streamRecord
|
||||
* the stream record that reveals that a catchpoint was hit
|
||||
* the stream record that reveals that a catchpoint was hit and
|
||||
* what the event was
|
||||
*/
|
||||
public static MIBreakpointHitEvent parse(IExecutionDMContext dmc, int token, MIResult[] results, MIStreamRecord streamRecord) {
|
||||
// stream record example: "Catchpoint 1 (exception caught)"
|
||||
|
@ -74,4 +75,19 @@ public class MICatchpointHitEvent extends MIBreakpointHitEvent {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This variant is for a catchpoint-hit in gdb >= 7.0.
|
||||
* {@link MIBreakpointHitEvent#parse(IExecutionDMContext, int, MIResult[], MIStreamRecord[])
|
||||
* delegates to us if it determines that the breakpoint hit was actually
|
||||
* caused by catchpoint. In this case, we use the event keyword used to set
|
||||
* the catchpoint as the reason (e.g., "catch", "throw"), whereas in the gdb
|
||||
* < 7.0 case we use the reason provided in the stream record (e.g.,
|
||||
* "exception caught"). The inconsistency is fine. The user will get the
|
||||
* insight he needs either way.
|
||||
*/
|
||||
public static MICatchpointHitEvent parse(IExecutionDMContext dmc, int token, MIResult[] results, int bkptNumber, String gdbKeyword) {
|
||||
MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(dmc, token, results);
|
||||
return new MICatchpointHitEvent(stoppedEvent.getDMContext(), token, results, stoppedEvent.getFrame(), bkptNumber, gdbKeyword);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue