From c652147479958856d114ce74e7eb8e46c9b6b2c2 Mon Sep 17 00:00:00 2001 From: Alena Laskavaia Date: Fri, 25 Apr 2008 16:06:06 +0000 Subject: [PATCH] bug 226689 - catchpoint support --- .../cdi/model/ICDIBreakpointManagement3.java | 27 +++ .../debug/core/cdi/model/ICDICatchpoint.java | 31 +++ .../plugin.properties | 1 + debug/org.eclipse.cdt.debug.core/plugin.xml | 22 +++ .../eclipse/cdt/debug/core/CDIDebugModel.java | 44 ++++- .../cdt/debug/core/model/ICCatchpoint.java | 55 ++++++ .../internal/core/CBreakpointManager.java | 67 +++++++ .../core/breakpoints/CCatchpoint.java | 84 ++++++++ .../debug/mi/core/cdi/BreakpointManager.java | 187 ++++++++++++++---- .../mi/core/cdi/SharedLibraryManager.java | 3 + .../debug/mi/core/cdi/model/Catchpoint.java | 88 +++++++++ .../cdt/debug/mi/core/cdi/model/Target.java | 11 +- .../cdt/debug/mi/core/CLIProcessor.java | 6 +- .../cdt/debug/mi/core/command/CLICatch.java | 47 +++++ .../debug/mi/core/command/CommandFactory.java | 6 +- .../core/event/MIBreakpointChangedEvent.java | 1 + .../debug/mi/core/output/CLICatchInfo.java | 72 +++++++ .../plugin.properties | 6 + debug/org.eclipse.cdt.debug.mi.ui/plugin.xml | 15 ++ 19 files changed, 726 insertions(+), 47 deletions(-) create mode 100644 debug/org.eclipse.cdt.debug.core/cdi/org/eclipse/cdt/debug/core/cdi/model/ICDIBreakpointManagement3.java create mode 100644 debug/org.eclipse.cdt.debug.core/cdi/org/eclipse/cdt/debug/core/cdi/model/ICDICatchpoint.java create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICCatchpoint.java create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CCatchpoint.java create mode 100644 debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/Catchpoint.java create mode 100644 debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/CLICatch.java create mode 100644 debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/output/CLICatchInfo.java diff --git a/debug/org.eclipse.cdt.debug.core/cdi/org/eclipse/cdt/debug/core/cdi/model/ICDIBreakpointManagement3.java b/debug/org.eclipse.cdt.debug.core/cdi/org/eclipse/cdt/debug/core/cdi/model/ICDIBreakpointManagement3.java new file mode 100644 index 00000000000..f50b54148d2 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/cdi/org/eclipse/cdt/debug/core/cdi/model/ICDIBreakpointManagement3.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2008 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * QNX Software Systems - catchpoints - bug 226689 + *******************************************************************************/ +package org.eclipse.cdt.debug.core.cdi.model; + +import org.eclipse.cdt.debug.core.cdi.CDIException; +import org.eclipse.cdt.debug.core.cdi.ICDICondition; + +public interface ICDIBreakpointManagement3 extends ICDIBreakpointManagement2{ + /** + * Set a catchpoint + * @param type - catchpoint type, interpreted by backend + * @param arg - extra argument, for example signal number + * @param cdiBreakpointType - cdi breakpoint type, just in case some inferiors support "hardware" catchpoints + */ + ICDICatchpoint setCatchpoint(String type, String arg, int cdiBreakpointType, + ICDICondition condition, boolean deferred, boolean enabled) throws CDIException; +} diff --git a/debug/org.eclipse.cdt.debug.core/cdi/org/eclipse/cdt/debug/core/cdi/model/ICDICatchpoint.java b/debug/org.eclipse.cdt.debug.core/cdi/org/eclipse/cdt/debug/core/cdi/model/ICDICatchpoint.java new file mode 100644 index 00000000000..b90974d0bfc --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/cdi/org/eclipse/cdt/debug/core/cdi/model/ICDICatchpoint.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2008 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * QNX Software Systems - catchpoints - bug 226689 + *******************************************************************************/ +package org.eclipse.cdt.debug.core.cdi.model; + +import org.eclipse.core.runtime.CoreException; + +public interface ICDICatchpoint extends ICDIBreakpoint { + /** + * Get catchpoint type. This is usually id in reverse web notation. + * @return catchpoint type id + * @throws CoreException + */ + String getEventType() throws CoreException; + + /** + * Get extra event argument. For example name of the exception or number of a signal. + * @return event argument + * @throws CoreException + */ + String getExtraArgument() throws CoreException; +} diff --git a/debug/org.eclipse.cdt.debug.core/plugin.properties b/debug/org.eclipse.cdt.debug.core/plugin.properties index 84121e1d1ac..c8b52e7165d 100644 --- a/debug/org.eclipse.cdt.debug.core/plugin.properties +++ b/debug/org.eclipse.cdt.debug.core/plugin.properties @@ -21,6 +21,7 @@ cLineBreakpoints.name=C/C++ Line Breakpoints cAddressBreakpoints.name=C/C++ Address Breakpoints cFunctionBreakpoints.name=C/C++ Function Breakpoints cWatchpoints.name=C/C++ Watchpoints +cCatchpoints.name=C/C++ Event Breakpoints breakpointProblem.name=C/C++ Breakpoint Problem containerName.mapping=Path Mapping diff --git a/debug/org.eclipse.cdt.debug.core/plugin.xml b/debug/org.eclipse.cdt.debug.core/plugin.xml index 0ce2a273de2..f320967af0b 100644 --- a/debug/org.eclipse.cdt.debug.core/plugin.xml +++ b/debug/org.eclipse.cdt.debug.core/plugin.xml @@ -104,6 +104,22 @@ + + + + + + + + + + + + diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDIDebugModel.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDIDebugModel.java index e3bda5fcb80..7a97d3033a8 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDIDebugModel.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDIDebugModel.java @@ -8,12 +8,15 @@ * Contributors: * QNX Software Systems - Initial API and implementation * Freescale Semiconductor - Address watchpoints, https://bugs.eclipse.org/bugs/show_bug.cgi?id=118299 + * QNX Software Systems - catchpoints - bug 226689 *******************************************************************************/ package org.eclipse.cdt.debug.core; import java.io.IOException; import java.math.BigInteger; import java.util.HashMap; +import java.util.Map; + import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.core.IBinaryParser; @@ -24,11 +27,13 @@ import org.eclipse.cdt.core.IBinaryParser.IBinaryObject; import org.eclipse.cdt.debug.core.cdi.model.ICDITarget; import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint; import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.cdt.debug.core.model.ICCatchpoint; import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; -import org.eclipse.cdt.debug.core.model.ICWatchpoint2; import org.eclipse.cdt.debug.core.model.ICWatchpoint; +import org.eclipse.cdt.debug.core.model.ICWatchpoint2; import org.eclipse.cdt.debug.internal.core.breakpoints.CAddressBreakpoint; +import org.eclipse.cdt.debug.internal.core.breakpoints.CCatchpoint; import org.eclipse.cdt.debug.internal.core.breakpoints.CFunctionBreakpoint; import org.eclipse.cdt.debug.internal.core.breakpoints.CLineBreakpoint; import org.eclipse.cdt.debug.internal.core.breakpoints.CWatchpoint; @@ -583,4 +588,41 @@ public class CDIDebugModel { // If handles are not file names ???? return handle1.equals( handle2 ); } + + public static ICCatchpoint catchpointExists(String type, String arg ) throws CoreException { + String modelId = getPluginIdentifier(); + + IBreakpointManager manager = DebugPlugin.getDefault().getBreakpointManager(); + IBreakpoint[] breakpoints = manager.getBreakpoints(modelId); + for (int i = 0; i < breakpoints.length; i++) { + if (!(breakpoints[i] instanceof ICCatchpoint)) { + continue; + } + ICCatchpoint breakpoint = (ICCatchpoint) breakpoints[i]; + + if (breakpoint.getEventType().equals(type)) { + String arg1 = breakpoint.getEventArgument(); + if (arg1 == null) + arg1 = ""; + String arg2 = arg == null ? "" : arg; + if (arg1.equals(arg2)) + return breakpoint; + } + + } + return null; + } + public static ICCatchpoint createCatchpoint(String type, String arg, boolean register) + throws CoreException { + final IResource resource = ResourcesPlugin.getWorkspace().getRoot(); + final Map attributes = new HashMap(); + attributes.put(IBreakpoint.ID, CDIDebugModel.getPluginIdentifier()); + attributes.put(IBreakpoint.ENABLED, true); + attributes.put(ICBreakpoint.IGNORE_COUNT, 0); + attributes.put(ICBreakpoint.CONDITION, ""); + attributes.put(ICCatchpoint.EVENT_TYPE_ID, type); + attributes.put(ICCatchpoint.EVENT_ARG, arg); + return new CCatchpoint(resource, attributes, register); + + } } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICCatchpoint.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICCatchpoint.java new file mode 100644 index 00000000000..bb1bd5c70f6 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICCatchpoint.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2008 QNX Software 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: + * QNX Software Systems - Initial API and implementation +* QNX Software Systems - catchpoints - bug 226689 + *******************************************************************************/ +package org.eclipse.cdt.debug.core.model; + +import org.eclipse.core.runtime.CoreException; + +/** + * Interface for debugger catchpoints (event breakpoints). Example of catchpoint + * is break on raising exception in C++, or break on receiving signal. + * + * @sinse 5.0 + */ +public interface ICCatchpoint extends ICBreakpoint { + /** + * Breakpoint attribute storing the catchpoint event id + * is set in (value "org.eclipse.cdt.debug.core.catchpoint.event_id"). + * This attribute is a String. + * + */ + public static final String EVENT_TYPE_ID = "org.eclipse.cdt.debug.core.catchpoint_event_id"; //$NON-NLS-1$ + /** + * Breakpoint attribute storing the catchpoint event argument + * is set in (value "org.eclipse.cdt.debug.core.catchpoint.event_arg"). + * This attribute is a String. + * + */ + public static final String EVENT_ARG = "org.eclipse.cdt.debug.core.catchpoint_event_arg"; //$NON-NLS-1$ + + /** + * Get catchpoint type. This is usually id in reverse web notation. + * This type is interpreted by underlying debugger implementation. + * Use extension point org.eclipse.cdt.debug.ui.breakpointContribution to define user visible label for this event type. + * @return catchpoint type id (not null) + * @throws CoreException + */ + String getEventType() throws CoreException; + + /** + * Get extra event argument. For example name of the exception or number of a signal. + * Use extension point org.eclipse.cdt.debug.ui.breakpointContribution to define UI control to edit/view this argument + * @return event argument (not null) + * @throws CoreException + */ + String getEventArgument() throws CoreException; +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CBreakpointManager.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CBreakpointManager.java index a1e4dfc7a7d..b325a5d7a0b 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CBreakpointManager.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CBreakpointManager.java @@ -11,6 +11,7 @@ * Ken Ryall (Nokia) - bugs 170027, 105196 * Ling Wang (Nokia) - bug 176081 * Freescale Semiconductor - Address watchpoints, https://bugs.eclipse.org/bugs/show_bug.cgi?id=118299 + * QNX Software Systems - catchpoints - bug 226689 *******************************************************************************/ package org.eclipse.cdt.debug.internal.core; @@ -49,6 +50,8 @@ import org.eclipse.cdt.debug.core.cdi.event.ICDIExecutableReloadedEvent; import org.eclipse.cdt.debug.core.cdi.model.ICDIAddressBreakpoint; import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpoint; import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpointManagement2; +import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpointManagement3; +import org.eclipse.cdt.debug.core.cdi.model.ICDICatchpoint; import org.eclipse.cdt.debug.core.cdi.model.ICDIFunctionBreakpoint; import org.eclipse.cdt.debug.core.cdi.model.ICDILineBreakpoint; import org.eclipse.cdt.debug.core.cdi.model.ICDILocationBreakpoint; @@ -61,6 +64,7 @@ import org.eclipse.cdt.debug.core.cdi.model.ICDIWatchpoint2; import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint; import org.eclipse.cdt.debug.core.model.ICBreakpoint; import org.eclipse.cdt.debug.core.model.ICBreakpointFilterExtension; +import org.eclipse.cdt.debug.core.model.ICCatchpoint; import org.eclipse.cdt.debug.core.model.ICDebugTarget; import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; @@ -251,6 +255,12 @@ public class CBreakpointManager implements IBreakpointsListener, IBreakpointMana catch( CDIException e ) { } } + if ( breakpoint instanceof ICCatchpoint && cdiBreakpoint instanceof ICDICatchpoint) { + ICCatchpoint mcatchpoint = (ICCatchpoint) breakpoint; + ICDICatchpoint cdicatchpoint = (ICDICatchpoint) cdiBreakpoint; + if (!mcatchpoint.getEventType().equals(cdicatchpoint.getEventType())) return false; + return (mcatchpoint.getEventArgument().equals(cdicatchpoint.getExtraArgument())); + } } catch( CoreException e ) { } @@ -451,6 +461,8 @@ public class CBreakpointManager implements IBreakpointsListener, IBreakpointMana private void handleBreakpointCreatedEvent( ICDIBreakpoint cdiBreakpoint ) { if ( cdiBreakpoint instanceof ICDIWatchpoint ) doHandleWatchpointCreatedEvent( (ICDIWatchpoint)cdiBreakpoint ); + if ( cdiBreakpoint instanceof ICDICatchpoint ) + doHandleCatachpointCreatedEvent( (ICDICatchpoint)cdiBreakpoint ); else if ( cdiBreakpoint instanceof ICDILocationBreakpoint ) doHandleLocationBreakpointCreatedEvent( (ICDILocationBreakpoint)cdiBreakpoint ); if ( !cdiBreakpoint.isTemporary() && !DebugPlugin.getDefault().getBreakpointManager().isEnabled() ) { @@ -458,6 +470,37 @@ public class CBreakpointManager implements IBreakpointsListener, IBreakpointMana } } + private void doHandleCatachpointCreatedEvent(ICDICatchpoint cdiCatchpoint) { + ICBreakpoint breakpoint = null; + synchronized( getBreakpointMap() ) { + breakpoint = getBreakpointMap().getCBreakpoint( cdiCatchpoint ); + if ( breakpoint == null ) { + try { + breakpoint = createCatchpoint( cdiCatchpoint ); + } + catch( CDIException e ) { + } + catch( CoreException e ) { + } + } + if ( breakpoint != null ) + getBreakpointMap().put( breakpoint, cdiCatchpoint ); + } + + if ( breakpoint != null ) { + try { + ICBreakpointFilterExtension filterExtension = getFilterExtension(breakpoint); + if (filterExtension!=null) filterExtension.setTargetFilter( getDebugTarget() ); + ((CBreakpoint)breakpoint).register( true ); + } + catch( CoreException e ) { + } + getBreakpointNotifier().breakpointInstalled( getDebugTarget(), breakpoint ); + changeBreakpointProperties( breakpoint, cdiCatchpoint ); + } + + } + private void doHandleLocationBreakpointCreatedEvent( ICDILocationBreakpoint cdiBreakpoint ) { if ( cdiBreakpoint.isTemporary() ) return; @@ -778,6 +821,17 @@ public class CBreakpointManager implements IBreakpointsListener, IBreakpointMana } else { b = cdiTarget.setWatchpoint( ICDIBreakpoint.REGULAR, accessType, expression, condition ); } + } else if (breakpoints[i] instanceof ICCatchpoint) { + ICCatchpoint catchpoint = (ICCatchpoint) breakpoints[i]; + ICDICondition condition = createCondition(catchpoint); + if (cdiTarget instanceof ICDIBreakpointManagement3) { + ICDIBreakpointManagement3 bpManager3 = (ICDIBreakpointManagement3) cdiTarget; + b = bpManager3.setCatchpoint(catchpoint.getEventType(), catchpoint + .getEventArgument(), ICDIBreakpoint.REGULAR, condition, true, breakpoints[i].isEnabled()); + } else { + throw new UnsupportedOperationException("BreakpointManager does not support this type of breapoints"); + } + } if ( b != null ) { Object obj = getBreakpointMap().get( breakpoints[i] ); @@ -953,6 +1007,19 @@ public class CBreakpointManager implements IBreakpointsListener, IBreakpointMana } return watchpoint; } + + private ICCatchpoint createCatchpoint(ICDICatchpoint cdiCatchpoint) throws CDIException, + CoreException { + + ICCatchpoint catchpoint; + catchpoint = CDIDebugModel.catchpointExists(cdiCatchpoint.getEventType(), cdiCatchpoint + .getExtraArgument()); + if (catchpoint != null) + return catchpoint; + catchpoint = CDIDebugModel.createCatchpoint(cdiCatchpoint.getEventType(), cdiCatchpoint + .getExtraArgument(), false); + return catchpoint; + } private void changeBreakpointProperties( ICBreakpoint breakpoint, IMarkerDelta delta ) { ICDIBreakpoint cdiBreakpoint = null; diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CCatchpoint.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CCatchpoint.java new file mode 100644 index 00000000000..dd940ef301b --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CCatchpoint.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2008 QNX Software 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: + * QNX Software Systems - Initial API and implementation + * QNX Software Systems - catchpoints - bug 226689 + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.core.breakpoints; + +import java.util.Map; + +import org.eclipse.cdt.debug.core.model.ICCatchpoint; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.DebugException; + +public class CCatchpoint extends CBreakpoint implements ICCatchpoint { + + private static final String C_CATCHPOINT_MARKER_TYPE = "org.eclipse.cdt.debug.core.cCatchpointMarker"; //$NON-NLS-1$; + + public CCatchpoint() { + + } + + public static String getMarkerType() { + return C_CATCHPOINT_MARKER_TYPE; + } + + public CCatchpoint(IResource resource, Map attributes, boolean add) throws CoreException { + this(); + // catchpoint must set non null EVENT_TYPE_ID property to be valid + if (attributes.get(EVENT_TYPE_ID) == null) + throw new IllegalArgumentException(); + setBreakpointMarker(resource, getMarkerType(), attributes, add); + + } + + private void setBreakpointMarker(final IResource resource, final String markerType, + final Map attributes, final boolean add) throws DebugException { + IWorkspaceRunnable wr = new IWorkspaceRunnable() { + + public void run(IProgressMonitor monitor) throws CoreException { + // create the marker + setMarker(resource.createMarker(markerType)); + // set attributes + ensureMarker().setAttributes(attributes); + // set the marker message + setAttribute(IMarker.MESSAGE, getMarkerMessage()); + // add to breakpoint manager if requested + register(add); + } + }; + run(wr); + } + + @Override + protected String getMarkerMessage() throws CoreException { + // default message, overridden by label provider, which would take care of translation + return "Event Breakpoint: " + getEventType(); // $NON-NLS-1$ + } + + /** + * @see ICCatchpoint#getEventType() + */ + public String getEventType() throws DebugException { + return ensureMarker().getAttribute(EVENT_TYPE_ID, ""); //$NON-NLS-1$ + } + + /** + * @see ICCatchpoint#getEventArgument() + */ + public String getEventArgument() throws CoreException { + return (String) ensureMarker().getAttribute(EVENT_ARG, ""); + } + +} diff --git a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/BreakpointManager.java b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/BreakpointManager.java index b587cc519bd..837fd7d149e 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/BreakpointManager.java +++ b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/BreakpointManager.java @@ -28,16 +28,19 @@ import org.eclipse.cdt.debug.core.cdi.ICDILineLocation; import org.eclipse.cdt.debug.core.cdi.ICDILocator; import org.eclipse.cdt.debug.core.cdi.model.ICDIAddressBreakpoint; import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpoint; +import org.eclipse.cdt.debug.core.cdi.model.ICDICatchpoint; import org.eclipse.cdt.debug.core.cdi.model.ICDIExceptionpoint; import org.eclipse.cdt.debug.core.cdi.model.ICDIFunctionBreakpoint; import org.eclipse.cdt.debug.core.cdi.model.ICDILineBreakpoint; import org.eclipse.cdt.debug.core.cdi.model.ICDIWatchpoint; import org.eclipse.cdt.debug.mi.core.MIException; import org.eclipse.cdt.debug.mi.core.MIFormat; +import org.eclipse.cdt.debug.mi.core.MIPlugin; import org.eclipse.cdt.debug.mi.core.MISession; import org.eclipse.cdt.debug.mi.core.cdi.model.AddressBreakpoint; import org.eclipse.cdt.debug.mi.core.cdi.model.AddressLocation; import org.eclipse.cdt.debug.mi.core.cdi.model.Breakpoint; +import org.eclipse.cdt.debug.mi.core.cdi.model.Catchpoint; import org.eclipse.cdt.debug.mi.core.cdi.model.Exceptionpoint; import org.eclipse.cdt.debug.mi.core.cdi.model.FunctionBreakpoint; import org.eclipse.cdt.debug.mi.core.cdi.model.FunctionLocation; @@ -45,6 +48,7 @@ import org.eclipse.cdt.debug.mi.core.cdi.model.LineBreakpoint; import org.eclipse.cdt.debug.mi.core.cdi.model.LocationBreakpoint; import org.eclipse.cdt.debug.mi.core.cdi.model.Target; import org.eclipse.cdt.debug.mi.core.cdi.model.Watchpoint; +import org.eclipse.cdt.debug.mi.core.command.CLICatch; import org.eclipse.cdt.debug.mi.core.command.CommandFactory; import org.eclipse.cdt.debug.mi.core.command.MIBreakAfter; import org.eclipse.cdt.debug.mi.core.command.MIBreakCondition; @@ -59,6 +63,7 @@ import org.eclipse.cdt.debug.mi.core.event.MIBreakpointChangedEvent; import org.eclipse.cdt.debug.mi.core.event.MIBreakpointCreatedEvent; import org.eclipse.cdt.debug.mi.core.event.MIBreakpointDeletedEvent; import org.eclipse.cdt.debug.mi.core.event.MIEvent; +import org.eclipse.cdt.debug.mi.core.output.CLICatchInfo; import org.eclipse.cdt.debug.mi.core.output.MIBreakInsertInfo; import org.eclipse.cdt.debug.mi.core.output.MIBreakListInfo; import org.eclipse.cdt.debug.mi.core.output.MIBreakWatchInfo; @@ -395,20 +400,21 @@ public class BreakpointManager extends Manager { List bList = getBreakpointsList(target); List eventList = new ArrayList(allMIBreakpoints.length); for (int i = 0; i < allMIBreakpoints.length; i++) { - int no = allMIBreakpoints[i].getNumber(); + MIBreakpoint miBreakpoint = allMIBreakpoints[i]; + int no = miBreakpoint.getNumber(); Breakpoint bp = getBreakpoint(target, no); if (bp != null) { MIBreakpoint[] miBps = bp.getMIBreakpoints(); for (int j = 0; j < miBps.length; j++) { if (miBps[j].getNumber() == no) { - if (hasBreakpointChanged(miBps[j], allMIBreakpoints[i])) { - miBps[j] = allMIBreakpoints[i]; - bp.setEnabled0(allMIBreakpoints[i].isEnabled()); + if (hasBreakpointChanged(miBps[j], miBreakpoint)) { + miBps[j] = miBreakpoint; + bp.setEnabled0(miBreakpoint.isEnabled()); // FIXME: We have a problem if the thread id change. ICDICondition oldCond = bp.getCondition(); String[] tids = oldCond.getThreadIds(); - Condition newCondition = new Condition(allMIBreakpoints[i].getIgnoreCount(), - allMIBreakpoints[i].getCondition(), tids); + Condition newCondition = new Condition(miBreakpoint.getIgnoreCount(), + miBreakpoint.getCondition(), tids); bp.setCondition0(newCondition); // Fire ChangedEvent eventList.add(new MIBreakpointChangedEvent(miSession, no)); @@ -418,60 +424,67 @@ public class BreakpointManager extends Manager { } else { // add the new breakpoint and fire CreatedEvent int type = ICDIBreakpoint.REGULAR; - if (allMIBreakpoints[i].isHardware()) { + if (miBreakpoint.isHardware()) { type = ICDIBreakpoint.HARDWARE; - } else if (allMIBreakpoints[i].isTemporary()) { + } else if (miBreakpoint.isTemporary()) { type = ICDIBreakpoint.TEMPORARY; } String[] tids = null; - String tid = allMIBreakpoints[i].getThreadId(); + String tid = miBreakpoint.getThreadId(); if (tid != null && tid.length() > 0) { tids = new String[] { tid }; } - Condition condition = new Condition(allMIBreakpoints[i].getIgnoreCount(), - allMIBreakpoints[i].getCondition(), tids); + Condition condition = new Condition(miBreakpoint.getIgnoreCount(), + miBreakpoint.getCondition(), tids); - if (allMIBreakpoints[i].isWatchpoint()) { + if (miBreakpoint.isWatchpoint()) { int watchType = 0; - if (allMIBreakpoints[i].isAccessWatchpoint() || allMIBreakpoints[i].isReadWatchpoint()) { + if (miBreakpoint.isAccessWatchpoint() || miBreakpoint.isReadWatchpoint()) { watchType |= ICDIWatchpoint.READ; } - if (allMIBreakpoints[i].isAccessWatchpoint() || allMIBreakpoints[i].isWriteWatchpoint()) { + if (miBreakpoint.isAccessWatchpoint() || miBreakpoint.isWriteWatchpoint()) { watchType |= ICDIWatchpoint.WRITE; } - Watchpoint wpoint = new Watchpoint(target, allMIBreakpoints[i].getWhat(), type, watchType, condition, allMIBreakpoints[i].isEnabled()); - wpoint.setMIBreakpoints(new MIBreakpoint[] {allMIBreakpoints[i]}); + Watchpoint wpoint = new Watchpoint(target, miBreakpoint.getWhat(), type, watchType, condition, miBreakpoint.isEnabled()); + wpoint.setMIBreakpoints(new MIBreakpoint[] {miBreakpoint}); bList.add(wpoint); } else { int hint = MIBreakpointChangedEvent.HINT_NONE; if (event instanceof MIBreakpointChangedEvent) { hint = ((MIBreakpointChangedEvent)event).getHint(); } - String function = allMIBreakpoints[i].getFunction(); - String file = allMIBreakpoints[i].getFile(); - int line = allMIBreakpoints[i].getLine(); - String addr = allMIBreakpoints[i].getAddress(); - boolean enabled = allMIBreakpoints[i].isEnabled(); + String function = miBreakpoint.getFunction(); + String file = miBreakpoint.getFile(); + int line = miBreakpoint.getLine(); + String addr = miBreakpoint.getAddress(); + boolean enabled = miBreakpoint.isEnabled(); + Breakpoint newBreakpoint = null; if (hint == MIBreakpointChangedEvent.HINT_NEW_LINE_BREAKPOINT || (hint == MIBreakpointChangedEvent.HINT_NONE && file != null && file.length() > 0 && line > 0)) { - LineLocation location = createLineLocation (allMIBreakpoints[i].getFile(), - allMIBreakpoints[i].getLine()); - Breakpoint newBreakpoint = new LineBreakpoint(target, type, location, condition, enabled); - newBreakpoint.setMIBreakpoints(new MIBreakpoint[] {allMIBreakpoints[i]}); - bList.add(newBreakpoint); - } else if (hint == MIBreakpointChangedEvent.HINT_NEW_FUNCTION_BREAKPOINT || - (hint == MIBreakpointChangedEvent.HINT_NONE && function != null && function.length() > 0)) { + LineLocation location = createLineLocation (miBreakpoint.getFile(), + miBreakpoint.getLine()); + newBreakpoint = new LineBreakpoint(target, type, location, condition, enabled); + } else if ((hint == MIBreakpointChangedEvent.HINT_NEW_FUNCTION_BREAKPOINT || + hint == MIBreakpointChangedEvent.HINT_NONE) && function != null && function.length() > 0) { FunctionLocation location = createFunctionLocation(file, function); - Breakpoint newBreakpoint = new FunctionBreakpoint(target, type, location, condition, enabled); - newBreakpoint.setMIBreakpoints(new MIBreakpoint[] {allMIBreakpoints[i]}); - bList.add(newBreakpoint); - } else if (hint == MIBreakpointChangedEvent.HINT_NEW_ADDRESS_BREAKPOINT || - (hint == MIBreakpointChangedEvent.HINT_NONE && addr != null && addr.length() > 0)) { + newBreakpoint = new FunctionBreakpoint(target, type, location, condition, enabled); + } else if (hint == MIBreakpointChangedEvent.HINT_NEW_CATCHPOINT || Catchpoint.getEventArgumentFromMI(miBreakpoint)!=null) { + String ctype = Catchpoint.getEventTypeFromMI(miBreakpoint); + if (ctype != null) { + newBreakpoint = new Catchpoint(target, ctype, Catchpoint + .getEventArgumentFromMI(miBreakpoint), condition, enabled); + } else { + MIPlugin.log("Unsupported catchpoint: "+miBreakpoint.getWhat()); //$NON-NLS-1$ log entry not for users + } + } else if (addr != null && addr.length() > 0) { BigInteger big = MIFormat.getBigInteger(addr); - AddressLocation location = createAddressLocation (big); - Breakpoint newBreakpoint = new AddressBreakpoint(target, type, location, condition, enabled); - newBreakpoint.setMIBreakpoints(new MIBreakpoint[] {allMIBreakpoints[i]}); + AddressLocation location = createAddressLocation(big); + newBreakpoint = new AddressBreakpoint(target, type, location, condition, + enabled); + } + if (newBreakpoint != null) { + newBreakpoint.setMIBreakpoints(new MIBreakpoint[] { miBreakpoint }); bList.add(newBreakpoint); } } @@ -670,18 +683,23 @@ public class BreakpointManager extends Manager { Session session = (Session)target.getSession(); SharedLibraryManager sharedMgr = session.getSharedLibraryManager(); if (sharedMgr.isDeferredBreakpoint(target)) { - List dList = (List)deferredMap.get(target); - if (dList == null) { - dList = Collections.synchronizedList(new ArrayList()); - deferredMap.put(target, dList); - } - dList.add(bkpt); + addDeferredBreakpoint(bkpt); } else { throw e; } } } + private void addDeferredBreakpoint(Breakpoint breakpoint) { + Target target = (Target)breakpoint.getTarget(); + List dList = (List)deferredMap.get(target); + if (dList == null) { + dList = Collections.synchronizedList(new ArrayList()); + deferredMap.put(target, dList); + } + dList.add(breakpoint); + } + public void setLocationBreakpoint (LocationBreakpoint bkpt) throws CDIException { Target target = (Target)bkpt.getTarget(); MISession miSession = target.getMISession(); @@ -1024,4 +1042,89 @@ public class BreakpointManager extends Manager { } return miBreakInserts; } + public ICDICatchpoint setCatchpoint(Target target, String type, String arg, ICDICondition condition, boolean enabled) throws CDIException { + Catchpoint catchpoint = new Catchpoint(target,type,arg,condition,enabled); + setCatchpoint(catchpoint); + return catchpoint; + } + public void setCatchpoint(Catchpoint catchpoint) throws CDIException { + Target target = (Target) catchpoint.getTarget(); + + MISession miSession = target.getMISession(); + CommandFactory factory = miSession.getCommandFactory(); + CLICatch breakCatch = factory.createCLICatch(catchpoint.getGdbEvent(), catchpoint + .getGdbArg()); + + catchpoint.setMIBreakpoints(new MIBreakpoint[0]); // initialize + boolean restart = false; + try { + restart = suspendInferior(target); + miSession.postCommand(breakCatch); + int no; + try { + CLICatchInfo cinfo = (CLICatchInfo) breakCatch.getMIInfo(); + if (cinfo == null) { + throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$ + } + MIBreakpoint[] points = cinfo.getMIBreakpoints(); + if (points == null || points.length == 0) { + throw new CDIException(CdiResources + .getString("cdi.BreakpointManager.Parsing_Error")); //$NON-NLS-1$ + } + no = points[0].getNumber(); + catchpoint.setMIBreakpoints(points); + } catch (MIException e) { + if (!catchpoint.isDeferred()) { + throw e; + } + addDeferredBreakpoint(catchpoint); + return; + } + + // Put the condition now. + String exprCond = null; + int ignoreCount = 0; + + ICDICondition condition = catchpoint.getCondition(); + if (condition != null) { + exprCond = condition.getExpression(); + ignoreCount = condition.getIgnoreCount(); + } + if (exprCond != null && exprCond.length() > 0) { + MIBreakCondition breakCondition = factory.createMIBreakCondition(no, exprCond); + miSession.postCommand(breakCondition); + MIInfo info = breakCondition.getMIInfo(); + if (info == null) { + throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$ + } + } + if (ignoreCount > 0) { + MIBreakAfter breakAfter = factory.createMIBreakAfter(no, ignoreCount); + miSession.postCommand(breakAfter); + MIInfo info = breakAfter.getMIInfo(); + if (info == null) { + throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$ + } + } + // how to deal with threads ??? + } catch (MIException e) { + throw new MI2CDIException(e); + } finally { + resumeInferior(target, restart); + } + + + + List bList = getBreakpointsList(target); + bList.add(catchpoint); + + // Fire a created Event. + MIBreakpoint[] miBreakpoints = catchpoint.getMIBreakpoints(); + if (miBreakpoints != null && miBreakpoints.length > 0) { + miSession.fireEvent(new MIBreakpointCreatedEvent(miSession, miBreakpoints[0] + .getNumber())); + } + + + } } diff --git a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/SharedLibraryManager.java b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/SharedLibraryManager.java index 8caea0eae89..c2a6ff1e142 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/SharedLibraryManager.java +++ b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/SharedLibraryManager.java @@ -31,6 +31,7 @@ import org.eclipse.cdt.debug.mi.core.MIPlugin; import org.eclipse.cdt.debug.mi.core.MISession; import org.eclipse.cdt.debug.mi.core.RxThread; import org.eclipse.cdt.debug.mi.core.cdi.model.Breakpoint; +import org.eclipse.cdt.debug.mi.core.cdi.model.Catchpoint; import org.eclipse.cdt.debug.mi.core.cdi.model.LocationBreakpoint; import org.eclipse.cdt.debug.mi.core.cdi.model.SharedLibrary; import org.eclipse.cdt.debug.mi.core.cdi.model.Target; @@ -151,6 +152,8 @@ public class SharedLibraryManager extends Manager { bpMgr.setLocationBreakpoint((LocationBreakpoint)bkpt); } else if (bkpt instanceof Watchpoint) { bpMgr.setWatchpoint((Watchpoint)bkpt); + } else if (bkpt instanceof Catchpoint) { + bpMgr.setCatchpoint((Catchpoint)bkpt); } else { throw new CDIException(); } diff --git a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/Catchpoint.java b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/Catchpoint.java new file mode 100644 index 00000000000..bac2080bfa7 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/Catchpoint.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.mi.core.cdi.model; + +import java.util.Arrays; + +import org.eclipse.cdt.debug.core.cdi.ICDICondition; +import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpoint; +import org.eclipse.cdt.debug.core.cdi.model.ICDICatchpoint; +import org.eclipse.cdt.debug.mi.core.output.MIBreakpoint; + +public class Catchpoint extends Breakpoint implements ICDICatchpoint { + + public static final String CATCH = "org.eclipse.cdt.debug.gdb.catch"; + public static final String THROW = "org.eclipse.cdt.debug.gdb.throw"; + public static final String SIGNAL_CATCH = "org.eclipse.cdt.debug.gdb.signal"; + private String eventType; + private String arg; + + public Catchpoint(Target target, String event, String arg, ICDICondition cond, boolean enabled) { + super(target, ICDIBreakpoint.REGULAR, cond, enabled); + this.eventType = event; + this.arg = arg==null?"":arg; + } + + public String getEventType() { + return eventType; + } + + public String getExtraArgument() { + return arg; + } + + + public String getGdbEvent() { + if (getEventType().equals(CATCH)) return "catch"; + if (getEventType().equals(THROW)) return "throw"; + if (getEventType().equals(SIGNAL_CATCH)) return "signal"; + return "unknown"; + } + + public String getGdbArg() { + return getExtraArgument(); + } + + @Override + public int hashCode() { + return eventType.hashCode(); + } + @Override + public boolean equals(Object arg0) { + if (this == arg0) return true; + if (!(arg0 instanceof Catchpoint)) return false; + MIBreakpoint[] breakpoints = getMIBreakpoints(); + if (breakpoints==null || breakpoints.length==0) { + return super.equals(arg0); + } + return Arrays.equals(breakpoints, ((Catchpoint)arg0).getMIBreakpoints()); + } + /** + * Returns event type by using miBreakpoint parameters + * @param miBreakpoint + * @return null if unknown type, null cannot be used to create valid Catchpoint + */ + public static String getEventTypeFromMI(MIBreakpoint miBreakpoint) { + if (miBreakpoint.getWhat().equals("exception catch")) { + return + Catchpoint.CATCH; + } else if (miBreakpoint.getWhat().equals("exception throw")) { + return Catchpoint.THROW; + } + return null; // not known/supported + } + + public static String getEventArgumentFromMI(MIBreakpoint miBreakpoint) { + // need a working gdb command command that support catch event argument test test + return ""; + } + +} diff --git a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/Target.java b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/Target.java index b9d2debd4bb..2bcaa30e6dd 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/Target.java +++ b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/Target.java @@ -28,7 +28,8 @@ import org.eclipse.cdt.debug.core.cdi.ICDILocation; import org.eclipse.cdt.debug.core.cdi.model.ICDIAddressBreakpoint; import org.eclipse.cdt.debug.core.cdi.model.ICDIAddressToSource; import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpoint; -import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpointManagement2; +import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpointManagement3; +import org.eclipse.cdt.debug.core.cdi.model.ICDICatchpoint; import org.eclipse.cdt.debug.core.cdi.model.ICDIExceptionpoint; import org.eclipse.cdt.debug.core.cdi.model.ICDIExpression; import org.eclipse.cdt.debug.core.cdi.model.ICDIFunctionBreakpoint; @@ -99,7 +100,7 @@ import org.eclipse.cdt.debug.mi.core.output.MIThreadSelectInfo; /** */ -public class Target extends SessionObject implements ICDITarget, ICDIBreakpointManagement2, ICDIAddressToSource, ICDIMemorySpaceManagement { +public class Target extends SessionObject implements ICDITarget, ICDIBreakpointManagement3, ICDIAddressToSource, ICDIMemorySpaceManagement { MISession miSession; ICDITargetConfiguration fConfiguration; @@ -1282,4 +1283,10 @@ public class Target extends SessionObject implements ICDITarget, ICDIBreakpointM return new String[0]; } } + + public ICDICatchpoint setCatchpoint(String type, String arg, int cdiType, ICDICondition condition, boolean deferred, + boolean enabled) throws CDIException { + BreakpointManager bMgr = ((Session)getSession()).getBreakpointManager(); + return bMgr.setCatchpoint(this,type,arg,condition,enabled); + } } diff --git a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/CLIProcessor.java b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/CLIProcessor.java index 9a409ee8d0f..21158c9944c 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/CLIProcessor.java +++ b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/CLIProcessor.java @@ -174,7 +174,8 @@ public class CLIProcessor { (operation.startsWith("tb") && "tbreak".indexOf(operation) != -1) || //$NON-NLS-1$ //$NON-NLS-2$ (operation.startsWith("hb") && "hbreak".indexOf(operation) != -1) || //$NON-NLS-1$ //$NON-NLS-2$ (operation.startsWith("thb") && "thbreak".indexOf(operation) != -1) || //$NON-NLS-1$ //$NON-NLS-2$ - (operation.startsWith("rb") && "rbreak".indexOf(operation) != -1)) { //$NON-NLS-1$ //$NON-NLS-2$ + (operation.startsWith("rb") && "rbreak".indexOf(operation) != -1) || //$NON-NLS-1$ //$NON-NLS-2$ + (operation.startsWith("catch"))) { //$NON-NLS-1$ isbreak = true; } return isbreak; @@ -222,6 +223,9 @@ public class CLIProcessor { // only function breakpoints can be set using rbreak return MIBreakpointChangedEvent.HINT_NEW_FUNCTION_BREAKPOINT; } + if (op.equals("catch")) { + return MIBreakpointChangedEvent.HINT_NEW_CATCHPOINT; + } if ( !st.hasMoreTokens() ) { // "break" with no arguments return MIBreakpointChangedEvent.HINT_NEW_LINE_BREAKPOINT; diff --git a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/CLICatch.java b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/CLICatch.java new file mode 100644 index 00000000000..710f1cb08de --- /dev/null +++ b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/CLICatch.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 QNX Software 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.mi.core.command; + +import org.eclipse.cdt.debug.mi.core.MIException; +import org.eclipse.cdt.debug.mi.core.output.CLICatchInfo; +import org.eclipse.cdt.debug.mi.core.output.MIInfo; +import org.eclipse.cdt.debug.mi.core.output.MIOutput; + + + +/** + * Gdb catch command + */ +public class CLICatch extends CLICommand { + + MIOutput out; + + public CLICatch(String event, String arg) { + super("catch " + event + " "+arg); //$NON-NLS-1$ + } + + /** + * This command return breakpoint inserted + */ + public MIInfo getMIInfo() throws MIException { + MIInfo info = null; + MIOutput out = getMIOutput(); + if (out != null) { + info = new CLICatchInfo(out); + if (info.isError()) { + throwMIException(info, out); + } + } + return info; + } + +} diff --git a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/CommandFactory.java b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/CommandFactory.java index 5bb36966796..edcf2609adb 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/CommandFactory.java +++ b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/CommandFactory.java @@ -79,7 +79,11 @@ public class CommandFactory { public MIBreakWatch createMIBreakWatch(boolean access, boolean read, String expression) { return new MIBreakWatch(getMIVersion(), access, read, expression); } - + + public CLICatch createCLICatch(String event, String arg) { + return new CLICatch(event, arg); + } + public MIDataDisassemble createMIDataDisassemble(String start, String end, boolean mixed) { return new MIDataDisassemble(getMIVersion(), start, end, mixed); } diff --git a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/event/MIBreakpointChangedEvent.java b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/event/MIBreakpointChangedEvent.java index 803fcc6d9a4..d81c35b2636 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/event/MIBreakpointChangedEvent.java +++ b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/event/MIBreakpointChangedEvent.java @@ -23,6 +23,7 @@ public class MIBreakpointChangedEvent extends MIChangedEvent { public static final int HINT_NEW_LINE_BREAKPOINT = 1; public static final int HINT_NEW_FUNCTION_BREAKPOINT = 2; public static final int HINT_NEW_ADDRESS_BREAKPOINT = 3; + public static final int HINT_NEW_CATCHPOINT = 4; int no = 0; int hint = HINT_NONE; diff --git a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/output/CLICatchInfo.java b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/output/CLICatchInfo.java new file mode 100644 index 00000000000..e836f9f6c66 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/output/CLICatchInfo.java @@ -0,0 +1,72 @@ +package org.eclipse.cdt.debug.mi.core.output; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +public class CLICatchInfo extends MIInfo { + MIBreakpoint[] breakpoints; + + public CLICatchInfo(MIOutput record) { + super(record); + parse(); + } + + /** + * sample output: Catchpoint 3 (catch) + */ + protected void parse() { + List aList = new ArrayList(); + try { + if (isDone()) { + MIOutput out = getMIOutput(); + MIOOBRecord[] oobs = out.getMIOOBRecords(); + for (int i = 0; i < oobs.length; i++) { + if (oobs[i] instanceof MIConsoleStreamOutput) { + MIStreamRecord cons = (MIStreamRecord) oobs[i]; + String str = cons.getString(); + // We are interested in the signal info + if (parseCatchpoint(str.trim(), aList)) + break; + } + } + } + } finally { + breakpoints = (MIBreakpoint[]) aList.toArray(new MIBreakpoint[aList.size()]); + } + } + + private boolean parseCatchpoint(String str, List aList) { + if (str.length() == 0) + return false; + if (str.startsWith("Catchpoint ")) { //$NON-NLS-1$ + int bn = 0; + + StringTokenizer tokenizer = new StringTokenizer(str); + for (int i = 0; tokenizer.hasMoreTokens(); i++) { + String sub = tokenizer.nextToken(); + switch (i) { + case 0: // first column is "Signal" + + break; + case 1: // second column is number + bn = Integer.parseInt(sub); + break; + } + } + MITuple tuple = new MITuple(); + MIBreakpoint m = new MIBreakpoint(tuple); + m.setNumber(bn); + aList.add(m); + return true; + } + return false; + } + + public MIBreakpoint[] getMIBreakpoints() { + if (breakpoints == null) { + parse(); + } + return breakpoints; + } +} diff --git a/debug/org.eclipse.cdt.debug.mi.ui/plugin.properties b/debug/org.eclipse.cdt.debug.mi.ui/plugin.properties index a499633036d..3b03e472680 100644 --- a/debug/org.eclipse.cdt.debug.mi.ui/plugin.properties +++ b/debug/org.eclipse.cdt.debug.mi.ui/plugin.properties @@ -20,3 +20,9 @@ TargetOptionsPage.label=GDB/MI Options VerboseMode.label=Verbose Mode VerboseMode.tooltip=Verbose Mode For gdb Console + +catchCatch.label = Exception Caught +catchThrow.label = Exception Thrown +catchType.label = Event Type +catchSignal.label = Signal Caught +catchSignal.arg.label = Signal Number \ No newline at end of file diff --git a/debug/org.eclipse.cdt.debug.mi.ui/plugin.xml b/debug/org.eclipse.cdt.debug.mi.ui/plugin.xml index 6d9b721cda6..7dbe5ac700f 100644 --- a/debug/org.eclipse.cdt.debug.mi.ui/plugin.xml +++ b/debug/org.eclipse.cdt.debug.mi.ui/plugin.xml @@ -85,4 +85,19 @@ + + + + + + + + + + + + + +