From c6035901f51647e94f1e80f2199ac24d636a2f2e Mon Sep 17 00:00:00 2001 From: John Cortell Date: Tue, 20 Apr 2010 15:29:57 +0000 Subject: [PATCH] [248587] Fixed reporting of catchpoint hit in gdb >= 7.0 --- .../command/MIRunControlEventProcessor.java | 4 +- .../MIRunControlEventProcessor_7_0.java | 2 + .../command/events/MIBreakpointHitEvent.java | 49 +++++++++++++------ .../command/events/MICatchpointHitEvent.java | 22 +++++++-- 4 files changed, 57 insertions(+), 20 deletions(-) diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/MIRunControlEventProcessor.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/MIRunControlEventProcessor.java index c0631c4e074..e28d9b37478 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/MIRunControlEventProcessor.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/MIRunControlEventProcessor.java @@ -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; @@ -219,7 +220,8 @@ public class MIRunControlEventProcessor * However, gdb also sends a stream record that reveals that it's * a catchpoint hit. * @since 3.0 - */ + */ + @ConfinedToDsfExecutor("") protected MIEvent createEvent(String reason, MIExecAsyncOutput exec, MIStreamRecord[] miStreamRecords) { IExecutionDMContext execDmc = getExecutionContext(exec); MIEvent event = null; diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/MIRunControlEventProcessor_7_0.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/MIRunControlEventProcessor_7_0.java index 51a833bc9c8..ae5b1f5593b 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/MIRunControlEventProcessor_7_0.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/MIRunControlEventProcessor_7_0.java @@ -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; diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/events/MIBreakpointHitEvent.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/events/MIBreakpointHitEvent.java index e83ee142b9f..9e6b5c5f0ea 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/events/MIBreakpointHitEvent.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/events/MIBreakpointHitEvent.java @@ -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++) { @@ -66,24 +78,29 @@ public class MIBreakpointHitEvent extends MIStoppedEvent { } } } - MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(dmc, token, results); - + MIStoppedEvent stoppedEvent = MIStoppedEvent.parse(dmc, token, results); + // 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); } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/events/MICatchpointHitEvent.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/events/MICatchpointHitEvent.java index 7f07a31340e..23c44bc57a4 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/events/MICatchpointHitEvent.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/events/MICatchpointHitEvent.java @@ -27,12 +27,12 @@ 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; } - + /** * This variant is for catchpoint-hit in gdb < 7.0. For those versions, gdb * sends us a stopped event, but it doesn't include a reason in it. @@ -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); + } }