From 2c2e4c5b962adf655549b58e35c4aaa3558550ad Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 8 Apr 2014 13:40:38 -0400 Subject: [PATCH] Bug 400628 - Support Dynamic Printf Change-Id: I1e030d05b482fef29ef7128d5a897544a0f85ca6 Signed-off-by: Marc Khouzam Reviewed-on: https://git.eclipse.org/r/10746 Tested-by: Hudson CI --- .../META-INF/MANIFEST.MF | 2 +- .../plugin.properties | 8 +- debug/org.eclipse.cdt.debug.core/plugin.xml | 61 +++ debug/org.eclipse.cdt.debug.core/pom.xml | 2 +- .../eclipse/cdt/debug/core/CDIDebugModel.java | 124 ++++- .../eclipse/cdt/debug/core/CDebugUtils.java | 28 +- .../debug/core/DebugCoreMessages.properties | 4 +- .../cdt/debug/core/model/ICDynamicPrintf.java | 65 +++ .../internal/core/CBreakpointManager.java | 13 +- .../breakpoints/AbstractDynamicPrintf.java | 52 +++ .../breakpoints/BreakpointMessages.properties | 12 +- .../core/breakpoints/BreakpointProblems.java | 10 +- .../breakpoints/CAddressDynamicPrintf.java | 53 +++ .../breakpoints/CFunctionDynamicPrintf.java | 49 ++ .../core/breakpoints/CLineDynamicPrintf.java | 73 +++ .../META-INF/MANIFEST.MF | 2 +- .../icons/dlcl16/dprintfd_obj.gif | Bin 0 -> 173 bytes .../icons/elcl16/dprintf_obj.gif | Bin 0 -> 230 bytes .../plugin.properties | 2 + debug/org.eclipse.cdt.debug.ui/plugin.xml | 52 ++- .../cdt/debug/internal/ui/CDebugImages.java | 7 +- .../internal/ui/CDebugModelPresentation.java | 19 +- .../ui/actions/ActionMessages.properties | 7 +- ...ddDynamicPrintfInteractiveRulerAction.java | 235 ++++++++++ ...cPrintfInteractiveRulerActionDelegate.java | 98 ++++ .../ui/actions/breakpoints/Messages.java | 27 ++ .../actions/breakpoints/Messages.properties | 16 + .../ToggleCDynamicPrintfTargetFactory.java | 72 +++ .../ToggleDynamicPrintfAdapter.java | 124 +++++ .../BreakpointsMessages.properties | 7 +- .../ui/breakpoints/CBreakpointContext.java | 16 +- .../CBreakpointPreferenceStore.java | 11 +- .../plugin.properties | 5 +- dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml | 32 ++ .../DisassemblyToggleDynamicPrintfTarget.java | 90 ++++ .../GDBDynamicPrintfPropertyPage.java | 423 ++++++++++++++++++ .../GDBTracepointPropertyPage.java | 32 +- .../gdb/internal/ui/breakpoints/Messages.java | 39 +- .../ui/breakpoints/Messages.properties | 42 +- .../ToggleDynamicPrintfTargetFactory.java | 94 ++++ .../AddDynamicPrintfRulerAction.java | 163 +++++++ .../AddDynamicPrintfRulerActionDelegate.java | 30 ++ .../ui/disassembly/DisassemblyMessages.java | 28 ++ .../DisassemblyMessages.properties | 15 + .../breakpoints/GDBDynamicPrintfUtils.java | 154 +++++++ .../cdt/dsf/gdb/breakpoints/Messages.java | 32 ++ .../dsf/gdb/breakpoints/Messages.properties | 18 + .../launching/FinalLaunchSequence_7_7.java | 97 ++++ .../dsf/gdb/service/GDBBreakpoints_7_7.java | 204 +++++++++ .../gdb/service/GdbDebugServicesFactory.java | 14 +- .../gdb/service/command/GDBControl_7_7.java | 43 ++ .../dsf/mi/service/MIBreakpointDMData.java | 40 +- .../cdt/dsf/mi/service/MIBreakpoints.java | 29 +- .../dsf/mi/service/MIBreakpointsManager.java | 36 +- .../mi/service/MIBreakpointsSynchronizer.java | 152 ++++++- .../command/CLIEventProcessor_7_0.java | 8 +- .../command/CLIEventProcessor_7_7.java | 71 +++ .../mi/service/command/CommandFactory.java | 14 + .../command/commands/MIDPrintfInsert.java | 170 +++++++ .../commands/MIGDBSetDPrintfStyle.java | 41 ++ .../service/command/output/MIBreakpoint.java | 50 ++- .../META-INF/MANIFEST.MF | 2 +- .../GDBJtagDSFFinalLaunchSequence_7_7.java | 78 ++++ .../dsf/gdb/service/GDBJtagControl_7_7.java | 39 ++ .../service/GdbJtagDebugServicesFactory.java | 5 +- 65 files changed, 3416 insertions(+), 125 deletions(-) create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICDynamicPrintf.java create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/AbstractDynamicPrintf.java create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CAddressDynamicPrintf.java create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CFunctionDynamicPrintf.java create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CLineDynamicPrintf.java create mode 100644 debug/org.eclipse.cdt.debug.ui/icons/dlcl16/dprintfd_obj.gif create mode 100644 debug/org.eclipse.cdt.debug.ui/icons/elcl16/dprintf_obj.gif create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/CAddDynamicPrintfInteractiveRulerAction.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/CAddDynamicPrintfInteractiveRulerActionDelegate.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/Messages.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/Messages.properties create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/ToggleCDynamicPrintfTargetFactory.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/ToggleDynamicPrintfAdapter.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/DisassemblyToggleDynamicPrintfTarget.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/GDBDynamicPrintfPropertyPage.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/ToggleDynamicPrintfTargetFactory.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/disassembly/AddDynamicPrintfRulerAction.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/disassembly/AddDynamicPrintfRulerActionDelegate.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/disassembly/DisassemblyMessages.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/disassembly/DisassemblyMessages.properties create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/breakpoints/GDBDynamicPrintfUtils.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/breakpoints/Messages.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/breakpoints/Messages.properties create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence_7_7.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBreakpoints_7_7.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_7.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CLIEventProcessor_7_7.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIDPrintfInsert.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIGDBSetDPrintfStyle.java create mode 100644 jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/GDBJtagDSFFinalLaunchSequence_7_7.java create mode 100644 jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/dsf/gdb/service/GDBJtagControl_7_7.java diff --git a/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF b/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF index 36d67ef2aec..a2bfcf6e170 100644 --- a/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF +++ b/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.debug.core; singleton:=true -Bundle-Version: 7.4.0.qualifier +Bundle-Version: 7.5.0.qualifier Bundle-Activator: org.eclipse.cdt.debug.core.CDebugCorePlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/debug/org.eclipse.cdt.debug.core/plugin.properties b/debug/org.eclipse.cdt.debug.core/plugin.properties index f6c0b57095a..5143875d060 100644 --- a/debug/org.eclipse.cdt.debug.core/plugin.properties +++ b/debug/org.eclipse.cdt.debug.core/plugin.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2000, 2010 QNX Software Systems and others. +# Copyright (c) 2000, 2014 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 @@ -14,6 +14,7 @@ # Texas Instruments - added extension point for source container type (279473) # Ericsson - Added support for Tracepoints (284286) # Sergey Prigogin (Google) +# Marc Khouzam (Ericsson) - Support for Dynamic printf (400628) ############################################################################### pluginName=C/C++ Development Tools Debug Model providerName=Eclipse CDT @@ -35,6 +36,9 @@ cEventBreakpoints.name=C/C++ Event Breakpoints cLineTracepoints.name=C/C++ Line Tracepoints cAddressTracepoints.name=C/C++ Address Tracepoints cFunctionTracepoints.name=C/C++ Function Tracepoints +cLineDynamicPrintf.name=C/C++ Line Dynamic Printf +cAddressDynamicPrintf.name=C/C++ Address Dynamic Printf +cFunctionDynamicPrintf.name=C/C++ Function Dynamic Printf breakpointProblem.name=C/C++ Breakpoint Problem containerName.project=Project @@ -58,4 +62,4 @@ sourceLocator.name = C/C++ Source Locator executablesProvider.name = Executables Provider sourceFilesProvider.name = Source Files Provider sourceRemappingProvider.name = Source Remapping Provider -executablesImporter.name = Executables Importer \ No newline at end of file +executablesImporter.name = Executables Importer diff --git a/debug/org.eclipse.cdt.debug.core/plugin.xml b/debug/org.eclipse.cdt.debug.core/plugin.xml index 37561872682..a13423eadd1 100644 --- a/debug/org.eclipse.cdt.debug.core/plugin.xml +++ b/debug/org.eclipse.cdt.debug.core/plugin.xml @@ -155,6 +155,49 @@ value="true"> + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -254,6 +297,24 @@ name="%cFunctionTracepoints.name" markerType="org.eclipse.cdt.debug.core.cFunctionTracepointMarker" id="cFunctionTracepoint"> + + + + + + ../../pom.xml - 7.4.0-SNAPSHOT + 7.5.0-SNAPSHOT org.eclipse.cdt.debug.core eclipse-plugin 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 e02da67b6d6..74f61314af0 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2011 QNX Software Systems and others. + * Copyright (c) 2004, 2014 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 @@ -10,6 +10,7 @@ * Freescale Semiconductor - Address watchpoints, https://bugs.eclipse.org/bugs/show_bug.cgi?id=118299 * QNX Software Systems - catchpoints - bug 226689 * Ericsson - tracepoints - bug 284286 + * Marc Khouzam (Ericsson) - Support for dynamic printf (400628) *******************************************************************************/ package org.eclipse.cdt.debug.core; @@ -31,6 +32,7 @@ import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint; import org.eclipse.cdt.debug.core.model.ICBreakpoint; import org.eclipse.cdt.debug.core.model.ICBreakpoint2; import org.eclipse.cdt.debug.core.model.ICBreakpointType; +import org.eclipse.cdt.debug.core.model.ICDynamicPrintf; import org.eclipse.cdt.debug.core.model.ICEventBreakpoint; import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; @@ -39,11 +41,14 @@ import org.eclipse.cdt.debug.core.model.ICTracepoint; 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.CAddressDynamicPrintf; import org.eclipse.cdt.debug.internal.core.breakpoints.CAddressTracepoint; import org.eclipse.cdt.debug.internal.core.breakpoints.CEventBreakpoint; import org.eclipse.cdt.debug.internal.core.breakpoints.CFunctionBreakpoint; +import org.eclipse.cdt.debug.internal.core.breakpoints.CFunctionDynamicPrintf; import org.eclipse.cdt.debug.internal.core.breakpoints.CFunctionTracepoint; import org.eclipse.cdt.debug.internal.core.breakpoints.CLineBreakpoint; +import org.eclipse.cdt.debug.internal.core.breakpoints.CLineDynamicPrintf; import org.eclipse.cdt.debug.internal.core.breakpoints.CLineTracepoint; import org.eclipse.cdt.debug.internal.core.breakpoints.CWatchpoint; import org.eclipse.cdt.debug.internal.core.model.CDebugTarget; @@ -240,7 +245,17 @@ public class CDIDebugModel { if (bp instanceof ICBreakpoint2) { return ((ICBreakpoint2) bp).getMarkerType(); } - if (bp instanceof ICTracepoint) { + if (bp instanceof ICDynamicPrintf) { + if (bp instanceof ICFunctionBreakpoint) { + return ICDynamicPrintf.C_FUNCTION_DYNAMICPRINTF_MARKER; + } else if (bp instanceof ICAddressBreakpoint) { + return ICDynamicPrintf.C_ADDRESS_DYNAMICPRINTF_MARKER; + } else if (bp instanceof ICLineBreakpoint) { + return ICDynamicPrintf.C_LINE_DYNAMICPRINTF_MARKER; + } else { + return ICDynamicPrintf.C_DYNAMICPRINTF_MARKER; + } + } else if (bp instanceof ICTracepoint) { if (bp instanceof ICFunctionBreakpoint) { return ICTracepoint.C_FUNCTION_TRACEPOINT_MARKER; } else if (bp instanceof ICAddressBreakpoint) { @@ -347,7 +362,7 @@ public class CDIDebugModel { } /** - * Creates a breakpoint without associated marker. + * Creates a line breakpoint without associated marker. *

* Note: Before a breakpoint created using this method can be used, the * client must first create a marker and register the breakpoint. The former @@ -371,9 +386,9 @@ public class CDIDebugModel { } /** - * Creates a breakpoint without associated marker. + * Creates a line tracepoint without associated marker. *

- * Note: Before a breakpoint created using this method can be used, the + * Note: Before a tracepoint created using this method can be used, the * client must first create a marker and register the breakpoint. The former * is accomplished using {@link IBreakpoint#setMarker(IMarker)}, the latter * using {@link IBreakpointManager#addBreakpoint(IBreakpoint)}. @@ -384,6 +399,31 @@ public class CDIDebugModel { return new CLineTracepoint(); } + /** + * @since 7.5 + */ + public static ICLineBreakpoint createLineDynamicPrintf(String sourceHandle, IResource resource, int type, + int lineNumber, boolean enabled, int ignoreCount, String condition, String printfStr, boolean register) throws CoreException { + HashMap attributes = new HashMap(10); + setLineBreakpointAttributes(attributes, sourceHandle, type, lineNumber, enabled, ignoreCount, condition); + attributes.put(ICDynamicPrintf.PRINTF_STRING, printfStr); + return new CLineDynamicPrintf(resource, attributes, register); + } + + /** + * Creates a line dynamic printf without associated marker. + *

+ * Note: Before a dynamic printf created using this method can be used, the + * client must first create a marker and register the breakpoint. The former + * is accomplished using {@link IBreakpoint#setMarker(IMarker)}, the latter + * using {@link IBreakpointManager#addBreakpoint(IBreakpoint)}. + * + * @since 7.5 + */ + public static ICLineBreakpoint createBlankLineDynamicPrintf() { + return new CLineDynamicPrintf(); + } + /** * Helper function for setting common line breakpoint attributes. * @@ -562,7 +602,7 @@ public class CDIDebugModel { } /** - * Creates a breakpoint without associated marker. + * Creates an address breakpoint without associated marker. *

* Note: Before a breakpoint created using this method can be used, the * client must first create a marker and register the breakpoint. The former @@ -588,9 +628,9 @@ public class CDIDebugModel { } /** - * Creates a breakpoint without associated marker. + * Creates an address tracepoint without associated marker. *

- * Note: Before a breakpoint created using this method can be used, the + * Note: Before a tracepoint created using this method can be used, the * client must first create a marker and register the breakpoint. The former * is accomplished using {@link IBreakpoint#setMarker(IMarker)}, the latter * using {@link IBreakpointManager#addBreakpoint(IBreakpoint)}. @@ -601,6 +641,33 @@ public class CDIDebugModel { return new CAddressTracepoint(); } + /** + * @since 7.5 + */ + public static ICAddressBreakpoint createAddressDynamicPrintf(String module, String sourceHandle, IResource resource, + int type, int lineNumber, IAddress address, boolean enabled, int ignoreCount, String condition, String printfStr, boolean register) + throws CoreException { + HashMap attributes = new HashMap(10); + setAddressBreakpointAttributes(attributes, module, sourceHandle, type, lineNumber, address, enabled, + ignoreCount, condition); + attributes.put(ICDynamicPrintf.PRINTF_STRING, printfStr); + return new CAddressDynamicPrintf(resource, attributes, register); + } + + /** + * Creates an address dynamic printf without associated marker. + *

+ * Note: Before a dynamic printf created using this method can be used, the + * client must first create a marker and register the breakpoint. The former + * is accomplished using {@link IBreakpoint#setMarker(IMarker)}, the latter + * using {@link IBreakpointManager#addBreakpoint(IBreakpoint)}. + * + * @since 7.5 + */ + public static ICAddressBreakpoint createBlankAddressDynamicPrintf() { + return new CAddressDynamicPrintf(); + } + /** * Helper function for setting common address breakpoint attributes. * @@ -641,9 +708,9 @@ public class CDIDebugModel { } /** - * Creates a breakpoint without associated marker. + * Creates a watchpoint without associated marker. *

- * Note: Before a breakpoint created using this method can be used, the + * Note: Before a watchpoint created using this method can be used, the * client must first create a marker and register the breakpoint. The former * is accomplished using {@link IBreakpoint#setMarker(IMarker)}, the latter * using {@link IBreakpointManager#addBreakpoint(IBreakpoint)}. @@ -1041,7 +1108,7 @@ public class CDIDebugModel { } /** - * Creates a breakpoint without associated marker. + * Creates a function breakpoint without associated marker. *

* Note: Before a breakpoint created using this method can be used, the * client must first create a marker and register the breakpoint. The former @@ -1108,9 +1175,9 @@ public class CDIDebugModel { } /** - * Creates a breakpoint without associated marker. + * Creates a function tracepoint without associated marker. *

- * Note: Before a breakpoint created using this method can be used, the + * Note: Before a tracepoint created using this method can be used, the * client must first create a marker and register the breakpoint. The former * is accomplished using {@link IBreakpoint#setMarker(IMarker)}, the latter * using {@link IBreakpointManager#addBreakpoint(IBreakpoint)}. @@ -1121,6 +1188,33 @@ public class CDIDebugModel { return new CFunctionTracepoint(); } + /** + * @since 7.5 + */ + public static ICFunctionBreakpoint createFunctionDynamicPrintf(String sourceHandle, IResource resource, int type, + String function, int charStart, int charEnd, int lineNumber, boolean enabled, int ignoreCount, + String condition, String printfStr, boolean register) throws CoreException { + HashMap attributes = new HashMap(10); + setFunctionBreakpointAttributes(attributes, sourceHandle, type, function, charStart, charEnd, lineNumber, + enabled, ignoreCount, condition); + attributes.put(ICDynamicPrintf.PRINTF_STRING, printfStr); + return new CFunctionDynamicPrintf(resource, attributes, register); + } + + /** + * Creates a function dynamic printf without associated marker. + *

+ * Note: Before a dynamic printf created using this method can be used, the + * client must first create a marker and register the breakpoint. The former + * is accomplished using {@link IBreakpoint#setMarker(IMarker)}, the latter + * using {@link IBreakpointManager#addBreakpoint(IBreakpoint)}. + * + * @since 7.5 + */ + public static ICFunctionBreakpoint createBlankFunctionDynamicPrintf() { + return new CFunctionDynamicPrintf(); + } + /** * Helper function for setting common address breakpoint attributes. * @@ -1443,9 +1537,9 @@ public class CDIDebugModel { } /** - * Creates a breakpoint without associated marker. + * Creates an event breakpoint without associated marker. *

- * Note: Before a breakpoint created using this method can be used, the + * Note: Before an event breakpoint created using this method can be used, the * client must first create a marker and register the breakpoint. The former * is accomplished using {@link IBreakpoint#setMarker(IMarker)}, the latter * using {@link IBreakpointManager#addBreakpoint(IBreakpoint)}. diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugUtils.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugUtils.java index f88761ee33a..08100c0aa2e 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugUtils.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugUtils.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 QNX Software Systems and others. + * Copyright (c) 2000, 2014 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 @@ -9,6 +9,7 @@ * QNX Software Systems - Initial API and implementation * Freescale Semiconductor - Address watchpoints, https://bugs.eclipse.org/bugs/show_bug.cgi?id=118299 * Patrick Chuong (Texas Instruments) - Update CDT ToggleBreakpointTargetFactory enablement (340177) + * Marc Khouzam (Ericsson) - Support for dynamic printf (400628) *******************************************************************************/ package org.eclipse.cdt.debug.core; @@ -35,6 +36,7 @@ import org.eclipse.cdt.debug.core.cdi.CDIException; import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint; import org.eclipse.cdt.debug.core.model.ICBreakpoint; import org.eclipse.cdt.debug.core.model.ICBreakpointType; +import org.eclipse.cdt.debug.core.model.ICDynamicPrintf; import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; import org.eclipse.cdt.debug.core.model.ICValue; @@ -331,7 +333,7 @@ public class CDebugUtils { if (breakpoint instanceof ICWatchpoint) { return getWatchpointText((ICWatchpoint)breakpoint, qualified); } - // this allow to create new breakpoint without implemention one the interfaces above and still see a label + // This allows to create a new breakpoint without implementing one of the interfaces above and still see a label Object message = breakpoint.getMarker().getAttribute(IMarker.MESSAGE); if (message != null) return message.toString(); @@ -342,6 +344,9 @@ public class CDebugUtils { StringBuffer label = new StringBuffer(); appendSourceName(breakpoint, label, qualified); appendLineNumber(breakpoint, label); + if (breakpoint instanceof ICDynamicPrintf) { + appendPrintfString((ICDynamicPrintf)breakpoint, label); + } appendBreakpointType(breakpoint, label); appendIgnoreCount(breakpoint, label); appendCondition(breakpoint, label); @@ -367,6 +372,9 @@ public class CDebugUtils { StringBuffer label = new StringBuffer(); appendSourceName(breakpoint, label, qualified); appendAddress(breakpoint, label); + if (breakpoint instanceof ICDynamicPrintf) { + appendPrintfString((ICDynamicPrintf)breakpoint, label); + } appendBreakpointType(breakpoint, label); appendIgnoreCount(breakpoint, label); appendCondition(breakpoint, label); @@ -377,6 +385,9 @@ public class CDebugUtils { StringBuffer label = new StringBuffer(); appendSourceName(breakpoint, label, qualified); appendFunction(breakpoint, label); + if (breakpoint instanceof ICDynamicPrintf) { + appendPrintfString((ICDynamicPrintf)breakpoint, label); + } appendBreakpointType(breakpoint, label); appendIgnoreCount(breakpoint, label); appendCondition(breakpoint, label); @@ -421,6 +432,17 @@ public class CDebugUtils { return label; } + /** + * @since 7.5 + */ + protected static void appendPrintfString(ICDynamicPrintf dprintf, StringBuffer buffer) throws CoreException { + String printfStr = dprintf.getPrintfString(); + if (printfStr != null && printfStr.length() > 0) { + buffer.append(' '); + buffer.append(MessageFormat.format(DebugCoreMessages.getString("CDebugUtils.printfString"), (Object[])new String[] { printfStr })); //$NON-NLS-1$ + } + } + protected static StringBuffer appendIgnoreCount(ICBreakpoint breakpoint, StringBuffer label) throws CoreException { int ignoreCount = breakpoint.getIgnoreCount(); if (ignoreCount > 0) { @@ -762,4 +784,4 @@ public class CDebugUtils { String customModel = System.getProperty(ICDebugConstants.PREF_TOGGLE_BREAKPOINT_MODEL_IDENTIFIER, null); return customModel != null && Boolean.valueOf(customModel); } -} \ No newline at end of file +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/DebugCoreMessages.properties b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/DebugCoreMessages.properties index 99fa5008e58..504e9b49e67 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/DebugCoreMessages.properties +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/DebugCoreMessages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2003, 2010 QNX Software Systems and others. +# Copyright (c) 2003, 2014 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 @@ -8,6 +8,7 @@ # Contributors: # QNX Software Systems - initial API and implementation # Freescale Semiconductor - Address watchpoints, https://bugs.eclipse.org/bugs/show_bug.cgi?id=118299 +# Marc Khouzam (Ericsson) - Support for dynamic printf (400628) ############################################################################### CDebugCorePlugin.0=No such debugger CDebugUtils.0=[line: {0}] @@ -19,6 +20,7 @@ CDebugUtils.5=[expression: ''{0}''] CDebugUtils.6=[memory space: {0}] CDebugUtils.7=[units: {0}] CDebugUtils.8=[type: {0}] +CDebugUtils.printfString=[{0}] CDebugUtils.Regular=Regular CDebugUtils.Hardware=Hardware CDebugUtils.Temporary=Temporary diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICDynamicPrintf.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICDynamicPrintf.java new file mode 100644 index 00000000000..6e6e9d4f1f7 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICDynamicPrintf.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.core.model; + +import org.eclipse.core.runtime.CoreException; + +/** + * A dynamic printf specific to the C/C++ debug model. + * + * @since 7.5 + */ +public interface ICDynamicPrintf extends ICLineBreakpoint { + /** + * Breakpoint marker type for this breakpoint type. + */ + public static final String C_DYNAMICPRINTF_MARKER = "org.eclipse.cdt.debug.core.cDynamicPrintfMarker"; //$NON-NLS-1$ + + /** + * Breakpoint marker type for this breakpoint type. + */ + public static final String C_LINE_DYNAMICPRINTF_MARKER = "org.eclipse.cdt.debug.core.cLineDynamicPrintfMarker"; //$NON-NLS-1$ + + /** + * Breakpoint marker type for this breakpoint type. + */ + public static final String C_ADDRESS_DYNAMICPRINTF_MARKER = "org.eclipse.cdt.debug.core.cAddressDynamicPrintfMarker"; //$NON-NLS-1$ + + /** + * Breakpoint marker type for this breakpoint type. + */ + public static final String C_FUNCTION_DYNAMICPRINTF_MARKER = "org.eclipse.cdt.debug.core.cFunctionDynamicPrintfMarker"; //$NON-NLS-1$ + + /** + * Dynamic printf attribute storing the string to be printed (value + * "org.eclipse.cdt.debug.core.printf_string"). This attribute + * is a String. + */ + public static final String PRINTF_STRING = "org.eclipse.cdt.debug.core.printf_string"; //$NON-NLS-1$ + + /** + * Returns the string used by this dynamic printf. + * + * @return the string used by this dynamic printf + * @exception CoreException if unable to access the property on this dynamic printf's + * underlying marker + */ + public String getPrintfString() throws CoreException; + + /** + * Sets the string attribute for this dynamic printf + * + * @param message The new string + * @exception CoreException if unable to access the property on this dynamic printf's + * underlying marker + */ + public void setPrintfString(String str) 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 a2304679022..1cf08dc458a 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2010 QNX Software Systems and others. + * Copyright (c) 2004, 2014 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 @@ -13,6 +13,7 @@ * Freescale Semiconductor - Address watchpoints, https://bugs.eclipse.org/bugs/show_bug.cgi?id=118299 * QNX Software Systems - catchpoints - bug 226689 * James Blackburn (Broadcom) - bug 314865 + * Marc Khouzam (Ericsson) - Support for dynamic printf (400628) *******************************************************************************/ package org.eclipse.cdt.debug.internal.core; @@ -68,6 +69,7 @@ import org.eclipse.cdt.debug.core.model.ICBreakpoint; import org.eclipse.cdt.debug.core.model.ICBreakpointFilterExtension; import org.eclipse.cdt.debug.core.model.ICBreakpointType; import org.eclipse.cdt.debug.core.model.ICDebugTarget; +import org.eclipse.cdt.debug.core.model.ICDynamicPrintf; import org.eclipse.cdt.debug.core.model.ICEventBreakpoint; import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; @@ -877,8 +879,13 @@ public class CBreakpointManager implements IBreakpointsListener, IBreakpointMana breakpointType = ((ICBreakpointType) icbreakpoint).getType(); } if ( icbreakpoint instanceof ICTracepoint) { - ICTracepoint breakpoint = (ICTracepoint)icbreakpoint; - IMarker marker = BreakpointProblems.reportUnsupportedTracepoint(breakpoint, getDebugTarget().getName(), getDebugTarget().getInternalID()); + ICTracepoint tracepoint = (ICTracepoint)icbreakpoint; + IMarker marker = BreakpointProblems.reportUnsupportedTracepoint(tracepoint, getDebugTarget().getName(), getDebugTarget().getInternalID()); + if (marker != null) + fBreakpointProblems.add(marker); + } else if ( icbreakpoint instanceof ICDynamicPrintf) { + ICDynamicPrintf dprintf = (ICDynamicPrintf)icbreakpoint; + IMarker marker = BreakpointProblems.reportUnsupportedDynamicPrintf(dprintf, getDebugTarget().getName(), getDebugTarget().getInternalID()); if (marker != null) fBreakpointProblems.add(marker); } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/AbstractDynamicPrintf.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/AbstractDynamicPrintf.java new file mode 100644 index 00000000000..2123bf92698 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/AbstractDynamicPrintf.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.core.breakpoints; + +import java.util.Map; + +import org.eclipse.cdt.debug.core.model.ICDynamicPrintf; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; + +/** + * Base class for different types of location DynamicPrintf. + * + * @since 7.5 + */ +public abstract class AbstractDynamicPrintf extends AbstractLineBreakpoint implements ICDynamicPrintf { + + public AbstractDynamicPrintf() { + super(); + } + + public AbstractDynamicPrintf( IResource resource, Map attributes, boolean add ) throws CoreException { + super( resource, attributes, add ); + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.debug.core.ICDynamicPrintf#getPrintfString() + */ + @Override + public String getPrintfString() throws CoreException { + return ensureMarker().getAttribute( PRINTF_STRING, "" ); //$NON-NLS-1$ + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.debug.core.ICDynamicPrintf#setPrintfString(String) + */ + public void setPrintfString( String str ) throws CoreException { + setAttribute( PRINTF_STRING, str ); + setAttribute( IMarker.MESSAGE, getMarkerMessage() ); + } +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/BreakpointMessages.properties b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/BreakpointMessages.properties index e4dacfadbf3..3f7261b2d79 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/BreakpointMessages.properties +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/BreakpointMessages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2003, 2009 QNX Software Systems and others. +# Copyright (c) 2003, 2014 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 @@ -8,12 +8,15 @@ # Contributors: # QNX Software Systems - initial API and implementation # Erisson - Added support for tracepoints (284286) +# Marc Khouzam (Ericsson) - Added support for dynamic printf (400628) ############################################################################### # The marker message of an address breakpoint. CAddressBreakpoint.0=Address breakpoint: {0} # The marker message of an address tracepoint. CAddressTracepoint.0=Address tracepoint: {0} +# The marker message of an address dynamic printf. +CAddressDynamicPrintf.0=Address dynamic printf: {0} CBreakpoint.1=\ [ignore count: {0}] CBreakpoint.2=\ if {0} @@ -22,6 +25,8 @@ CBreakpoint.2=\ if {0} CFunctionBreakpoint.0=Function breakpoint: {0} # The marker message of a function tracepoint. CFunctionTracepoint.0=Function tracepoint: {0} +# The marker message of a function dynamic printf. +CFunctionDynamicPrintf.0=Function dynamic printf: {0} # The marker message of a line breakpoint. CLineBreakpoint.0=Line breakpoint: {0} @@ -29,6 +34,10 @@ CLineBreakpoint.0=Line breakpoint: {0} CLineBreakpoint.1=Line breakpoint (relocated): {0} # The marker message of a line tracepoint. CLineTracepoint.0=Line tracepoint: {0} +# The marker message of a line dynamic printf. +CLineDynamicPrintf.0=Line dynamic printf: {0} +# The marker message of a relocated line breakpoint. +CLineDynamicPrintf.1=Line dynamic printf (relocated): {0} # The marker message of a write watchpoint. CWatchpoint.0=Write watchpoint: {0} @@ -45,3 +54,4 @@ BreakpointProblems_Moved=Breakpoint could not be set at line {0}, moved to line BreakpointProblems_Unresolved=Unresolved breakpoint BreakpointProblems_UnsupportedTracepoint=Tracepoints are not supported +BreakpointProblems_UnsupportedDynamicPrintf=Dynamic printfs are not supported diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/BreakpointProblems.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/BreakpointProblems.java index 828c4ef729f..3c479c25cae 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/BreakpointProblems.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/BreakpointProblems.java @@ -1,12 +1,13 @@ /******************************************************************************* - * Copyright (c) 2007, 2009 Nokia and others. + * Copyright (c) 2007, 2014 Nokia 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: - * Nokia - Initial API and implementation + * Nokia - Initial API and implementation + * Marc Khouzam (Ericsson) - Added support for Dynamic Printf (Bug 400628) *******************************************************************************/ package org.eclipse.cdt.debug.internal.core.breakpoints; @@ -53,6 +54,11 @@ public class BreakpointProblems { return marker; } + public static IMarker reportUnsupportedDynamicPrintf(ICBreakpoint breakpoint, String contextName, String contextID) throws CoreException { + IMarker marker = BreakpointProblems.reportBreakpointProblem(breakpoint, BreakpointMessages.getString("BreakpointProblems_UnsupportedDynamicPrintf"), IMarker.SEVERITY_WARNING, UNRESOLVED, true, false, contextName, contextID); //$NON-NLS-1$ + return marker; + } + public static void removeProblemsForBreakpoint(ICBreakpoint breakpoint) throws CoreException { IMarker marker = breakpoint.getMarker(); if (marker != null) diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CAddressDynamicPrintf.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CAddressDynamicPrintf.java new file mode 100644 index 00000000000..cd683b254ae --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CAddressDynamicPrintf.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.core.breakpoints; + +import java.util.Map; + +import org.eclipse.cdt.debug.core.CDebugUtils; +import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint; +import org.eclipse.cdt.debug.core.model.ICDynamicPrintf; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; + +import com.ibm.icu.text.MessageFormat; + +/** + * A DynamicPrintf that prints a message when a particular address is reached. + * + * @since 7.5 + */ +public class CAddressDynamicPrintf extends AbstractDynamicPrintf implements ICAddressBreakpoint, ICDynamicPrintf { + + public CAddressDynamicPrintf() { + } + + public CAddressDynamicPrintf( IResource resource, Map attributes, boolean add ) throws CoreException { + super( resource, attributes, add ); + } + + /** + * Returns the type of marker associated with this type of breakpoints + */ + public String getMarkerType() { + return C_ADDRESS_DYNAMICPRINTF_MARKER; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.debug.internal.core.breakpoints.CBreakpoint#getMarkerMessage() + */ + @Override + protected String getMarkerMessage() throws CoreException { + return MessageFormat.format( BreakpointMessages.getString( "CAddressDynamicPrintf.0" ), (Object[])new String[] { CDebugUtils.getBreakpointText( this, false ) } ); //$NON-NLS-1$ + } +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CFunctionDynamicPrintf.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CFunctionDynamicPrintf.java new file mode 100644 index 00000000000..7a726fc529d --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CFunctionDynamicPrintf.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.core.breakpoints; + +import java.util.Map; + +import org.eclipse.cdt.debug.core.CDebugUtils; +import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint; +import org.eclipse.cdt.debug.core.model.ICDynamicPrintf; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; + +import com.ibm.icu.text.MessageFormat; + +/** + * A DynamicPrintf that collects data when a function is entered. + * + * @since 7.5 + */ +public class CFunctionDynamicPrintf extends AbstractDynamicPrintf implements ICFunctionBreakpoint, ICDynamicPrintf { + public CFunctionDynamicPrintf() { + } + + public CFunctionDynamicPrintf( IResource resource, Map attributes, boolean add ) throws CoreException { + super( resource, attributes, add ); + } + + /** + * Returns the type of marker associated with this type of breakpoints + */ + public String getMarkerType() { + return C_FUNCTION_DYNAMICPRINTF_MARKER; + } + + /*(non-Javadoc) + * @see org.eclipse.cdt.debug.internal.core.breakpoints.CBreakpoint#getMarkerMessage() + */ + protected String getMarkerMessage() throws CoreException { + return MessageFormat.format( BreakpointMessages.getString( "CFunctionDynamicPrintf.0" ), (Object[])new String[] { CDebugUtils.getBreakpointText( this, false ) } ); //$NON-NLS-1$ + } +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CLineDynamicPrintf.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CLineDynamicPrintf.java new file mode 100644 index 00000000000..7cabddd4658 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CLineDynamicPrintf.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.core.breakpoints; + +import java.util.Map; + +import org.eclipse.cdt.debug.core.CDebugUtils; +import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.cdt.debug.core.model.ICDynamicPrintf; +import org.eclipse.cdt.debug.core.model.ICLineBreakpoint2; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; + +import com.ibm.icu.text.MessageFormat; + +/** + * A DynamicPrintf that prints a string when a particular line of code is reached. + * + * @since 7.5 + */ +public class CLineDynamicPrintf extends AbstractDynamicPrintf implements ICDynamicPrintf, ICLineBreakpoint2 { + + public CLineDynamicPrintf() { + } + + public CLineDynamicPrintf( IResource resource, Map attributes, boolean add ) throws CoreException { + super( resource, attributes, add ); + } + + @Override + public String getMarkerType() { + return C_LINE_DYNAMICPRINTF_MARKER; + } + + /*(non-Javadoc) + * @see org.eclipse.cdt.debug.internal.core.breakpoints.CBreakpoint#getMarkerMessage() + */ + @Override + protected String getMarkerMessage() throws CoreException { + IMarker marker = this.getMarker(); + int bp_line = 0; + int bp_request_line = 0; + String bp_file = null; + String bp_reqest_file = null; + + if (marker != null) { + bp_line = marker.getAttribute(IMarker.LINE_NUMBER, -1); + bp_request_line = marker.getAttribute(ICLineBreakpoint2.REQUESTED_LINE, -1); + bp_file = marker.getAttribute(ICBreakpoint.SOURCE_HANDLE, (String)null); + bp_reqest_file = marker.getAttribute(ICLineBreakpoint2.REQUESTED_SOURCE_HANDLE, (String)null); + } + + if (bp_line != bp_request_line || + (bp_file == null && bp_reqest_file != null) || + (bp_file != null && !bp_file.equals(bp_reqest_file)) ) + { + return MessageFormat.format( BreakpointMessages.getString( "CLineDynamicPrintf.1" ), (Object[])new String[] { CDebugUtils.getBreakpointText( this, false ) } ); //$NON-NLS-1$ + } + else { + return MessageFormat.format( BreakpointMessages.getString( "CLineDynamicPrintf.0" ), (Object[])new String[] { CDebugUtils.getBreakpointText( this, false ) } ); //$NON-NLS-1$ + + } + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF b/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF index fd06d44bdfc..83cb2367c03 100644 --- a/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF +++ b/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF @@ -7,7 +7,7 @@ Bundle-Activator: org.eclipse.cdt.debug.ui.CDebugUIPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin Export-Package: - org.eclipse.cdt.debug.internal.ui;x-internal:x-friends:="org.eclipse.cdt.dsf.ui";x-friends:="org.eclipse.cdt.dsf.ui", + org.eclipse.cdt.debug.internal.ui;x-friends:="org.eclipse.cdt.dsf.ui,org.eclipse.cdt.dsf.gdb.ui", org.eclipse.cdt.debug.internal.ui.actions;x-friends:="org.eclipse.cdt.dsf.ui,org.eclipse.cdt.debug.ui.memory.memorybrowser", org.eclipse.cdt.debug.internal.ui.actions.breakpoints;x-internal:=true, org.eclipse.cdt.debug.internal.ui.breakpoints;x-friends:="org.eclipse.cdt.dsf.ui,org.eclipse.cdt.dsf.gdb.ui", diff --git a/debug/org.eclipse.cdt.debug.ui/icons/dlcl16/dprintfd_obj.gif b/debug/org.eclipse.cdt.debug.ui/icons/dlcl16/dprintfd_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..79e75031f510a7bd29993b66ac256e753c8b9b6c GIT binary patch literal 173 zcmZ?wbhEHb6krfwc+Ab9$WYH9T(9O=q!(Immef6A&yAI*9zK8f^X;c!AHV+o|K~p% zQ2Zz8T$GwvlA5AWo>`Ki;O^-gz@Ye(g^`PapFxKK2tWoiu(*CW$1M-B^`$a4hO3>I2;ukPXvpw9dvBGX(GVF!n}3Gi?Z$q M8!CL%+!+|G0kc$0Jpcdz literal 0 HcmV?d00001 diff --git a/debug/org.eclipse.cdt.debug.ui/icons/elcl16/dprintf_obj.gif b/debug/org.eclipse.cdt.debug.ui/icons/elcl16/dprintf_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..072d2ae0637888b1170d1fc5f0378ce1595386d1 GIT binary patch literal 230 zcmZ?wbhEHb6krfwXc1vhWTaA17(r<0f%`&^cf>l$h)nq}g z+AI#C_9jKe83y*kOil+~1=gJLOg>Pc!^T_i!%;v$?$zrQyZyJ`|JV~J&%|I202Uf` A{Qv*} literal 0 HcmV?d00001 diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.properties b/debug/org.eclipse.cdt.debug.ui/plugin.properties index 0f70afeed03..2fda45869f0 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.properties +++ b/debug/org.eclipse.cdt.debug.ui/plugin.properties @@ -13,6 +13,7 @@ # Marc Khouzam (Ericsson) - Added support for connect command (Bug 365601) # Marc Dumais (Ericsson) - Added support for reverse debug action (Bug 365776) # Alvaro Sanchez-Leon (Ericsson AB) - Support for Step into selection (bug 244865) +# Marc Khouzam (Ericsson) - Added dynamic printf support (Bug 400628) ############################################################################### pluginName=C/C++ Development Tools Debugger UI @@ -40,6 +41,7 @@ ShowDebuggerConsoleAction.tooltip=Show Debugger Console On Target Selection AddBreakpoint.label=Toggle Brea&kpoint AddBreakpointInteractive.label=&Add Breakpoint... +AddDynamicPrintfInteractive.label=Add &Dynamic-Printf... EnableBreakpoint.label=&Toggle Breakpoint Enabled BreakpointProperties.label=Breakpoint P&roperties... RulerBreakpointProperties.label=Breakpoint P&roperties... diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.xml b/debug/org.eclipse.cdt.debug.ui/plugin.xml index 495b8c23566..b297cf9038e 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.xml +++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml @@ -439,13 +439,20 @@ menubarPath="debug" id="org.eclipse.cdt.debug.internal.ui.actions.EnableDisableBreakpointRulerActionDelegate"> + + - + + + - + - + + + + @@ -1219,6 +1236,9 @@ + + + @@ -1235,6 +1255,10 @@ + + + + @@ -1250,6 +1274,10 @@ + + + + @@ -1874,7 +1902,7 @@ id="org.eclipse.cdt.debug.ui.ToggleCTracepointsTargetFactory" class="org.eclipse.cdt.debug.internal.ui.actions.breakpoints.ToggleCTracepointsTargetFactory"> - + @@ -1891,6 +1919,22 @@ + + + + + + + + + + + + + + diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDebugImages.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDebugImages.java index 87f689ae6ad..6d8b0fc9165 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDebugImages.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDebugImages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 QNX Software Systems and others. + * Copyright (c) 2000, 2014 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 @@ -8,6 +8,7 @@ * Contributors: * QNX Software Systems - Initial API and implementation * Ericsson - Added tracepoint support (284286) + * Marc Khouzam (Ericsson) - Added dynamic printf support (400628) *******************************************************************************/ package org.eclipse.cdt.debug.internal.ui; @@ -73,6 +74,8 @@ public class CDebugImages { public static final String IMG_OBJS_FUNCTION_BREAKPOINT_DISABLED = NAME_PREFIX + "funbrkpd_obj.gif"; //$NON-NLS-1$ public static final String IMG_OBJS_TRACEPOINT_ENABLED = NAME_PREFIX + "trcp_obj.gif"; //$NON-NLS-1$ public static final String IMG_OBJS_TRACEPOINT_DISABLED = NAME_PREFIX + "trcpd_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_DYNAMICPRINTF_ENABLED = NAME_PREFIX + "dprintf_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_DYNAMICPRINTF_DISABLED = NAME_PREFIX + "dprintfd_obj.gif"; //$NON-NLS-1$ public static final String IMG_OBJS_WATCHPOINT_ENABLED = NAME_PREFIX + "readwrite_obj.gif"; //$NON-NLS-1$ public static final String IMG_OBJS_WATCHPOINT_DISABLED = NAME_PREFIX + "readwrite_obj_disabled.gif"; //$NON-NLS-1$ public static final String IMG_OBJS_EVENTBREAKPOINT_ENABLED = NAME_PREFIX + "eventbreakpoint_obj.gif"; //$NON-NLS-1$ @@ -160,6 +163,8 @@ public class CDebugImages { public static final ImageDescriptor DESC_OBJS_HWBREAKPOINT_DISABLED = createManaged(T_OBJ, IMG_OBJS_HWBREAKPOINT_DISABLED); public static final ImageDescriptor DESC_OBJS_TRACEPOINT_ENABLED = createManaged(T_ELCL, IMG_OBJS_TRACEPOINT_ENABLED); public static final ImageDescriptor DESC_OBJS_TRACEPOINT_DISABLED = createManaged(T_DLCL, IMG_OBJS_TRACEPOINT_DISABLED); + public static final ImageDescriptor DESC_OBJS_DYNAMICPRINTF_ENABLED = createManaged(T_ELCL, IMG_OBJS_DYNAMICPRINTF_ENABLED); + public static final ImageDescriptor DESC_OBJS_DYNAMICPRINTF_DISABLED = createManaged(T_DLCL, IMG_OBJS_DYNAMICPRINTF_DISABLED); public static final ImageDescriptor DESC_OBJS_WATCHPOINT_ENABLED = createManaged(T_OBJ, IMG_OBJS_WATCHPOINT_ENABLED); public static final ImageDescriptor DESC_OBJS_WATCHPOINT_DISABLED = createManaged(T_OBJ, IMG_OBJS_WATCHPOINT_DISABLED); public static final ImageDescriptor DESC_OBJS_EVENTBREAKPOINT_ENABLED = createManaged(T_OBJ, IMG_OBJS_EVENTBREAKPOINT_ENABLED); diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDebugModelPresentation.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDebugModelPresentation.java index ac7b540a6ef..714370298dc 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDebugModelPresentation.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDebugModelPresentation.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2010 QNX Software Systems and others. + * Copyright (c) 2004, 2014 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 @@ -11,6 +11,7 @@ * ARM Limited - https://bugs.eclipse.org/bugs/show_bug.cgi?id=186981 * Ken Ryall (Nokia) - Bug 201165 don't toss images on dispose. * Ericsson - Bug 284286 support for tracepoints + * Marc Khouzam (Ericsson) - Added dynamic printf support (400628) *******************************************************************************/ package org.eclipse.cdt.debug.internal.ui; @@ -44,6 +45,7 @@ import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint; import org.eclipse.cdt.debug.core.model.ICGlobalVariable; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; import org.eclipse.cdt.debug.core.model.ICModule; +import org.eclipse.cdt.debug.core.model.ICDynamicPrintf; import org.eclipse.cdt.debug.core.model.ICSignal; import org.eclipse.cdt.debug.core.model.ICStackFrame; import org.eclipse.cdt.debug.core.model.ICThread; @@ -356,6 +358,10 @@ public class CDebugModelPresentation extends LabelProvider implements IDebugMode if ( breakpoint instanceof ICTracepoint ) { return getTracepointImage( (ICTracepoint)breakpoint ); } + // Check for ICDynamicPrintf first because they are also ICLineBreakpoint + if ( breakpoint instanceof ICDynamicPrintf ) { + return getDynamicPrintfImage( (ICDynamicPrintf)breakpoint ); + } if ( breakpoint instanceof ICLineBreakpoint ) { // checks if the breakpoint type is a hardware breakpoint, // if so, return the hardware breakpoint image @@ -390,6 +396,17 @@ public class CDebugModelPresentation extends LabelProvider implements IDebugMode return getImageCache().getImageFor( new OverlayImageDescriptor( fDebugImageRegistry.get( descriptor ), computeOverlays( breakpoint ) ) ); } + protected Image getDynamicPrintfImage( ICDynamicPrintf dynamicPrintf ) throws CoreException { + ImageDescriptor descriptor = null; + if ( dynamicPrintf.isEnabled() ) { + descriptor = CDebugImages.DESC_OBJS_DYNAMICPRINTF_ENABLED; + } + else { + descriptor = CDebugImages.DESC_OBJS_DYNAMICPRINTF_DISABLED; + } + return getImageCache().getImageFor( new OverlayImageDescriptor( fDebugImageRegistry.get( descriptor ), computeOverlays( dynamicPrintf ) ) ); + } + protected Image getTracepointImage( ICTracepoint tracepoint ) throws CoreException { ImageDescriptor descriptor = null; if ( tracepoint.isEnabled() ) { diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ActionMessages.properties b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ActionMessages.properties index 6be1401ba9e..29199645172 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ActionMessages.properties +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ActionMessages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2003, 2010-7 QNX Software Systems and others. +# Copyright (c) 2003, 2014 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 @@ -8,6 +8,7 @@ # Contributors: # QNX Software Systems - initial API and implementation # Freescale Semiconductor - Address watchpoints, https://bugs.eclipse.org/bugs/show_bug.cgi?id=118299 +# Marc Khouzam (Ericsson) - Added dynamic printf support (400628) ############################################################################### LoadSymbolsActionDelegate.Unable_to_load_symbols_of_shared_library_1=Unable to load symbols of shared library. @@ -125,6 +126,8 @@ ToggleCBreakpointsTargetFactory.CBreakpointDescription=Standard C/C++ breakpoint ToggleCBreakpointsTargetFactory.CBreakpointName=C/C++ Breakpoints ToggleCBreakpointsTargetFactory.CTracepointDescription=Standard C/C++ tracepoint type. ToggleCBreakpointsTargetFactory.CTracepointName=C/C++ Tracepoints +ToggleCBreakpointsTargetFactory.CDynamicPrintfDescription=Standard C/C++ Dynamic Printf type. +ToggleCBreakpointsTargetFactory.CDynamicPrintfName=C/C++ Dynamic Printf RetargetAction.0=Error RetargetAction.1=Operation failed RetargetMoveToLineAction.0=The operation is unavailable on the current selection. Please place the cursor on valid line to run to. @@ -134,3 +137,5 @@ CAddBreakpointInteractiveRulerAction_error_title=Error CAddBreakpointInteractiveRulerAction_error_message=Unable to create breakpoint CRulerToggleBreakpointActionDelegate_label=Toggle Brea&kpoint CRulerToggleBreakpointAction_accelerator=Double Click +CAddDynamicPrintfInteractiveRulerAction_label=Add &Dynamic Printf... +CAddDynamicPrintfInteractiveRulerAction_error_message=Unable to create dynamic printf diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/CAddDynamicPrintfInteractiveRulerAction.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/CAddDynamicPrintfInteractiveRulerAction.java new file mode 100644 index 00000000000..b00dd3353d7 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/CAddDynamicPrintfInteractiveRulerAction.java @@ -0,0 +1,235 @@ +/******************************************************************************* + * Copyright (c) 2005, 2014 IBM Corporation 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: + * IBM Corporation - initial API and implementation + * Wind River Systems - added support for IToggleBreakpointsTargetFactory + * Marc Khouzam - Create class for dynamic printf (Bug 400628) + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.actions.breakpoints; + +import org.eclipse.cdt.debug.internal.ui.actions.ActionMessages; +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.cdt.debug.ui.breakpoints.IToggleBreakpointsTargetCExtension; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget; +import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetFactory; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.text.source.IVerticalRulerInfo; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.ui.texteditor.IUpdate; + +/** + * Action to interactively create a dynamic printf from the vertical ruler of a + * workbench part containing a document. The part must provide an + * IToggleBreakpointsTargetExtension2 adapter. + *

+ * Clients may instantiate this class. + *

+ * @since 7.4 + * @see org.eclipse.debug.ui.actions.RulerToggleBreakpointActionDelegate + */ +public class CAddDynamicPrintfInteractiveRulerAction extends Action implements IUpdate { + + private IWorkbenchPart fPart; + private IDocument fDocument; + private IVerticalRulerInfo fRulerInfo; + + private IToggleBreakpointsTargetCExtension fDynamicPrintfBreakpointsTarget; + + /** + * Constructs a new action to toggle a dynamic printf in the given + * part containing the given document and ruler. + * + * @param part the part in which to toggle the dynamic printf - provides + * an IToggleBreakpointsTarget adapter + * @param document the document breakpoints are being set in or + * null when the document should be derived from the given part + * @param rulerInfo specifies location the user has double-clicked + */ + public CAddDynamicPrintfInteractiveRulerAction(IWorkbenchPart part, IDocument document, IVerticalRulerInfo rulerInfo) { + super(ActionMessages.getString("CAddDynamicPrintfInteractiveRulerAction_label")); //$NON-NLS-1$ + fPart = part; + fDocument = document; + fRulerInfo = rulerInfo; + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.action.IAction#run() + */ + public void run() { + IDocument document= getDocument(); + if (document == null) { + return; + } + + int line = fRulerInfo.getLineOfLastMouseButtonActivity(); + + // Test if line is valid + if (line == -1) + return; + + try { + if (fDynamicPrintfBreakpointsTarget != null) { + ITextSelection selection = getTextSelection(document, line); + if (fDynamicPrintfBreakpointsTarget.canCreateLineBreakpointsInteractive(fPart, selection)) { + fDynamicPrintfBreakpointsTarget.createLineBreakpointsInteractive(fPart, selection); + } + } + } catch (BadLocationException e) { + reportException(e); + } catch (CoreException e) { + reportException(e); + } + } + + /** + * Report an error to the user. + * + * @param e underlying exception + */ + private void reportException(Exception e) { + IStatus status= new Status(IStatus.ERROR, CDebugUIPlugin.PLUGIN_ID, "Error creating dynamic printf: ", e); //$NON-NLS-1$ + ErrorDialog.openError( + fPart.getSite().getShell(), + ActionMessages.getString("CAddBreakpointInteractiveRulerAction_error_title"), //$NON-NLS-1$ + ActionMessages.getString("CAddDynamicPrintfInteractiveRulerAction_error_message"), //$NON-NLS-1$ + status); + CDebugUIPlugin.log(status); + } + + /** + * Disposes this action. Clients must call this method when + * this action is no longer needed. + */ + public void dispose() { + fDocument = null; + fPart = null; + fRulerInfo = null; + } + + /** + * Returns the document on which this action operates. + * + * @return the document or null if none + */ + private IDocument getDocument() { + if (fDocument != null) + return fDocument; + + if (fPart instanceof ITextEditor) { + ITextEditor editor= (ITextEditor)fPart; + IDocumentProvider provider = editor.getDocumentProvider(); + if (provider != null) + return provider.getDocument(editor.getEditorInput()); + } + + IDocument doc = (IDocument) fPart.getAdapter(IDocument.class); + if (doc != null) { + return doc; + } + + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IUpdate#update() + */ + public void update() { + IDocument document= getDocument(); + if (document != null) { + int line = fRulerInfo.getLineOfLastMouseButtonActivity(); + if (line > -1) { + try { + ITextSelection selection = getTextSelection(document, line); + + if (fDynamicPrintfBreakpointsTarget == null) { + fDynamicPrintfBreakpointsTarget = fetchDynamicPrintfBreakpointsTarget(selection); + } + + if (fDynamicPrintfBreakpointsTarget == null) { + setEnabled(false); + return; + } + if (fDynamicPrintfBreakpointsTarget.canCreateLineBreakpointsInteractive(fPart, selection)) { + setEnabled(true); + return; + } + } catch (BadLocationException e) { + reportException(e); + } + } + } + setEnabled(false); + } + + /** + * Determines the text selection for the breakpoint action. If clicking on the ruler inside + * the highlighted text, return the text selection for the highlighted text. Otherwise, + * return a text selection representing the start of the line. + * + * @param document The IDocument backing the Editor. + * @param line The line clicked on in the ruler. + * @return An ITextSelection as described. + * @throws BadLocationException If underlying operations throw. + */ + private ITextSelection getTextSelection(IDocument document, int line) throws BadLocationException { + IRegion region = document.getLineInformation(line); + ITextSelection textSelection = new TextSelection(document, region.getOffset(), 0); + ISelectionProvider provider = fPart.getSite().getSelectionProvider(); + if (provider != null){ + ISelection selection = provider.getSelection(); + if (selection instanceof ITextSelection + && ((ITextSelection) selection).getStartLine() <= line + && ((ITextSelection) selection).getEndLine() >= line) { + textSelection = (ITextSelection) selection; + } + } + return textSelection; + } + + private IToggleBreakpointsTargetCExtension fetchDynamicPrintfBreakpointsTarget(ITextSelection selection) { + if (fDynamicPrintfBreakpointsTarget == null){ + IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint(IDebugUIConstants.PLUGIN_ID, IDebugUIConstants.EXTENSION_POINT_TOGGLE_BREAKPOINTS_TARGET_FACTORIES); + IConfigurationElement[] elements = ep.getConfigurationElements(); + for (int i= 0; i < elements.length; i++) { + String id = elements[i].getAttribute("id"); //$NON-NLS-1$ + if (id != null && id.equals("org.eclipse.cdt.debug.ui.ToggleCDynamicPrintfTargetFactory")) { //$NON-NLS-1$ + try{ + Object obj = elements[i].createExecutableExtension("class"); //$NON-NLS-1$ + if(obj instanceof IToggleBreakpointsTargetFactory) { + IToggleBreakpointsTarget target = ((IToggleBreakpointsTargetFactory)obj).createToggleTarget(ToggleCDynamicPrintfTargetFactory.TOGGLE_C_DYNAMICPRINTF_TARGET_ID); + if (target instanceof IToggleBreakpointsTargetCExtension) { + fDynamicPrintfBreakpointsTarget = (IToggleBreakpointsTargetCExtension)target; + } + } + } catch (CoreException e){ + } + break; + } + } + } + return fDynamicPrintfBreakpointsTarget; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/CAddDynamicPrintfInteractiveRulerActionDelegate.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/CAddDynamicPrintfInteractiveRulerActionDelegate.java new file mode 100644 index 00000000000..6efd0b00164 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/CAddDynamicPrintfInteractiveRulerActionDelegate.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2005, 2014 IBM Corporation 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: + * IBM Corporation - initial API and implementation + * Marc Khouzam - Create class for dynamic printf (Bug 400628) + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.actions.breakpoints; + +import org.eclipse.cdt.debug.ui.breakpoints.IToggleBreakpointsTargetCExtension; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.text.source.IVerticalRulerInfo; +import org.eclipse.ui.IActionDelegate2; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.texteditor.AbstractRulerActionDelegate; +import org.eclipse.ui.texteditor.ITextEditor; + +/** + * Creates a Dynamic Printf interactively, that is with user input as well as context + * information gathered from editor location. This action delegate can be + * contributed to an editor with the editorActions extension point. + * This action is as a factory that creates another action that performs the + * actual breakpoint toggling. The created action acts on the editor's + * IToggleBreakpointsTargetCExtension to create the breakpoint. + *

+ * This action should be contributed to a vertical ruler context menu via the + * popupMenus extension point, by referencing the ruler's context + * menu identifier in the targetID attribute. + *

+ * <extension point="org.eclipse.ui.popupMenus">
+ *   <viewerContribution
+ *     targetID="example.rulerContextMenuId"
+ *     id="example.RulerPopupActions">
+ *       <action
+ *         label="Add Dynamic Printf"
+ *         class="org.eclipse.debug.ui.actions.CAddDynamicPrintfInteractiveRulerActionDelegate"
+ *         menubarPath="additions"
+ *         id="example.rulerContextMenu.createDynamicPrintfAction">
+ *       </action>
+ *   </viewerContribution>
+ * 
+ *

+ *

+ * Clients may refer to this class as an action delegate in plug-in XML. + *

+ * @see IToggleBreakpointsTargetCExtension + * @since 7.4 + * @noextend This class is not intended to be sub-classed by clients. + * @noinstantiate This class is not intended to be instantiated by clients. + */ +public class CAddDynamicPrintfInteractiveRulerActionDelegate extends AbstractRulerActionDelegate implements IActionDelegate2 { + + private IEditorPart fEditor = null; + private CAddDynamicPrintfInteractiveRulerAction fDelegate = null; + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.AbstractRulerActionDelegate#createAction(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.source.IVerticalRulerInfo) + */ + protected IAction createAction(ITextEditor editor, IVerticalRulerInfo rulerInfo) { + fDelegate = new CAddDynamicPrintfInteractiveRulerAction(editor, null, rulerInfo); + return fDelegate; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorActionDelegate#setActiveEditor(org.eclipse.jface.action.IAction, org.eclipse.ui.IEditorPart) + */ + public void setActiveEditor(IAction callerAction, IEditorPart targetEditor) { + if (fEditor != null) { + if (fDelegate != null) { + fDelegate.dispose(); + fDelegate = null; + } + } + fEditor = targetEditor; + super.setActiveEditor(callerAction, targetEditor); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate2#init(org.eclipse.jface.action.IAction) + */ + public void init(IAction action) { + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate2#dispose() + */ + public void dispose() { + if (fDelegate != null) { + fDelegate.dispose(); + } + fDelegate = null; + fEditor = null; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/Messages.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/Messages.java new file mode 100644 index 00000000000..432af8fa19c --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/Messages.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.actions.breakpoints; + + +import org.eclipse.osgi.util.NLS; + +public class Messages extends NLS { + + public static String Default_LineDynamicPrintf_String; + public static String Default_FunctionDynamicPrintf_String; + + static { + NLS.initializeMessages(Messages.class.getName(), Messages.class); + } + + private Messages() { + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/Messages.properties b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/Messages.properties new file mode 100644 index 00000000000..6344323e204 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/Messages.properties @@ -0,0 +1,16 @@ +####################################################################################### +# Copyright (c) 2014 Ericsson 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: +# Marc Khouzam (Ericsson) - Initial API and implementation +####################################################################################### + +# We use %d in the below string on purpose to show the user that it is possible +# Don't use %s with an in-line string, as it crashes GDB 7.5 and 7.6 +# http://sourceware.org/bugzilla/show_bug.cgi?id=15433 +Default_LineDynamicPrintf_String="Hit line %d of {0}\\n",{1} +Default_FunctionDynamicPrintf_String="Entered function: {1} of {0}\\n" diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/ToggleCDynamicPrintfTargetFactory.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/ToggleCDynamicPrintfTargetFactory.java new file mode 100644 index 00000000000..4453b778e9e --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/ToggleCDynamicPrintfTargetFactory.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.actions.breakpoints; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.cdt.debug.internal.ui.actions.ActionMessages; +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget; +import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetFactory; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IWorkbenchPart; + +/** + * Toggle Dynamic Printf target factory for the CEditor. + * + * @since 7.5 + */ +public class ToggleCDynamicPrintfTargetFactory implements IToggleBreakpointsTargetFactory { + + public static String TOGGLE_C_DYNAMICPRINTF_TARGET_ID = CDebugUIPlugin.getUniqueIdentifier() + ".toggleCDynamicPrintfTarget"; //$NON-NLS-1$ + + private static Set TOGGLE_TARGET_IDS = new HashSet(1); + static { + TOGGLE_TARGET_IDS.add(TOGGLE_C_DYNAMICPRINTF_TARGET_ID); + } + + private ToggleDynamicPrintfAdapter fCToggleDynamicPrintfTarget = new ToggleDynamicPrintfAdapter(); + + @Override + public IToggleBreakpointsTarget createToggleTarget(String targetID) { + if (TOGGLE_C_DYNAMICPRINTF_TARGET_ID.equals(targetID)) { + return fCToggleDynamicPrintfTarget; + } + return null; + } + + @Override + public String getDefaultToggleTarget(IWorkbenchPart part, ISelection selection) { + return null; + } + + @Override + public String getToggleTargetDescription(String targetID) { + if (TOGGLE_C_DYNAMICPRINTF_TARGET_ID.equals(targetID)) { + return ActionMessages.getString("ToggleCBreakpointsTargetFactory.CDynamicPrintfDescription"); //$NON-NLS-1$ + } + return null; + } + + @Override + public String getToggleTargetName(String targetID) { + if (TOGGLE_C_DYNAMICPRINTF_TARGET_ID.equals(targetID)) { + return ActionMessages.getString("ToggleCBreakpointsTargetFactory.CDynamicPrintfName"); //$NON-NLS-1$ + } + return null; + } + + @Override + public Set getToggleTargets(IWorkbenchPart part, ISelection selection) { + return TOGGLE_TARGET_IDS; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/ToggleDynamicPrintfAdapter.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/ToggleDynamicPrintfAdapter.java new file mode 100644 index 00000000000..f8525e03205 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/breakpoints/ToggleDynamicPrintfAdapter.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.actions.breakpoints; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.debug.core.CDIDebugModel; +import org.eclipse.cdt.debug.core.model.ICBreakpointType; +import org.eclipse.cdt.debug.core.model.ICDynamicPrintf; +import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint; +import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; +import org.eclipse.cdt.debug.core.model.ICWatchpoint; +import org.eclipse.cdt.debug.ui.breakpoints.AbstractToggleBreakpointAdapter; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.osgi.util.NLS; +import org.eclipse.ui.IWorkbenchPart; + +/** + * Toggles a dynamic printf in a C/C++ editor. + * + * @since 7.5 + */ +public class ToggleDynamicPrintfAdapter extends AbstractToggleBreakpointAdapter { + + @Override + protected ICLineBreakpoint findLineBreakpoint( String sourceHandle, IResource resource, int lineNumber ) throws CoreException { + return CDIDebugModel.lineBreakpointExists( sourceHandle, resource, lineNumber ); + } + + @Override + protected void createLineBreakpoint(boolean interactive, IWorkbenchPart part, String sourceHandle, + IResource resource, int lineNumber) throws CoreException + { + if (interactive) { + ICDynamicPrintf dprintf = (ICDynamicPrintf)CDIDebugModel.createBlankLineDynamicPrintf(); + Map attributes = new HashMap(); + CDIDebugModel.setLineBreakpointAttributes( + attributes, sourceHandle, getBreakpointType(), lineNumber, true, 0, "" ); //$NON-NLS-1$ + + // Although the user will be given the opportunity to provide the printf string + // in the properties dialog, we pre-fill it with the default string to be nice + attributes.put(ICDynamicPrintf.PRINTF_STRING, + NLS.bind(Messages.Default_LineDynamicPrintf_String, sourceHandle, lineNumber)); + + openBreakpointPropertiesDialog(dprintf, part, resource, attributes); + } else { + // We provide a default printf string to make the dynamic printf useful automatically + String printfStr = NLS.bind(Messages.Default_LineDynamicPrintf_String, sourceHandle, lineNumber); + + CDIDebugModel.createLineDynamicPrintf( + sourceHandle, resource, getBreakpointType(), lineNumber, true, 0, "", printfStr, true );//$NON-NLS-1$ + } + } + + @Override + protected ICFunctionBreakpoint findFunctionBreakpoint( String sourceHandle, IResource resource, String functionName ) throws CoreException { + return CDIDebugModel.functionBreakpointExists( sourceHandle, resource, functionName ); + } + + @Override + protected void createFunctionBreakpoint(boolean interactive, IWorkbenchPart part, String sourceHandle, + IResource resource, String functionName, int charStart, int charEnd, int lineNumber ) throws CoreException + { + if (interactive) { + ICDynamicPrintf dprintf = (ICDynamicPrintf)CDIDebugModel.createBlankFunctionDynamicPrintf(); + Map attributes = new HashMap(); + CDIDebugModel.setFunctionBreakpointAttributes( attributes, sourceHandle, getBreakpointType(), functionName, + charStart, charEnd, lineNumber, true, 0, "" ); //$NON-NLS-1$ + + // Although the user will be given the opportunity to provide the printf string + // in the properties dialog, we pre-fill it with the default string to be nice + dprintf.setPrintfString(NLS.bind(Messages.Default_FunctionDynamicPrintf_String, sourceHandle, functionName)); + + openBreakpointPropertiesDialog(dprintf, part, resource, attributes); + } else { + // We provide a default printf string to make the dynamic printf useful automatically + String printfStr = NLS.bind(Messages.Default_FunctionDynamicPrintf_String, sourceHandle, functionName); + + CDIDebugModel.createFunctionDynamicPrintf(sourceHandle, resource, getBreakpointType(), functionName, charStart, + charEnd, lineNumber, true, 0, "", printfStr, true); //$NON-NLS-1$ + } + } + + @Override + protected ICWatchpoint findWatchpoint( String sourceHandle, IResource resource, String expression ) throws CoreException { + return null; + } + + @Override + public boolean canToggleWatchpoints(IWorkbenchPart part, ISelection selection) { + return false; + } + + protected void createWatchpoint( boolean interactive, IWorkbenchPart part, String sourceHandle, IResource resource, + int charStart, int charEnd, int lineNumber, String expression, String memorySpace, String range) throws CoreException + { + } + + @Override + public boolean canCreateEventBreakpointsInteractive(IWorkbenchPart part, ISelection selection) { + return false; + } + + @Override + protected void createEventBreakpoint(boolean interactive, IWorkbenchPart part, IResource resource, String type, + String arg) throws CoreException { + + } + + protected int getBreakpointType() { + return ICBreakpointType.REGULAR; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/BreakpointsMessages.properties b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/BreakpointsMessages.properties index 1877790d4f4..72affd1a867 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/BreakpointsMessages.properties +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/BreakpointsMessages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2003, 2009 QNX Software Systems and others. +# Copyright (c) 2003, 2014 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 @@ -9,6 +9,7 @@ # QNX Software Systems - initial API and implementation # Nokia - https://bugs.eclipse.org/bugs/show_bug.cgi?id=145606 # IBM Corporation +# Marc Khouzam (Ericsson) - Added dynamic printf support (400628) ############################################################################### CBreakpointPropertyPage.0=Ignore count must be a nonnegative integer @@ -45,3 +46,7 @@ ThreadFilterEditor.0=&Restrict to Selected Targets and Threads: TracepointPropertyPage.tracepointType_function_label=C/C++ Function Tracepoint TracepointPropertyPage.tracepointType_address_label=C/C++ Address Tracepoint TracepointPropertyPage.tracepointType_line_label=C/C++ Line Tracepoint + +DPrintfPropertyPage.dprintfType_function_label=C/C++ Function Dynamic Printf +DPrintfPropertyPage.dprintfType_address_label=C/C++ Address Dynamic Printf +DPrintfPropertyPage.dprintfType_line_label=C/C++ Line Dynamic Printf diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointContext.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointContext.java index 5e94f2860eb..4801540779c 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointContext.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointContext.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 Wind River Systems and others. + * Copyright (c) 2007, 2014 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 @@ -8,6 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation * Ericsson - Added tracepoint support (284286) + * Marc Khouzam (Ericsson) - Added dynamic printf support (400628) *******************************************************************************/ package org.eclipse.cdt.debug.internal.ui.breakpoints; @@ -16,6 +17,7 @@ import java.util.Map; import org.eclipse.cdt.debug.core.CDIDebugModel; import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint; import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.cdt.debug.core.model.ICDynamicPrintf; import org.eclipse.cdt.debug.core.model.ICEventBreakpoint; import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; @@ -178,19 +180,25 @@ class CBreakpointContextWorkbenchAdapter implements IWorkbenchAdapter { private String getBreakpointMainLabel(ICBreakpoint breakpoint) { if (breakpoint instanceof ICFunctionBreakpoint) { if (breakpoint instanceof ICTracepoint) { - return BreakpointsMessages.getString("TracepointPropertyPage.tracepointType_function_label"); //$NON-NLS-1$ + return BreakpointsMessages.getString("TracepointPropertyPage.tracepointType_function_label"); //$NON-NLS-1$ + } else if (breakpoint instanceof ICDynamicPrintf) { + return BreakpointsMessages.getString("DPrintfPropertyPage.dprintfType_function_label"); //$NON-NLS-1$ } else { return BreakpointsMessages.getString("CBreakpointPropertyPage.breakpointType_function_label"); //$NON-NLS-1$ } } else if (breakpoint instanceof ICAddressBreakpoint) { if (breakpoint instanceof ICTracepoint) { return BreakpointsMessages.getString("TracepointPropertyPage.tracepointType_address_label"); //$NON-NLS-1$ + } else if (breakpoint instanceof ICDynamicPrintf) { + return BreakpointsMessages.getString("DPrintfPropertyPage.dprintfType_address_label"); //$NON-NLS-1$ } else { return BreakpointsMessages.getString("CBreakpointPropertyPage.breakpointType_address_label"); //$NON-NLS-1$ } } else if (breakpoint instanceof ICLineBreakpoint) { if (breakpoint instanceof ICTracepoint) { return BreakpointsMessages.getString("TracepointPropertyPage.tracepointType_line_label"); //$NON-NLS-1$ + } else if (breakpoint instanceof ICDynamicPrintf) { + return BreakpointsMessages.getString("DPrintfPropertyPage.dprintfType_line_label"); //$NON-NLS-1$ } else { return BreakpointsMessages.getString("CBreakpointPropertyPage.breakpointType_line_label"); //$NON-NLS-1$ } @@ -212,8 +220,8 @@ class CBreakpointContextWorkbenchAdapter implements IWorkbenchAdapter { class CBreakpointContextAdapterFactory implements IAdapterFactory { private static final Class[] fgAdapterList = new Class[] { - IBreakpoint.class, ICBreakpoint.class, ICTracepoint.class, IActionFilter.class, IPreferenceStore.class, - IWorkbenchAdapter.class, + IBreakpoint.class, ICBreakpoint.class, ICTracepoint.class, ICDynamicPrintf.class, + IActionFilter.class, IPreferenceStore.class, IWorkbenchAdapter.class, }; private static final IActionFilter fgActionFilter = new CBreakpointContextActionFilter(); diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointPreferenceStore.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointPreferenceStore.java index 468898d3e8b..72495eb3a45 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointPreferenceStore.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointPreferenceStore.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 QNX Software Systems and others. + * Copyright (c) 2000, 2014 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 @@ -9,6 +9,7 @@ * QNX Software Systems - Initial API and implementation * QNX Software Systems - Refactored to use platform implementation * Marc Khouzam (Ericsson) - Added support for Tracepoints (bug 376116) + * Marc Khouzam (Ericsson) - Added support for Dynamic-Printf (bug 400628) *******************************************************************************/ package org.eclipse.cdt.debug.internal.ui.breakpoints; @@ -24,6 +25,7 @@ import java.util.Set; import org.eclipse.cdt.debug.core.CDIDebugModel; import org.eclipse.cdt.debug.core.model.ICBreakpoint; import org.eclipse.cdt.debug.core.model.ICBreakpoint2; +import org.eclipse.cdt.debug.core.model.ICDynamicPrintf; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint2; import org.eclipse.cdt.debug.core.model.ICTracepoint; import org.eclipse.core.resources.IMarker; @@ -39,8 +41,8 @@ import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; /** - * A preference store that presents the state of the properties of a C/C++ breakpoint - * or Tracepoint. + * A preference store that presents the state of the properties of a C/C++ breakpoint, + * tracepoint or dynamic-printf. */ public class CBreakpointPreferenceStore implements IPersistentPreferenceStore { @@ -138,6 +140,9 @@ public class CBreakpointPreferenceStore implements IPersistentPreferenceStore { else if ( breakpoint instanceof ICTracepoint && property.equals( ICTracepoint.PASS_COUNT ) ) { ((ICTracepoint)breakpoint).setPassCount( getInt( ICTracepoint.PASS_COUNT ) ); } + else if ( breakpoint instanceof ICDynamicPrintf && property.equals( ICDynamicPrintf.PRINTF_STRING ) ) { + ((ICDynamicPrintf)breakpoint).setPrintfString( getString( ICDynamicPrintf.PRINTF_STRING ) ); + } else if ( property.equals( ICBreakpoint.CONDITION ) ) { breakpoint.setCondition( getString( ICBreakpoint.CONDITION ) ); } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.properties b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.properties index 219fa516a90..ecfaccb4c67 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.properties +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2008, 2012 Ericsson and others. +# Copyright (c) 2008, 2014 Ericsson 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 @@ -10,6 +10,7 @@ # IBM Corporation # Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121) # Vladimir Prus (Mentor Graphics) - OS Resources view (bug 360314) +# Marc Khouzam (Ericsson) - Support for dynamic printf (bug 400628) ############################################################################### pluginName=GDB DSF Debugger Integration UI providerName=Eclipse CDT @@ -28,6 +29,8 @@ tracepoints.property.common=Common tracepoints.property.actions=Actions tracepoints.action.page.label=Actions tracepointActionsPrefPage.name=Tracepoint Actions +dynamicPrintf.property.common=Common +action.addDynamicPrintf.label=Add Dynamic-Printf... # Tracepoints view.traceControl.name=Trace Control diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml index 8e3c48eb152..766bd9c6138 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml @@ -200,6 +200,19 @@ + + + + + + + + + + +
@@ -420,6 +433,16 @@ menubarPath="renderGroup"> + + + + + + + + + + diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/DisassemblyToggleDynamicPrintfTarget.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/DisassemblyToggleDynamicPrintfTarget.java new file mode 100644 index 00000000000..109c8055a1a --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/DisassemblyToggleDynamicPrintfTarget.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.breakpoints; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.core.CDIDebugModel; +import org.eclipse.cdt.debug.core.model.ICBreakpointType; +import org.eclipse.cdt.debug.core.model.ICDynamicPrintf; +import org.eclipse.cdt.dsf.debug.ui.actions.AbstractDisassemblyBreakpointsTarget; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.osgi.util.NLS; +import org.eclipse.ui.IWorkbenchPart; + +/** + * Toggle dynamic printf target implementation for the disassembly part. + */ +public class DisassemblyToggleDynamicPrintfTarget extends AbstractDisassemblyBreakpointsTarget { + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.AbstractDisassemblyBreakpointsTarget#createLineBreakpoint(java.lang.String, org.eclipse.core.resources.IResource, int) + */ + @Override + protected void createLineBreakpoint(String sourceHandle, IResource resource, int lineNumber) throws CoreException { + // We provide a default printf string to make the dynamic printf useful automatically + String printfStr = NLS.bind(Messages.Default_LineDynamicPrintf_String, sourceHandle, lineNumber); + + CDIDebugModel.createLineDynamicPrintf(sourceHandle, resource, getBreakpointType(), lineNumber, true, 0, "", printfStr, true); //$NON-NLS-1$ + } + + @Override + protected void createLineBreakpointInteractive(IWorkbenchPart part, String sourceHandle, IResource resource, int lineNumber) + throws CoreException + { + ICDynamicPrintf dprintf = (ICDynamicPrintf)CDIDebugModel.createBlankLineDynamicPrintf(); + Map attributes = new HashMap(); + CDIDebugModel.setLineBreakpointAttributes( + attributes, sourceHandle, getBreakpointType(), lineNumber, true, 0, "" ); //$NON-NLS-1$ + + // Although the user will be given the opportunity to provide the printf string + // in the properties dialog, we pre-fill it with the default string to be nice. + attributes.put(ICDynamicPrintf.PRINTF_STRING, + NLS.bind(Messages.Default_LineDynamicPrintf_String, sourceHandle, lineNumber)); + + openBreakpointPropertiesDialog(dprintf, part, resource, attributes); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.AbstractDisassemblyBreakpointsTarget#createAddressBreakpoint(org.eclipse.core.resources.IResource, org.eclipse.cdt.core.IAddress) + */ + @Override + protected void createAddressBreakpoint(IResource resource, IAddress address) throws CoreException { + // We provide a default printf string to make the dynamic printf useful automatically + String printfStr = NLS.bind(Messages.Default_AddressDynamicPrintf_String, address); + + CDIDebugModel.createAddressDynamicPrintf(null, null, resource, getBreakpointType(), -1, address, true, 0, "", printfStr, true); //$NON-NLS-1$ + } + + @Override + protected void createAddressBreakpointInteractive(IWorkbenchPart part, IResource resource, IAddress address) + throws CoreException + { + ICDynamicPrintf dprintf = (ICDynamicPrintf)CDIDebugModel.createBlankAddressDynamicPrintf(); + Map attributes = new HashMap(); + CDIDebugModel.setAddressBreakpointAttributes( + attributes, null, null, getBreakpointType(), -1, address, true, 0, "" ); //$NON-NLS-1$ + + // Although the user will be given the opportunity to provide the printf string + // in the properties dialog, we pre-fill it with the default string to be nice + attributes.put(ICDynamicPrintf.PRINTF_STRING, + NLS.bind(Messages.Default_AddressDynamicPrintf_String, address)); + + openBreakpointPropertiesDialog(dprintf, part, resource, attributes); + } + + protected int getBreakpointType() { + return ICBreakpointType.REGULAR; + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/GDBDynamicPrintfPropertyPage.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/GDBDynamicPrintfPropertyPage.java new file mode 100644 index 00000000000..66c6b89d792 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/GDBDynamicPrintfPropertyPage.java @@ -0,0 +1,423 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.breakpoints; + +import org.eclipse.cdt.debug.core.CDIDebugModel; +import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint; +import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.cdt.debug.core.model.ICDynamicPrintf; +import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint; +import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; +import org.eclipse.cdt.debug.internal.ui.breakpoints.CBreakpointContext; +import org.eclipse.cdt.debug.internal.ui.breakpoints.CBreakpointPreferenceStore; +import org.eclipse.cdt.debug.ui.breakpoints.ICBreakpointContext; +import org.eclipse.cdt.debug.ui.preferences.ReadOnlyFieldEditor; +import org.eclipse.cdt.dsf.gdb.breakpoints.GDBDynamicPrintfUtils; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.model.IDebugElement; +import org.eclipse.debug.core.model.IDebugModelProvider; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.contexts.IDebugContextProvider; +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.IntegerFieldEditor; +import org.eclipse.jface.preference.StringFieldEditor; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbenchPropertyPage; +import org.eclipse.ui.model.IWorkbenchAdapter; + +/** + * The preference page used to present the properties of a GDB dynamic printf as preferences. + */ +public class GDBDynamicPrintfPropertyPage extends FieldEditorPreferencePage implements IWorkbenchPropertyPage { + + private class DynamicPrintfIntegerFieldEditor extends IntegerFieldEditor { + + public DynamicPrintfIntegerFieldEditor(String name, String labelText, Composite parent) { + super(name, labelText, parent); + setErrorMessage(Messages.PropertyPage_integer_negative); + } + + /** + * @see IntegerFieldEditor#checkState() + */ + @Override + protected boolean checkState() { + Text control = getTextControl(); + if (!control.isEnabled()) { + clearErrorMessage(); + return true; + } + return super.checkState(); + } + + /** + * Only store if the text control is enabled + * + * @see FieldEditor#doStore() + */ + @Override + protected void doStore() { + Text text = getTextControl(); + if (text.isEnabled()) { + super.doStore(); + } + } + + /** + * Clears the error message from the message line if the error message is the error message from this field editor. + */ + @Override + protected void clearErrorMessage() { + if (getPage() != null) { + String message = getPage().getErrorMessage(); + if ( message != null ) { + if (getErrorMessage().equals(message)) { + super.clearErrorMessage(); + } + } + else { + super.clearErrorMessage(); + } + } + } + } + + class DynamicPrintfStringFieldEditor extends StringFieldEditor { + + public DynamicPrintfStringFieldEditor(String name, String labelText, Composite parent) { + super(name, labelText, parent); + } + + /** + * @see StringFieldEditor#checkState() + */ + @Override + protected boolean checkState() { + Text control = getTextControl(); + if (!control.isEnabled()) { + clearErrorMessage(); + return true; + } + return super.checkState(); + } + + @Override + protected void doStore() { + Text text = getTextControl(); + if (text.isEnabled()) { + super.doStore(); + } + } + + @Override + protected void doLoad() { + String value = getPreferenceStore().getString(getPreferenceName()); + setStringValue(value); + } + + /** + * Clears the error message from the message line if the error message is the error message from this field editor. + */ + @Override + protected void clearErrorMessage() { + if (getPage() != null) { + String message = getPage().getErrorMessage(); + if ( message != null ) { + if (getErrorMessage().equals(message)) { + super.clearErrorMessage(); + } + } + else { + super.clearErrorMessage(); + } + } + } + } + + private class LabelFieldEditor extends ReadOnlyFieldEditor { + private String fValue; + + public LabelFieldEditor(Composite parent, String title, String value) { + super(title, title, parent); + fValue = value; + } + + @Override + protected void doLoad() { + if (textField != null) { + textField.setText(fValue); + } + } + @Override + protected void doLoadDefault() { + // nothing + } + + } + + private BooleanFieldEditor fEnabled; + + private DynamicPrintfStringFieldEditor fCondition; + + private Text fIgnoreCountTextControl; + private DynamicPrintfIntegerFieldEditor fIgnoreCount; + + private DynamicPrintfStringFieldEditor fPrintString; + + private IAdaptable fElement; + + /** + * The preference store used to interface between the dynamic printf and the + * dynamic printf preference page. This preference store is initialized only + * when the preference store cannot be retrieved from the preference + * dialog's element. + * @see #getPreferenceStore() + */ + private CBreakpointPreferenceStore fDynamicPrintfPreferenceStore; + + public GDBDynamicPrintfPropertyPage() { + super(GRID); + noDefaultAndApplyButton(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.preference.FieldEditorPreferencePage#createFieldEditors() + */ + @Override + protected void createFieldEditors() { + ICDynamicPrintf dprintf = getDprintf(); + createMainLabel(dprintf); + createTypeSpecificLabelFieldEditors(dprintf); + createEnabledField(getFieldEditorParent()); + createConditionEditor(getFieldEditorParent()); + createIgnoreCountEditor(getFieldEditorParent()); + createPrintStringEditor(getFieldEditorParent()); + } + + private void createMainLabel(ICDynamicPrintf dprintf) { + addField(createLabelEditor(getFieldEditorParent(), + Messages.PropertyPage_Class, + getDynamicPrintfMainLabel(dprintf))); + } + + private void createTypeSpecificLabelFieldEditors(ICDynamicPrintf dprintf) { + if (dprintf instanceof ICFunctionBreakpoint) { + createFunctionEditor(getFieldEditorParent()); + } + else if (dprintf instanceof ICAddressBreakpoint) { + String address = getPreferenceStore().getString(ICLineBreakpoint.ADDRESS); + if (address == null || address.trim().length() == 0) { + address = Messages.PropertyPage_NotAvailable; + } + addField(createLabelEditor(getFieldEditorParent(), Messages.PropertyPage_Address, address)); + } + else { // LineDprintf + String fileName = getPreferenceStore().getString(ICBreakpoint.SOURCE_HANDLE); + if (fileName != null) { + addField(createLabelEditor(getFieldEditorParent(), Messages.PropertyPage_File, fileName)); + } + int lNumber = getPreferenceStore().getInt(IMarker.LINE_NUMBER); + if (lNumber > 0) { + createLineNumberEditor(getFieldEditorParent()); + } + } + } + + private String getDynamicPrintfMainLabel(ICDynamicPrintf dprintf) { + IWorkbenchAdapter labelProvider = (IWorkbenchAdapter)getElement().getAdapter(IWorkbenchAdapter.class); + if (labelProvider != null) { + return labelProvider.getLabel(getElement()); + } + // default main label is the label of marker type for the dynamic printf + return CDIDebugModel.calculateMarkerType(dprintf); + } + + protected void createFunctionEditor(Composite parent) { + ICDynamicPrintf dprintf = getDprintf(); + if (dprintf == null || dprintf.getMarker() == null) { + DynamicPrintfStringFieldEditor expressionEditor = new DynamicPrintfStringFieldEditor( + ICLineBreakpoint.FUNCTION, Messages.PropertyPage_FunctionName, parent); + expressionEditor.setErrorMessage(Messages.PropertyPage_function_value_errorMessage); + expressionEditor.setEmptyStringAllowed(false); + addField(expressionEditor); + } else { + String function = getPreferenceStore().getString(ICLineBreakpoint.FUNCTION); + if (function == null) { + function = Messages.PropertyPage_NotAvailable; + } + addField(createLabelEditor(getFieldEditorParent(), Messages.PropertyPage_FunctionName, function)); + } + } + protected void createLineNumberEditor(Composite parent) { + String title = Messages.PropertyPage_LineNumber; + DynamicPrintfIntegerFieldEditor labelFieldEditor = new DynamicPrintfIntegerFieldEditor(IMarker.LINE_NUMBER, title, parent); + labelFieldEditor.setValidRange(1, Integer.MAX_VALUE); + addField(labelFieldEditor); + } + + protected void createEnabledField(Composite parent) { + fEnabled = new BooleanFieldEditor(ICBreakpoint.ENABLED, Messages.PropertyPage_Enabled, parent); + addField(fEnabled); + } + + protected void createConditionEditor(Composite parent) { + fCondition = new DynamicPrintfStringFieldEditor(ICBreakpoint.CONDITION, Messages.PropertyPage_Condition, parent); + fCondition.setEmptyStringAllowed(true); + fCondition.setErrorMessage(Messages.PropertyPage_InvalidCondition); + addField(fCondition); + } + + protected void createIgnoreCountEditor(Composite parent) { + fIgnoreCount = new DynamicPrintfIntegerFieldEditor(ICBreakpoint.IGNORE_COUNT, Messages.PropertyPage_IgnoreCount, parent); + fIgnoreCount.setValidRange(0, Integer.MAX_VALUE); + fIgnoreCountTextControl = fIgnoreCount.getTextControl(parent); + fIgnoreCountTextControl.setEnabled( getPreferenceStore().getInt(ICBreakpoint.IGNORE_COUNT) >= 0 ); + addField(fIgnoreCount); + } + + protected void createPrintStringEditor(Composite parent) { + fPrintString = new DynamicPrintfStringFieldEditor(ICDynamicPrintf.PRINTF_STRING, Messages.DynamicPrintfPropertyPage_PrintString, parent) { + @Override + protected boolean doCheckState() { + GDBDynamicPrintfUtils.GDBDynamicPrintfString parsedStr = + new GDBDynamicPrintfUtils.GDBDynamicPrintfString(getTextControl().getText()); + + boolean valid = parsedStr.isValid(); + if (!valid) { + setErrorMessage(parsedStr.getErrorMessage()); + } + + return valid; + } + }; + addField(fPrintString); + } + + protected FieldEditor createLabelEditor(Composite parent, String title, String value) { + return new LabelFieldEditor(parent, title, value); + } + + protected ICDynamicPrintf getDprintf() { + IAdaptable element = getElement(); + if (element instanceof ICDynamicPrintf) { + return (ICDynamicPrintf)element; + } + + if (element instanceof ICBreakpointContext) { + ICBreakpoint breakpoint =((ICBreakpointContext)element).getBreakpoint(); + if (breakpoint instanceof ICDynamicPrintf) { + return (ICDynamicPrintf)breakpoint; + } + assert false : "Should always have a dprintf"; //$NON-NLS-1$ + } + + return (ICDynamicPrintf)element.getAdapter(ICDynamicPrintf.class); + } + + protected Object getDebugContext() { + IDebugContextProvider provider = (IDebugContextProvider)getElement().getAdapter(IDebugContextProvider.class); + if (provider != null) { + ISelection selection = provider.getActiveContext(); + if (selection instanceof IStructuredSelection) { + return ((IStructuredSelection) selection).getFirstElement(); + } + return null; + } + return DebugUITools.getDebugContext(); + } + + + protected IResource getResource() { + IAdaptable element = getElement(); + if (element instanceof ICDynamicPrintf) { + IMarker marker = ((ICDynamicPrintf)element).getMarker(); + if (marker != null) { + return marker.getResource(); + } + } else if (element instanceof ICBreakpointContext) { + return ((ICBreakpointContext)element).getResource(); + } + return null; + } + + @Override + public IPreferenceStore getPreferenceStore() { + IAdaptable element = getElement(); + if (element instanceof ICBreakpointContext) { + return ((ICBreakpointContext)element).getPreferenceStore(); + } + + if (fDynamicPrintfPreferenceStore == null) { + CBreakpointContext bpContext = element instanceof CBreakpointContext ? + (CBreakpointContext)element : null; + fDynamicPrintfPreferenceStore = new CBreakpointPreferenceStore(bpContext, null); + } + return fDynamicPrintfPreferenceStore; + } + + @Override + public boolean performCancel() { + IPreferenceStore store = getPreferenceStore(); + if (store instanceof CBreakpointPreferenceStore) { + ((CBreakpointPreferenceStore)store).setCanceled(true); + } + return super.performCancel(); + } + + @Override + public boolean performOk() { + IPreferenceStore store = getPreferenceStore(); + if (store instanceof CBreakpointPreferenceStore) { + ((CBreakpointPreferenceStore)store).setCanceled(false); + } + return super.performOk(); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchPropertyPage#getElement() + */ + @Override + public IAdaptable getElement() { + return fElement; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchPropertyPage#setElement(org.eclipse.core.runtime.IAdaptable) + */ + @Override + public void setElement(IAdaptable element) { + fElement = element; + } + + protected String[] getDebugModelIds() { + String[] debugModelIds = null; + Object debugContext = getDebugContext(); + IDebugModelProvider debugModelProvider = (IDebugModelProvider) + DebugPlugin.getAdapter(debugContext, IDebugModelProvider.class); + if (debugModelProvider != null) { + debugModelIds = debugModelProvider.getModelIdentifiers(); + } else if (debugContext instanceof IDebugElement) { + debugModelIds = new String[] { ((IDebugElement)debugContext).getModelIdentifier() }; + } + return debugModelIds; + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/GDBTracepointPropertyPage.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/GDBTracepointPropertyPage.java index 9567949d65f..306e281ad6d 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/GDBTracepointPropertyPage.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/GDBTracepointPropertyPage.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2013 Ericsson and others. + * Copyright (c) 2009, 2014 Ericsson 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 @@ -9,6 +9,7 @@ * Ericsson - Initial API and implementation * Marc Khouzam (Ericsson) - Updated to allow updating properties * before creating the tracepoint (Bug 376116) + * Marc Khouzam (Ericsson) - Support for dynamic printf (bug 400628) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.internal.ui.breakpoints; @@ -45,7 +46,6 @@ import org.eclipse.ui.model.IWorkbenchAdapter; /** * The preference page used to present the properties of a GDB tracepoint as preferences. - * A TracepointPreferenceStore is used to interface between this page and the tracepoint. */ public class GDBTracepointPropertyPage extends FieldEditorPreferencePage implements IWorkbenchPropertyPage { @@ -53,7 +53,7 @@ public class GDBTracepointPropertyPage extends FieldEditorPreferencePage impleme public TracepointIntegerFieldEditor(String name, String labelText, Composite parent) { super(name, labelText, parent); - setErrorMessage(Messages.TracepointPropertyPage_integer_negative); + setErrorMessage(Messages.PropertyPage_integer_negative); } /** @@ -223,7 +223,7 @@ public class GDBTracepointPropertyPage extends FieldEditorPreferencePage impleme private void createMainLabel(ICTracepoint tracepoint) { addField(createLabelEditor(getFieldEditorParent(), - Messages.TracepointPropertyPage_Class, + Messages.PropertyPage_Class, getTracepointMainLabel(tracepoint))); } @@ -234,14 +234,14 @@ public class GDBTracepointPropertyPage extends FieldEditorPreferencePage impleme else if (tracepoint instanceof ICAddressBreakpoint) { String address = getPreferenceStore().getString(ICLineBreakpoint.ADDRESS); if (address == null || address.trim().length() == 0) { - address = Messages.TracepointPropertyPage_NotAvailable; + address = Messages.PropertyPage_NotAvailable; } - addField(createLabelEditor(getFieldEditorParent(), Messages.TracepointPropertyPage_Address, address)); + addField(createLabelEditor(getFieldEditorParent(), Messages.PropertyPage_Address, address)); } else { // LineTracepoint String fileName = getPreferenceStore().getString(ICBreakpoint.SOURCE_HANDLE); if (fileName != null) { - addField(createLabelEditor(getFieldEditorParent(), Messages.TracepointPropertyPage_File, fileName)); + addField(createLabelEditor(getFieldEditorParent(), Messages.PropertyPage_File, fileName)); } int lNumber = getPreferenceStore().getInt(IMarker.LINE_NUMBER); if (lNumber > 0) { @@ -263,39 +263,39 @@ public class GDBTracepointPropertyPage extends FieldEditorPreferencePage impleme ICTracepoint tracepoint = getTracepoint(); if (tracepoint == null || tracepoint.getMarker() == null) { TracepointStringFieldEditor expressionEditor = new TracepointStringFieldEditor( - ICLineBreakpoint.FUNCTION, Messages.TracepointPropertyPage_FunctionName, parent); - expressionEditor.setErrorMessage(Messages.TracepointPropertyPage_function_value_errorMessage); + ICLineBreakpoint.FUNCTION, Messages.PropertyPage_FunctionName, parent); + expressionEditor.setErrorMessage(Messages.PropertyPage_function_value_errorMessage); expressionEditor.setEmptyStringAllowed(false); addField(expressionEditor); } else { String function = getPreferenceStore().getString(ICLineBreakpoint.FUNCTION); if (function == null) { - function = Messages.TracepointPropertyPage_NotAvailable; + function = Messages.PropertyPage_NotAvailable; } - addField(createLabelEditor(getFieldEditorParent(), Messages.TracepointPropertyPage_FunctionName, function)); + addField(createLabelEditor(getFieldEditorParent(), Messages.PropertyPage_FunctionName, function)); } } protected void createLineNumberEditor(Composite parent) { - String title = Messages.TracepointPropertyPage_LineNumber; + String title = Messages.PropertyPage_LineNumber; TracepointIntegerFieldEditor labelFieldEditor = new TracepointIntegerFieldEditor(IMarker.LINE_NUMBER, title, parent); labelFieldEditor.setValidRange(1, Integer.MAX_VALUE); addField(labelFieldEditor); } protected void createEnabledField(Composite parent) { - fEnabled = new BooleanFieldEditor(ICBreakpoint.ENABLED, Messages.TracepointPropertyPage_Enabled, parent); + fEnabled = new BooleanFieldEditor(ICBreakpoint.ENABLED, Messages.PropertyPage_Enabled, parent); addField(fEnabled); } protected void createConditionEditor(Composite parent) { - fCondition = new TracepointStringFieldEditor(ICBreakpoint.CONDITION, Messages.TracepointPropertyPage_Condition, parent); + fCondition = new TracepointStringFieldEditor(ICBreakpoint.CONDITION, Messages.PropertyPage_Condition, parent); fCondition.setEmptyStringAllowed(true); - fCondition.setErrorMessage(Messages.TracepointPropertyPage_InvalidCondition); + fCondition.setErrorMessage(Messages.PropertyPage_InvalidCondition); addField(fCondition); } protected void createIgnoreCountEditor(Composite parent) { - fIgnoreCount = new TracepointIntegerFieldEditor(ICBreakpoint.IGNORE_COUNT, Messages.TracepointPropertyPage_IgnoreCount, parent); + fIgnoreCount = new TracepointIntegerFieldEditor(ICBreakpoint.IGNORE_COUNT, Messages.PropertyPage_IgnoreCount, parent); fIgnoreCount.setValidRange(0, Integer.MAX_VALUE); fIgnoreCountTextControl = fIgnoreCount.getTextControl(parent); fIgnoreCountTextControl.setEnabled( getPreferenceStore().getInt(ICBreakpoint.IGNORE_COUNT) >= 0 ); diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/Messages.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/Messages.java index 088a48303b0..413ad6379a8 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/Messages.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/Messages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2010 Wind River Systems, Inc. and others. + * Copyright (c) 2009, 2014 Wind River Systems, Inc. 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 @@ -7,6 +7,7 @@ * * Contributors: * Wind River Systems - initial API and implementation + * Marc Khouzam (Ericsson) - Support for dynamic printf (bug 400628) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.internal.ui.breakpoints; @@ -15,24 +16,30 @@ import org.eclipse.osgi.util.NLS; public class Messages extends NLS { public static String ToggleTracepointsTargetFactory_description; public static String ToggleTracepointsTargetFactory_name; - public static String TracepointPropertyPage_integer_negative; - public static String TracepointPropertyPage_NotAvailable; - public static String TracepointPropertyPage_FunctionName; - public static String TracepointPropertyPage_Address; - public static String TracepointPropertyPage_File; - public static String TracepointPropertyPage_LineNumber; - public static String TracepointPropertyPage_Project; - public static String TracepointPropertyPage_Condition; - public static String TracepointPropertyPage_InvalidCondition; - public static String TracepointPropertyPage_IgnoreCount; + public static String ToggleDynamicPrintfTargetFactory_description; + public static String ToggleDynamicPrintfTargetFactory_name; + public static String Default_AddressDynamicPrintf_String; + public static String Default_LineDynamicPrintf_String; + + public static String PropertyPage_integer_negative; + public static String PropertyPage_NotAvailable; + public static String PropertyPage_FunctionName; + public static String PropertyPage_Address; + public static String PropertyPage_File; + public static String PropertyPage_LineNumber; + public static String PropertyPage_Project; + public static String PropertyPage_Condition; + public static String PropertyPage_InvalidCondition; + public static String PropertyPage_IgnoreCount; public static String TracepointPropertyPage_PassCount; - public static String TracepointPropertyPage_Class; - public static String TracepointPropertyPage_Enabled; - public static String TracepointPropertyPage_function_value_errorMessage; - + public static String PropertyPage_function_value_errorMessage; + public static String PropertyPage_Class; + public static String PropertyPage_Enabled; + public static String DynamicPrintfPropertyPage_PrintString; + public static String GdbThreadFilterEditor_Thread; public static String GdbThreadFilterEditor_RestrictToSelected; - + static { // initialize resource bundle NLS.initializeMessages(Messages.class.getName(), Messages.class); diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/Messages.properties b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/Messages.properties index 00829688e21..ab0f586ca71 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/Messages.properties +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/Messages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2009, 2010 Wind River Systems and others. +# Copyright (c) 2009, 2014 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 @@ -8,25 +8,37 @@ # Contributors: # Wind River Systems - initial API and implementation # Ericsson - added Tracepoint support +# Marc Khouzam (Ericsson) - Support for dynamic printf (bug 400628) ############################################################################### ToggleTracepointsTargetFactory_description=Standard C/C++ Tracepoint type. ToggleTracepointsTargetFactory_name=C/C++ Tracepoints -TracepointPropertyPage_integer_negative=Count must be a nonnegative integer -TracepointPropertyPage_NotAvailable=Not available -TracepointPropertyPage_FunctionName=Function name: -TracepointPropertyPage_Address=Address: -TracepointPropertyPage_File=File: -TracepointPropertyPage_LineNumber=Line number: -TracepointPropertyPage_Project=Project: -TracepointPropertyPage_Condition=&Condition: -TracepointPropertyPage_InvalidCondition=Invalid condition. -TracepointPropertyPage_IgnoreCount=&Ignore count: +PropertyPage_integer_negative=Count must be a nonnegative integer +PropertyPage_NotAvailable=Not available +PropertyPage_FunctionName=Function name: +PropertyPage_Address=Address: +PropertyPage_File=File: +PropertyPage_LineNumber=Line number: +PropertyPage_Project=Project: +PropertyPage_Condition=&Condition: +PropertyPage_InvalidCondition=Invalid condition. +PropertyPage_IgnoreCount=&Ignore count: TracepointPropertyPage_PassCount=&Pass count: -TracepointPropertyPage_Class=Class: -TracepointPropertyPage_Enabled=Enabled -TracepointPropertyPage_function_value_errorMessage=Enter a function expression: +PropertyPage_Class=Class: +PropertyPage_Enabled=Enabled +PropertyPage_function_value_errorMessage=Enter a function expression: +DynamicPrintfPropertyPage_PrintString=&printf( + +ToggleDynamicPrintfTargetFactory_description=Standard C/C++ Dynamic Printf type. +ToggleDynamicPrintfTargetFactory_name=C/C++ Dynamic Printf + +# We use %d in the below string on purpose to show the user that it is possible +# Don't use %s with an in-line string, as it crashes GDB 7.5 and 7.6 +# http://sourceware.org/bugzilla/show_bug.cgi?id=15433 +Default_LineDynamicPrintf_String="Hit line %d of {0}\\n",{1} +# We use %x in the below string on purpose to show the user that it is possible +Default_AddressDynamicPrintf_String="Hit address 0x%x\\n",{0} GdbThreadFilterEditor_Thread=Thread -GdbThreadFilterEditor_RestrictToSelected=&Restrict to Selected Processes and Threads: \ No newline at end of file +GdbThreadFilterEditor_RestrictToSelected=&Restrict to Selected Processes and Threads: diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/ToggleDynamicPrintfTargetFactory.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/ToggleDynamicPrintfTargetFactory.java new file mode 100644 index 00000000000..fb0123c91fe --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/breakpoints/ToggleDynamicPrintfTargetFactory.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.breakpoints; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.IDisassemblyPart; +import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget; +import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetFactory; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IWorkbenchPart; + +/** + * Toggle DynamicPrintf target factory for disassembly parts. + * We use a separate factory because the tracepoint factory is controlled + * through an action set, while the breakpoint factory is down in DSF (not DSF-GDB). + * + * @since 2.4 + */ +public class ToggleDynamicPrintfTargetFactory implements IToggleBreakpointsTargetFactory { + + /** + * Toggle DynamicPrintf target-id for normal C DynamicPrintf. + * Note: The id must be the same as in ToggleCDynamicPrintfTargetFactory + * which is used for the editor. We need the id to be the same so that when + * the user goes from editor to DSF disassembly view, the choice of breakpoint + * targets looks the same and is remembered. + * To use the same id though, we must be careful not to have the two factories + * return the same id for the same part, or else it may confuse things. + * This is why this factory only returns this id for the DSF disassembly part, + * leaving ToggleCDynamicPrintfTargetFactory to return the same id + * for the editor. + */ + public static final String TOGGLE_C_DYNAMICPRINTF_TARGET_ID = CDebugUIPlugin.PLUGIN_ID + ".toggleCDynamicPrintfTarget"; //$NON-NLS-1$ + + private static final Set TOGGLE_TARGET_IDS_ALL = new HashSet(1); + static { + TOGGLE_TARGET_IDS_ALL.add(TOGGLE_C_DYNAMICPRINTF_TARGET_ID); + } + + private static final IToggleBreakpointsTarget fgDisassemblyToggleDynamicPrintfTarget = new DisassemblyToggleDynamicPrintfTarget(); + + public ToggleDynamicPrintfTargetFactory() { + } + + @Override + public IToggleBreakpointsTarget createToggleTarget(String targetID) { + if (TOGGLE_C_DYNAMICPRINTF_TARGET_ID.equals(targetID)) { + return fgDisassemblyToggleDynamicPrintfTarget; + } + return null; + } + + @Override + public String getDefaultToggleTarget(IWorkbenchPart part, ISelection selection) { + return null; + } + + @Override + public String getToggleTargetDescription(String targetID) { + if (TOGGLE_C_DYNAMICPRINTF_TARGET_ID.equals(targetID)) { + return Messages.ToggleDynamicPrintfTargetFactory_description; + } + return null; + } + + @Override + public String getToggleTargetName(String targetID) { + if (TOGGLE_C_DYNAMICPRINTF_TARGET_ID.equals(targetID)) { + return Messages.ToggleDynamicPrintfTargetFactory_name; + } + return null; + } + + @Override + public Set getToggleTargets(IWorkbenchPart part, ISelection selection) { + if (part instanceof IDisassemblyPart) { + return TOGGLE_TARGET_IDS_ALL; + } + return Collections.emptySet(); + } + +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/disassembly/AddDynamicPrintfRulerAction.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/disassembly/AddDynamicPrintfRulerAction.java new file mode 100644 index 00000000000..0bd0b6e2f94 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/disassembly/AddDynamicPrintfRulerAction.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright (c) 2008, 2014 Wind River Systems, Inc. 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 + * Marc Khouzam (Ericsson) - Support for dynamic printf (Bug 400628) + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.disassembly; + +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.cdt.debug.ui.breakpoints.IToggleBreakpointsTargetCExtension; +import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions.AbstractDisassemblyBreakpointRulerAction; +import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.IDisassemblyPart; +import org.eclipse.cdt.dsf.gdb.internal.ui.breakpoints.ToggleDynamicPrintfTargetFactory; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget; +import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetFactory; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.text.source.IVerticalRulerInfo; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.ui.IWorkbenchPart; + +/** + * Ruler action to add dynamic printf with a dialog properties. + */ +public class AddDynamicPrintfRulerAction extends AbstractDisassemblyBreakpointRulerAction { + + private IToggleBreakpointsTargetCExtension fDynamicPrintfBreakpointsTarget; + + protected AddDynamicPrintfRulerAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo) { + super(disassemblyPart, rulerInfo); + setText(DisassemblyMessages.Disassembly_action_AddDynamicPrintf_label); + } + + /* + * @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions.AbstractDisassemblyAction#run() + */ + @Override + public void run() { + if (fDynamicPrintfBreakpointsTarget != null) { + IWorkbenchPart part = getDisassemblyPart(); + ISelection selection = getSelection(); + try { + if (fDynamicPrintfBreakpointsTarget.canCreateLineBreakpointsInteractive(part, selection)) { + fDynamicPrintfBreakpointsTarget.createLineBreakpointsInteractive(part, selection); + } + } catch (CoreException e) { + reportException(e); + } + } + } + + @Override + public void update() { + IDisassemblyPart part = getDisassemblyPart(); + if (part != null && part.isConnected()) { + ISelection selection = getSelection(); + if (fDynamicPrintfBreakpointsTarget == null) { + fDynamicPrintfBreakpointsTarget = fetchDynamicPrintfBreakpointsTarget(selection); + } + + if (fDynamicPrintfBreakpointsTarget == null) { + setEnabled(false); + return; + } + if (fDynamicPrintfBreakpointsTarget.canCreateLineBreakpointsInteractive(part, selection)) { + setEnabled(true); + return; + } + } + setEnabled(false); + } + + + /** + * Report an error to the user. + * + * @param e underlying exception + */ + private void reportException(Exception e) { + IStatus status= new Status(IStatus.ERROR, CDebugUIPlugin.PLUGIN_ID, "Error creating dynamic printf: ", e); //$NON-NLS-1$ + ErrorDialog.openError( + getDisassemblyPart().getSite().getShell(), + DisassemblyMessages.Disassembly_action_AddDynamicPrintf_errorTitle, + DisassemblyMessages.Disassembly_action_AddDynamicPrintf_errorMessage, + status); + CDebugUIPlugin.log(status); + } + + /** + * Determines the text selection for the breakpoint action. If clicking on the ruler inside + * the highlighted text, return the text selection for the highlighted text. Otherwise, + * return a text selection representing the start of the line. + * + * @return An ISelection as described. + * @throws BadLocationException If underlying operations throw. + */ + private ISelection getSelection() { + IDocument document = getDocument(); + if (document != null) { + int line = getRulerInfo().getLineOfLastMouseButtonActivity(); + + try { + IRegion region = getDocument().getLineInformation(line); + ITextSelection textSelection = new TextSelection(document, region.getOffset(), 0); + ISelectionProvider provider = getDisassemblyPart().getSite().getSelectionProvider(); + if (provider != null){ + ISelection selection = provider.getSelection(); + if (selection instanceof ITextSelection + && ((ITextSelection) selection).getStartLine() <= line + && ((ITextSelection) selection).getEndLine() >= line) { + textSelection = (ITextSelection) selection; + } + } + return textSelection; + } catch (BadLocationException e) { + } + } + return StructuredSelection.EMPTY; + } + + private IToggleBreakpointsTargetCExtension fetchDynamicPrintfBreakpointsTarget(ISelection selection) { + if (fDynamicPrintfBreakpointsTarget == null){ + IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint(IDebugUIConstants.PLUGIN_ID, IDebugUIConstants.EXTENSION_POINT_TOGGLE_BREAKPOINTS_TARGET_FACTORIES); + IConfigurationElement[] elements = ep.getConfigurationElements(); + for (int i= 0; i < elements.length; i++) { + String id = elements[i].getAttribute("id"); //$NON-NLS-1$ + if (id != null && id.equals("org.eclipse.cdt.dsf.gdb.ui.ToggleDynamicPrintfTargetFactory")) { //$NON-NLS-1$ + try{ + Object obj = elements[i].createExecutableExtension("class"); //$NON-NLS-1$ + if(obj instanceof IToggleBreakpointsTargetFactory) { + IToggleBreakpointsTarget target = ((IToggleBreakpointsTargetFactory)obj).createToggleTarget(ToggleDynamicPrintfTargetFactory.TOGGLE_C_DYNAMICPRINTF_TARGET_ID); + if (target instanceof IToggleBreakpointsTargetCExtension) { + fDynamicPrintfBreakpointsTarget = (IToggleBreakpointsTargetCExtension)target; + } + } + } catch (CoreException e){ + } + break; + } + } + } + return fDynamicPrintfBreakpointsTarget; + } + +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/disassembly/AddDynamicPrintfRulerActionDelegate.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/disassembly/AddDynamicPrintfRulerActionDelegate.java new file mode 100644 index 00000000000..58de94770de --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/disassembly/AddDynamicPrintfRulerActionDelegate.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2008, 2014 Wind River Systems, Inc. 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: + * Marc Khouzam (Ericsson) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.disassembly; + +import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions.AbstractDisassemblyRulerActionDelegate; +import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.IDisassemblyPart; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.text.source.IVerticalRulerInfo; + +/** + * Ruler action delegate for the "Add Dynamic Printf..." action. + */ +public class AddDynamicPrintfRulerActionDelegate extends AbstractDisassemblyRulerActionDelegate { + + /* + * @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions.AbstractDisassemblyRulerActionDelegate#createAction(org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyPart, org.eclipse.jface.text.source.IVerticalRulerInfo) + */ + @Override + protected IAction createAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo) { + return new AddDynamicPrintfRulerAction(disassemblyPart, rulerInfo); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/disassembly/DisassemblyMessages.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/disassembly/DisassemblyMessages.java new file mode 100644 index 00000000000..6573262b2f0 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/disassembly/DisassemblyMessages.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - Support for dynamic printf (Bug 400628) + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui.disassembly; + +import org.eclipse.osgi.util.NLS; + +public final class DisassemblyMessages extends NLS { + public static String Disassembly_action_AddDynamicPrintf_label; + public static String Disassembly_action_AddDynamicPrintf_errorMessage; + public static String Disassembly_action_AddDynamicPrintf_errorTitle; + public static String Disassembly_action_AddDynamicPrintf_accelerator; + + static { + NLS.initializeMessages(DisassemblyMessages.class.getName(), DisassemblyMessages.class); + } + + // Do not instantiate + private DisassemblyMessages() { + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/disassembly/DisassemblyMessages.properties b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/disassembly/DisassemblyMessages.properties new file mode 100644 index 00000000000..d34ec2ec099 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/disassembly/DisassemblyMessages.properties @@ -0,0 +1,15 @@ +########################################################################## +# Copyright (c) 2014 Ericsson 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: +# Marc Khouzam (Ericsson) - Support for dynamic printf (Bug 400628) +########################################################################## + +Disassembly_action_AddDynamicPrintf_label=Add Dynamic Printf... +Disassembly_action_AddDynamicPrintf_errorMessage=Unable to create dynamic printf +Disassembly_action_AddDynamicPrintf_errorTitle=Error +Disassembly_action_AddDynamicPrintf_accelerator=Double Click diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/breakpoints/GDBDynamicPrintfUtils.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/breakpoints/GDBDynamicPrintfUtils.java new file mode 100644 index 00000000000..293b6a1e76a --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/breakpoints/GDBDynamicPrintfUtils.java @@ -0,0 +1,154 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - Support Dynamic Printf (Bug 400628) + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.breakpoints; + +import org.eclipse.cdt.dsf.concurrent.Immutable; +import org.eclipse.osgi.util.NLS; + + +/** + * Utility methods to help deal with Dynamic Printf logic. + * + * @since 4.4 + */ +public class GDBDynamicPrintfUtils { + + @Immutable + public static class GDBDynamicPrintfString { + private boolean fValid; + private String fStringSection; + private String[] fArgs; + private String fErrorMessage; + + public GDBDynamicPrintfString(String str) { + if (str == null) { + fErrorMessage = Messages.DynamicPrintf_Invalid_string; + return; + } + + str = str.trim(); + + // No point in having an empty string, just disable the dprintf instead + if (str.isEmpty()) { + fErrorMessage = Messages.DynamicPrintf_Invalid_string; + return; + } + + // First character must be a double-quote + if (str.charAt(0) != '"') { + fErrorMessage = Messages.DynamicPrintf_Printf_must_start_with_quote; + return; + } + + // Now go through the string and look for two things: + // 1- count the number of % (but ignore any %%) + // 2- find the closing double-quote (but ignore any \") + char[] chars = str.toCharArray(); + int closingQuoteIndex = 0; + int numArgExpected = 0; + for (int i=1; i i+1 && chars[i+1] != '%') { + // Not a %% so we have found an expected argument. + numArgExpected++; + } + + // We either found a second %, which we must skip to + // avoid parsing it again, or we didn't and we know + // our next character must be part of the format. + // In both cases we can and should skip the next character. + // Note that we are not going to make sure the format is + // correct as that becomes really complex. + i++; + break; + } + + // If we found the closing double-quote, there is no need to keep counting + if (closingQuoteIndex > 0) break; + } + + if (closingQuoteIndex < 1) { + // Didn't find a closing double-quote! + fErrorMessage = Messages.DynamicPrintf_Printf_missing_closing_quote; + return; + } + + // We extract the string part of the printf string leaving the arguments + fStringSection = str.substring(0, closingQuoteIndex+1); + + int numArgPresent = 0; + if (closingQuoteIndex + 1 >= str.length()) { + // No more characters after the string part + fArgs = new String[0]; + numArgPresent = 0; + } else { + String argString = str.substring(closingQuoteIndex+1).trim(); + if (argString.charAt(0) != ',') { + fErrorMessage = Messages.DynamicPrintf_Missing_comma; + return; + } + + // Remove the first , to avoid an empty element after the split. + // Then split the string but keep any empty results + String[] args = argString.substring(1).split(",", -1); //$NON-NLS-1$ + + for (String argument : args) { + if (argument.trim().isEmpty()) { + fErrorMessage = Messages.DynamicPrintf_Empty_arg; + return; + } + } + + fArgs = args; + numArgPresent = fArgs.length; + } + + if (numArgPresent != numArgExpected) { + if (numArgPresent > numArgExpected) { + fErrorMessage = NLS.bind(Messages.DynamicPrintf_Extra_arg, numArgPresent - numArgExpected); + } else { + fErrorMessage = NLS.bind(Messages.DynamicPrintf_Missing_arg, numArgExpected - numArgPresent); + } + return; + } + + // Everything is ok! + fValid = true; + } + + public boolean isValid() { + return fValid; + } + + public String getString() { + if (!isValid()) return ""; //$NON-NLS-1$ + return fStringSection; + } + + public String[] getArguments() { + if (!isValid()) return new String[0]; + return fArgs; + } + + public String getErrorMessage() { + return fErrorMessage; + } + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/breakpoints/Messages.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/breakpoints/Messages.java new file mode 100644 index 00000000000..54aa24e3414 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/breakpoints/Messages.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - Support for dynamic printf (bug 400628) + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.breakpoints; + +import org.eclipse.osgi.util.NLS; + +/** @since 4.4 */ +public class Messages extends NLS { + public static String DynamicPrintf_Invalid_string; + public static String DynamicPrintf_Printf_must_start_with_quote; + public static String DynamicPrintf_Printf_missing_closing_quote; + public static String DynamicPrintf_Missing_comma; + public static String DynamicPrintf_Empty_arg; + public static String DynamicPrintf_Extra_arg; + public static String DynamicPrintf_Missing_arg; + + static { + // initialize resource bundle + NLS.initializeMessages(Messages.class.getName(), Messages.class); + } + + private Messages() { + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/breakpoints/Messages.properties b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/breakpoints/Messages.properties new file mode 100644 index 00000000000..c4ed7a08937 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/breakpoints/Messages.properties @@ -0,0 +1,18 @@ +####################################################################################### +# Copyright (c) 2014 Ericsson 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: +# Marc Khouzam (Ericsson) - Support for dynamic printf (bug 400628) +####################################################################################### + +DynamicPrintf_Invalid_string=Invalid printf string +DynamicPrintf_Printf_must_start_with_quote=Printf string must start with a " +DynamicPrintf_Printf_missing_closing_quote=Printf string is missing its closing " +DynamicPrintf_Missing_comma=Printf string can only have a , after its closing " +DynamicPrintf_Empty_arg=Printf string should not have empty arguments +DynamicPrintf_Extra_arg={0} extra arguments in printf specification +DynamicPrintf_Missing_arg={0} missing arguments in printf specification diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence_7_7.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence_7_7.java new file mode 100644 index 00000000000..093da8ff752 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence_7_7.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.launching; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; +import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.concurrent.RequestMonitorWithProgress; +import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; +import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl; +import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetDPrintfStyle; +import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +/** + * Subclass for GDB >= 7.7. + * + * @since 4.4 + */ +public class FinalLaunchSequence_7_7 extends FinalLaunchSequence_7_2 { + + private IGDBControl fControl; + + public FinalLaunchSequence_7_7(DsfSession session, Map attributes, RequestMonitorWithProgress rm) { + super(session, attributes, rm); + } + + @Override + protected String[] getExecutionOrder(String group) { + if (GROUP_TOP_LEVEL.equals(group)) { + // Initialize the list with the base class' steps + // We need to create a list that we can modify, which is why we create our own ArrayList. + List orderList = new ArrayList(Arrays.asList(super.getExecutionOrder(GROUP_TOP_LEVEL))); + + // Now insert our steps right after the initialization of the base class. + orderList.add(orderList.indexOf("stepInitializeFinalLaunchSequence_7_2") + 1, "stepInitializeFinalLaunchSequence_7_7"); //$NON-NLS-1$ //$NON-NLS-2$ + orderList.add(orderList.indexOf("stepSourceGDBInitFile"), "stepSetDPrinfStyle"); //$NON-NLS-1$ //$NON-NLS-2$ + + return orderList.toArray(new String[orderList.size()]); + } + + return null; + } + + /** + * Initialize the members of the FinalLaunchSequence_7_7 class. + * This step is mandatory for the rest of the sequence to complete. + */ + @Execute + public void stepInitializeFinalLaunchSequence_7_7(RequestMonitor rm) { + DsfServicesTracker tracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), getSession().getId()); + fControl = tracker.getService(IGDBControl.class); + tracker.dispose(); + + if (fControl == null) { + rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Cannot obtain service", null)); //$NON-NLS-1$ + return; + } + + rm.done(); + } + + /** + * Specify how dynamic printf should be handled by GDB. + */ + @Execute + public void stepSetDPrinfStyle(final RequestMonitor rm) { + // We use the 'call' style which will + // have dprintf call the printf function in the program. + fControl.queueCommand( + fControl.getCommandFactory().createMIGDBSetDPrintfStyle(fControl.getContext(), + MIGDBSetDPrintfStyle.CALL_STYLE), + new ImmediateDataRequestMonitor(rm) { + @Override + protected void handleCompleted() { + // We accept errors + rm.done(); + } + }); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBreakpoints_7_7.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBreakpoints_7_7.java new file mode 100644 index 00000000000..5b51fcf084b --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBreakpoints_7_7.java @@ -0,0 +1,204 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - 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.ConfinedToDsfExecutor; +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.concurrent.Sequence.Step; +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.gdb.internal.GdbPlugin; +import org.eclipse.cdt.dsf.mi.service.IMICommandControl; +import org.eclipse.cdt.dsf.mi.service.IMIRunControl; +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.CommandFactory; +import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo; +import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakpoint; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +/** + * Breakpoints service for GDB 7.7. + * This version supports dynamic printf + * + * @since 4.4 + */ +public class GDBBreakpoints_7_7 extends GDBBreakpoints_7_6 { + + private IMICommandControl fConnection; + private IMIRunControl fRunControl; + private CommandFactory fCommandFactory; + + public GDBBreakpoints_7_7(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); + fRunControl = getServicesTracker().getService(IMIRunControl.class); + if (fConnection == null || fRunControl == null) { + rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, "Service is not available")); //$NON-NLS-1$ + return; + } + + fCommandFactory = fConnection.getCommandFactory(); + + // 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(), + GDBBreakpoints_7_6.class.getName(), + GDBBreakpoints_7_7.class.getName() }, + new Hashtable()); + + rm.done(); + } + + @Override + public void shutdown(RequestMonitor requestMonitor) { + unregister(); + super.shutdown(requestMonitor); + } + + @Override + protected void addDynamicPrintf( + final IBreakpointsTargetDMContext context, + final Map attributes, + final DataRequestMonitor drm) { + final MIBreakpointsSynchronizer bs = getServicesTracker().getService(MIBreakpointsSynchronizer.class); + if (bs != null) { + // Skip the dprintf set from the console or from outside of Eclipse + // because they are already installed on the target. + bs.getTargetBreakpoint( + context, + attributes, + new DataRequestMonitor(getExecutor(), drm) { + @Override + @ConfinedToDsfExecutor( "fExecutor" ) + protected void handleSuccess() { + MIBreakpoint miBpt = getData(); + if (miBpt != null) { + bs.removeCreatedTargetBreakpoint(context, miBpt); + MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(miBpt); + getBreakpointMap(context).put(newBreakpoint.getNumber(), newBreakpoint); + IBreakpointDMContext dmc = + new MIBreakpointDMContext(GDBBreakpoints_7_7.this, new IDMContext[] { context }, newBreakpoint.getNumber()); + drm.setData(dmc); + getSession().dispatchEvent(new BreakpointAddedEvent(dmc), getProperties()); + drm.done(); + } + else { + doAddDynamicPrintf(context, attributes, drm); + } + } + }); + } + else { + doAddDynamicPrintf(context, attributes, drm); + } + } + + /** + * Add a Dynamic Printf. + */ + protected void doAddDynamicPrintf(final IBreakpointsTargetDMContext context, Map attributes, final DataRequestMonitor finalRm) + { + // Select the context breakpoints map + final Map contextBreakpoints = getBreakpointMap(context); + if (contextBreakpoints == null) { + finalRm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); + return; + } + + // Extract the relevant parameters (providing default values to avoid potential NPEs) + final String location = formatLocation(attributes); + if (location.equals(NULL_STRING)) { + finalRm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_CONTEXT, null)); + return; + } + + final String printfStr = (String) getProperty(attributes, MIBreakpoints.PRINTF_STRING, ""); //$NON-NLS-1$ + final Boolean enabled = (Boolean) getProperty(attributes, MIBreakpoints.IS_ENABLED, true); + final Boolean isTemporary = (Boolean) getProperty(attributes, MIBreakpointDMData.IS_TEMPORARY, false); + final String condition = (String) getProperty(attributes, MIBreakpoints.CONDITION, NULL_STRING); + final Integer ignoreCount = (Integer) getProperty(attributes, MIBreakpoints.IGNORE_COUNT, 0); + String threadId = (String) getProperty(attributes, MIBreakpointDMData.THREAD_ID, "0"); //$NON-NLS-1$ + final int tid = Integer.parseInt(threadId); + + final Step insertDPrintf = new Step() { + @Override + public void execute(final RequestMonitor rm) { + // Execute the command + fConnection.queueCommand( + fCommandFactory.createMIDPrintfInsert(context, isTemporary, condition, ignoreCount, tid, !enabled, location, printfStr), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + + // With MI, an invalid location won't generate an error + if (getData().getMIBreakpoints().length == 0) { + rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, DYNAMIC_PRINTF_INSERTION_FAILURE, null)); + return; + } + + // Create a breakpoint object and store it in the map + final MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(getData().getMIBreakpoints()[0]); + int reference = newBreakpoint.getNumber(); + if (reference == -1) { + rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, DYNAMIC_PRINTF_INSERTION_FAILURE, null)); + return; + } + contextBreakpoints.put(reference, newBreakpoint); + + // Format the return value + MIBreakpointDMContext dmc = new MIBreakpointDMContext(GDBBreakpoints_7_7.this, new IDMContext[] { context }, reference); + finalRm.setData(dmc); + + // Flag the event + getSession().dispatchEvent(new BreakpointAddedEvent(dmc), getProperties()); + + rm.done(); + } + + @Override + protected void handleError() { + rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, DYNAMIC_PRINTF_INSERTION_FAILURE, getStatus().getException())); + } + }); + } + }; + + fRunControl.executeWithTargetAvailable(context, new Step[] { insertDPrintf }, finalRm); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java index 1b362cf7013..36d53855ace 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java @@ -16,6 +16,7 @@ * Marc Khouzam (Ericsson) - Support for GDB 7.4 trace control service * William Riley (Renesas) - Support for GDB 7.3 disassembly service (Bug 357270) * Marc Khouzam (Ericsson) - Support for GDB 7.4 processes service (Bug 389945) + * Marc Khouzam (Ericsson) - Support dynamic printf in bp service 7.5 (Bug 400628) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.service; @@ -37,6 +38,7 @@ import org.eclipse.cdt.dsf.gdb.service.command.GDBControl; import org.eclipse.cdt.dsf.gdb.service.command.GDBControl_7_0; import org.eclipse.cdt.dsf.gdb.service.command.GDBControl_7_2; import org.eclipse.cdt.dsf.gdb.service.command.GDBControl_7_4; +import org.eclipse.cdt.dsf.gdb.service.command.GDBControl_7_7; import org.eclipse.cdt.dsf.mi.service.CSourceLookup; import org.eclipse.cdt.dsf.mi.service.IMIBackend; import org.eclipse.cdt.dsf.mi.service.IMIExpressions; @@ -68,10 +70,12 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory { public static final String GDB_7_3_VERSION = "7.3"; //$NON-NLS-1$ /** @since 4.1 */ public static final String GDB_7_4_VERSION = "7.4"; //$NON-NLS-1$ - /** @since 4.2*/ + /** @since 4.2 */ public static final String GDB_7_5_VERSION = "7.5"; //$NON-NLS-1$ - /** @since 4.2*/ + /** @since 4.2 */ public static final String GDB_7_6_VERSION = "7.5.50"; //$NON-NLS-1$ + /** @since 4.4 */ + public static final String GDB_7_7_VERSION = "7.7"; //$NON-NLS-1$ private final String fVersion; @@ -126,6 +130,9 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory { @Override protected IBreakpoints createBreakpointService(DsfSession session) { + if (GDB_7_7_VERSION.compareTo(fVersion) <= 0) { + return new GDBBreakpoints_7_7(session); + } if (GDB_7_6_VERSION.compareTo(fVersion) <= 0) { return new GDBBreakpoints_7_6(session); } @@ -144,6 +151,9 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory { } protected ICommandControl createCommandControl(DsfSession session, ILaunchConfiguration config) { + if (GDB_7_7_VERSION.compareTo(fVersion) <= 0) { + return new GDBControl_7_7(session, config, new CommandFactory_6_8()); + } if (GDB_7_4_VERSION.compareTo(fVersion) <= 0) { return new GDBControl_7_4(session, config, new CommandFactory_6_8()); } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_7.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_7.java new file mode 100644 index 00000000000..c7df43ccfc8 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_7.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.service.command; + +import java.util.Map; + +import org.eclipse.cdt.dsf.concurrent.RequestMonitorWithProgress; +import org.eclipse.cdt.dsf.concurrent.Sequence; +import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService; +import org.eclipse.cdt.dsf.gdb.launching.FinalLaunchSequence_7_7; +import org.eclipse.cdt.dsf.mi.service.command.CLIEventProcessor_7_7; +import org.eclipse.cdt.dsf.mi.service.command.CommandFactory; +import org.eclipse.cdt.dsf.mi.service.command.IEventProcessor; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.debug.core.ILaunchConfiguration; + +/** + * Need a new FinalLaunchSequence for GDB 7.7 + * @since 4.4 + */ +public class GDBControl_7_7 extends GDBControl_7_4 { + public GDBControl_7_7(DsfSession session, ILaunchConfiguration config, CommandFactory factory) { + super(session, config, factory); + } + + @Override + protected IEventProcessor createCLIEventProcessor(ICommandControlService connection, ICommandControlDMContext controlDmc) { + return new CLIEventProcessor_7_7(connection, controlDmc); + } + + @Override + protected Sequence getCompleteInitializationSequence(Map attributes, RequestMonitorWithProgress rm) { + return new FinalLaunchSequence_7_7(getSession(), attributes, rm); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointDMData.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointDMData.java index bff232cda88..88dd2b1301c 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointDMData.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointDMData.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 Ericsson and others. + * Copyright (c) 2007, 2014 Ericsson 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 @@ -7,6 +7,7 @@ * * Contributors: * Ericsson - Initial API and implementation + * Marc Khouzam (Ericsson) - Support for dynamic printf (400628) *******************************************************************************/ package org.eclipse.cdt.dsf.mi.service; @@ -40,7 +41,8 @@ public class MIBreakpointDMData implements IBreakpointDMData { // Breakpoint types public static enum MIBreakpointNature { UNKNOWN, BREAKPOINT, WATCHPOINT, CATCHPOINT, - /** @since 3.0*/ TRACEPOINT }; + /** @since 3.0*/ TRACEPOINT, + /** @since 4.4*/ DYNAMICPRINTF }; private final MIBreakpointNature fNature; @@ -71,6 +73,8 @@ public class MIBreakpointDMData implements IBreakpointDMData { fBreakpoint = dsfMIBreakpoint; if (dsfMIBreakpoint.isTracepoint()) { fNature = MIBreakpointNature.TRACEPOINT; + } else if (dsfMIBreakpoint.isDynamicPrintf()) { + fNature = MIBreakpointNature.DYNAMICPRINTF; } else if (dsfMIBreakpoint.isWatchpoint()) { fNature = MIBreakpointNature.WATCHPOINT; } else if (dsfMIBreakpoint.isCatchpoint()) { @@ -148,6 +152,31 @@ public class MIBreakpointDMData implements IBreakpointDMData { break; } + case DYNAMICPRINTF: + { + // Generic breakpoint attributes + fProperties.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.DYNAMICPRINTF); + fProperties.put(MIBreakpoints.FILE_NAME, dsfMIBreakpoint.getFile()); + fProperties.put(MIBreakpoints.LINE_NUMBER, dsfMIBreakpoint.getLine()); + fProperties.put(MIBreakpoints.FUNCTION, dsfMIBreakpoint.getFunction()); + fProperties.put(MIBreakpoints.ADDRESS, dsfMIBreakpoint.getAddress()); + fProperties.put(MIBreakpoints.CONDITION, dsfMIBreakpoint.getCondition()); + fProperties.put(MIBreakpoints.PRINTF_STRING, dsfMIBreakpoint.getPrintfString()); + fProperties.put(MIBreakpoints.IS_ENABLED, new Boolean(dsfMIBreakpoint.isEnabled())); + fProperties.put(MIBreakpoints.COMMANDS, dsfMIBreakpoint.getCommands()); + + // MI-specific breakpoint attributes + fProperties.put(NUMBER, dsfMIBreakpoint.getNumber()); + fProperties.put(TYPE, dsfMIBreakpoint.getType()); + fProperties.put(THREAD_ID, dsfMIBreakpoint.getThreadId()); + fProperties.put(FULL_NAME, dsfMIBreakpoint.getFullName()); + fProperties.put(HITS, dsfMIBreakpoint.getTimes()); + fProperties.put(IS_TEMPORARY, new Boolean(dsfMIBreakpoint.isTemporary())); + fProperties.put(IS_HARDWARE, new Boolean(dsfMIBreakpoint.isHardware())); + fProperties.put(LOCATION, formatLocation()); + break; + } + case CATCHPOINT: { // Because gdb doesn't support catchpoints in mi, we end up using @@ -280,6 +309,13 @@ public class MIBreakpointDMData implements IBreakpointDMData { return fBreakpoint.getPassCount(); } + /** + * @since 4.4 + */ + public String getPrintfString() { + return fBreakpoint.getPrintfString(); + } + /** * @since 3.0 */ diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpoints.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpoints.java index 84be847ce2a..d8c45ee7d64 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpoints.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpoints.java @@ -1,13 +1,14 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 Ericsson and others. + * Copyright (c) 2007, 2014 Ericsson 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: - * Ericsson - Initial API and implementation + * Ericsson - Initial API and implementation * Mike Wrighton (Mentor Graphics) - Formatting address for a watchpoint (Bug 376105) + * Marc Khouzam (Ericsson) - Support for dynamic printf (Bug 400628) *******************************************************************************/ package org.eclipse.cdt.dsf.mi.service; @@ -77,7 +78,9 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints, I public static final String CATCHPOINT = "catchpoint"; //$NON-NLS-1$ /** @since 3.0 */ public static final String TRACEPOINT = "tracepoint"; //$NON-NLS-1$ - + /** @since 4.4 */ + public static final String DYNAMICPRINTF = "dynamicPrintf"; //$NON-NLS-1$ + // Basic set of breakpoint attribute markers public static final String FILE_NAME = PREFIX + ".fileName"; //$NON-NLS-1$ public static final String LINE_NUMBER = PREFIX + ".lineNumber"; //$NON-NLS-1$ @@ -98,6 +101,10 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints, I // Catchpoint properties + // DynamicPrintf properties + /** @since 4.4 */ + public static final String PRINTF_STRING = PREFIX + ".printf_string"; //$NON-NLS-1$ + /** * Property that indicates the kind of catchpoint (.e.g, fork call, C++ * exception throw). Value is the gdb keyword associated with that type, as @@ -174,6 +181,8 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints, I public final static String INVALID_CONDITION = "Invalid condition"; //$NON-NLS-1$ /** @since 3.0 */ public final static String TRACEPOINT_INSERTION_FAILURE = "Tracepoint insertion failure"; //$NON-NLS-1$ + /** @since 4.4 */ + public final static String DYNAMIC_PRINTF_INSERTION_FAILURE = "Dynamic printf insertion failure"; //$NON-NLS-1$ /** @since 3.0 */ public final static String INVALID_BREAKPOINT_TYPE = "Invalid breakpoint type"; //$NON-NLS-1$ /** @since 3.0 */ @@ -522,6 +531,9 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints, I else if (type.equals(MIBreakpoints.CATCHPOINT)) { addCatchpoint(context, attributes, drm); } + else if (type.equals(MIBreakpoints.DYNAMICPRINTF)) { + addDynamicPrintf(context, attributes, drm); + } else { drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); drm.done(); @@ -868,6 +880,17 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints, I fRunControl.executeWithTargetAvailable(context, new Step[] { insertBreakpointStep }, finalRm); } + /** + * Add a DynamicPrintf. Currently not supported in this version, but only in the GDB 7.7 version. + * + * @since 4.4 + */ + protected void addDynamicPrintf(final IBreakpointsTargetDMContext context, final Map attributes, final DataRequestMonitor drm) { + // Not supported + drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNKNOWN_BREAKPOINT_TYPE, null)); + drm.done(); + } + //------------------------------------------------------------------------- // removeBreakpoint //------------------------------------------------------------------------- diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java index 66dc5863739..14763ba07b0 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java @@ -14,6 +14,7 @@ * Marc Khouzam (Ericsson) - Fix support for thread filter (Bug 355833) * Marc Khouzam (Ericsson) - Generalize thread filtering logic (Bug 431986) * Marc Khouzam (Ericsson) - Accept multiple calls to startTrackingBreakpoints (Bug 389945) + * Marc Khouzam (Ericsson) - Support for dynamic printf (Bug 400628) *******************************************************************************/ package org.eclipse.cdt.dsf.mi.service; @@ -35,6 +36,7 @@ import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint; 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.ICDynamicPrintf; import org.eclipse.cdt.debug.core.model.ICEventBreakpoint; import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; @@ -1073,11 +1075,12 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo // Convert the breakpoint attributes for the back-end // Refresh the set of attributes at each iteration just in case... Map attrs = convertToTargetBreakpoint(breakpoint, attributes); - // Tracepoints are not affected by "skip-all" - if (!(breakpoint instanceof ICTracepoint) && !fBreakpointManager.isEnabled()) { + // Tracepoints and dynamic printf are not affected by "skip-all" + if (!(breakpoint instanceof ICTracepoint) && !(breakpoint instanceof ICDynamicPrintf) + && !fBreakpointManager.isEnabled()) { attrs.put(MIBreakpoints.IS_ENABLED, false); } - // Add the secret ingredient.. + attrs.put(MIBreakpointDMData.THREAD_ID, thread); // Then install the spiked breakpoint @@ -1135,8 +1138,9 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo for (IBreakpointsTargetDMContext context : fBreakpointIDs.keySet()) { for (ICBreakpoint breakpoint : fBreakpointIDs.get(context).keySet()) { try { - // Note that Tracepoints are not affected by "skip-all" - if (!(breakpoint instanceof ICTracepoint) && breakpoint.isEnabled()) { + // Note that Tracepoints and dynamic printf are not affected by "skip-all" + if (!(breakpoint instanceof ICTracepoint) && !(breakpoint instanceof ICDynamicPrintf) + && breakpoint.isEnabled()) { for (IBreakpointDMContext ref : fBreakpointIDs.get(context).get(breakpoint)) { Map delta = new HashMap(); delta.put(MIBreakpoints.IS_ENABLED, enabled); @@ -1250,8 +1254,9 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo try { // Retrieve the breakpoint attributes final Map attrs = breakpoint.getMarker().getAttributes(); - // Tracepoints are not affected by "skip-all" - if (!(breakpoint instanceof ICTracepoint) && !fBreakpointManager.isEnabled()) { + // Tracepoints and dynamic printf are not affected by "skip-all" + if (!(breakpoint instanceof ICTracepoint) && !(breakpoint instanceof ICDynamicPrintf) + && !fBreakpointManager.isEnabled()) { attrs.put(ICBreakpoint.ENABLED, false); } @@ -1807,6 +1812,10 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo // Threads if (cdt_attributes.containsKey(ATTR_THREAD_FILTER)) result.put(ATTR_THREAD_FILTER, cdt_attributes.get(ATTR_THREAD_FILTER)); + + // For IDynamicPrintf + if (cdt_attributes.containsKey(ICDynamicPrintf.PRINTF_STRING)) + result.put(MIBreakpoints.PRINTF_STRING, cdt_attributes.get(ICDynamicPrintf.PRINTF_STRING)); return result; } @@ -1946,8 +1955,11 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo // A tracepoint is a LineBreakpoint, but needs its own type properties.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.TRACEPOINT); properties.put(MIBreakpoints.PASS_COUNT, attributes.get(ICTracepoint.PASS_COUNT)); + } else if (breakpoint instanceof ICDynamicPrintf) { + // A DynamicPrintf is a LineBreakpoint, but needs its own type + properties.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.DYNAMICPRINTF); + properties.put(MIBreakpoints.PRINTF_STRING, attributes.get(ICDynamicPrintf.PRINTF_STRING)); } - } else if (breakpoint instanceof ICEventBreakpoint) { properties.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.CATCHPOINT); @@ -1986,8 +1998,9 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo } // Adjust for "skip-all" - // Tracepoints are not affected by "skip-all" - if (!(breakpoint instanceof ICTracepoint ) && !fBreakpointManager.isEnabled()) { + // Tracepoints and dynamic printf are not affected by "skip-all" + if (!(breakpoint instanceof ICTracepoint) && !(breakpoint instanceof ICDynamicPrintf) + && !fBreakpointManager.isEnabled()) { properties.put(MIBreakpoints.IS_ENABLED, false); } @@ -2016,7 +2029,8 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo || delta.containsKey(ATTR_THREAD_FILTER) // Thread ID || delta.containsKey(MIBreakpoints.EXPRESSION) // Watchpoint expression || delta.containsKey(MIBreakpoints.READ) // Watchpoint type - || delta.containsKey(MIBreakpoints.WRITE)) { // Watchpoint type + || delta.containsKey(MIBreakpoints.WRITE) // Watchpoint type + || delta.containsKey(MIBreakpoints.PRINTF_STRING)) {// Dprintf string return true; } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsSynchronizer.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsSynchronizer.java index c1ae7f6b003..a29da1d37f0 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsSynchronizer.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsSynchronizer.java @@ -9,6 +9,7 @@ * Mentor Graphics - Initial API and implementation * Salvatore Culcasi (ST) - Bug 407163 - GDB Console: breakpoint not added with MinGW and gdb * Marc Khouzam (Ericsson) - Update breakpoint handling for GDB >= 7.4 (Bug 389945) + * Marc Khouzam (Ericsson) - Support for dynamic printf (Bug 400628) *******************************************************************************/ package org.eclipse.cdt.dsf.mi.service; @@ -32,6 +33,7 @@ import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint; 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.ICDynamicPrintf; import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; import org.eclipse.cdt.debug.core.model.ICTracepoint; @@ -448,6 +450,21 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI plBpt.getMarker().setAttribute( BreakpointActionManager.BREAKPOINT_ACTION_ATTRIBUTE, sb.toString()); } + } else if (plBpt instanceof ICDynamicPrintf && miBpt.isDynamicPrintf()) { + // Cannot synchronize the string as there is a bug in GDB 7.7 that corrupts it. + // https://sourceware.org/bugzilla/show_bug.cgi?id=15806 + // If we were to synchronize here, we would overwrite the string defined by + // the user with the corrupted one! + // Truth is that we don't need to synchronize the string anyway because there + // is currently no way to change a dprintf string in GDB; instead a new + // dprintf must be created. That means that there will be no =breakpoint-modifed + // event that indicates a real dprintf string change; only the other fields can + // change and are handled as any other breakpoint. + // + // ICDynamicPrintf plDPrintf = (ICDynamicPrintf)plBpt; + // if (!plDPrintf.getPrintfString().equals(miBpt.getPrintfString())) { + // plDPrintf.setPrintfString(miBpt.getPrintfString()); + // } } } catch(CoreException e) { @@ -513,6 +530,11 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI && isPlatformTracepoint((ICTracepoint)b, miBpt, fileName)) { return (ICBreakpoint)b; } + if (b instanceof ICDynamicPrintf + && miBpt.isDynamicPrintf() + && isPlatformDynamicPrintf((ICDynamicPrintf)b, miBpt, fileName)) { + return (ICBreakpoint)b; + } if (b instanceof ICWatchpoint && miBpt.isWatchpoint() && isPlatformWatchpoint((ICWatchpoint)b, miBpt)) { @@ -522,6 +544,7 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI && !miBpt.isWatchpoint() && !isCatchpoint(miBpt) && !miBpt.isTracepoint() + && !miBpt.isDynamicPrintf() && isPlatformLineBreakpoint((ICLineBreakpoint)b, miBpt, fileName)) { return (ICBreakpoint)b; } @@ -536,6 +559,9 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI else if (miBpt.isTracepoint()) { return createPlatformTracepoint(fileName, miBpt); } + else if (miBpt.isDynamicPrintf()) { + return createPlatformDynamicPrintf(fileName, miBpt); + } else { return createPlatformLocationBreakpoint(fileName, miBpt); } @@ -576,7 +602,7 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI } catch(NumberFormatException e) { throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.getUniqueIdentifier(), - String.format("Invalid breakpoint addres: %s", miBpt.getAddress()))); //$NON-NLS-1$ + String.format("Invalid breakpoint address: %s", miBpt.getAddress()))); //$NON-NLS-1$ } } @@ -659,7 +685,7 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI } catch(NumberFormatException e) { throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.getUniqueIdentifier(), - String.format("Invalid breakpoint addres: %s", miBpt.getAddress()))); //$NON-NLS-1$ + String.format("Invalid breakpoint address: %s", miBpt.getAddress()))); //$NON-NLS-1$ } } @@ -706,6 +732,93 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI true); } + private ICBreakpoint createPlatformDynamicPrintf(String fileName, MIBreakpoint miBpt) throws CoreException { + if (isAddressBreakpoint(miBpt)) { + return createPlatformAddressDynamicPrintf(fileName, miBpt); + } + // TODO This is currently causing problems because we think a normal dprintf is a function one +// else if (isFunctionBreakpoint(miBpt)) { +// return createPlatformFunctionDynamicPrintf(fileName, miBpt); +// } + else { + return createPlatformLineDynamicPrintf(fileName, miBpt); + } + } + + private ICBreakpoint createPlatformAddressDynamicPrintf(String fileName, MIBreakpoint miBpt) throws CoreException { + IResource resource = getResource(fileName); + + int type = 0; + if (miBpt.isTemporary()) + type |= ICBreakpointType.TEMPORARY; + if (miBpt.isHardware()) + type |= ICBreakpointType.HARDWARE; + + try { + return CDIDebugModel.createAddressDynamicPrintf( + null, + null, + resource, + type, + getLineNumber(miBpt), + getPlatformAddress(miBpt.getAddress()), + miBpt.isEnabled(), + miBpt.getIgnoreCount(), + miBpt.getCondition(), + miBpt.getPrintfString(), + true); + } + catch(NumberFormatException e) { + throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.getUniqueIdentifier(), + String.format("Invalid breakpoint address: %s", miBpt.getAddress()))); //$NON-NLS-1$ + } + } + + private ICBreakpoint createPlatformFunctionDynamicPrintf(String fileName, MIBreakpoint miBpt) throws CoreException { + IResource resource = getResource(fileName); + + int type = 0; + if (miBpt.isTemporary()) + type |= ICBreakpointType.TEMPORARY; + if (miBpt.isHardware()) + type |= ICBreakpointType.HARDWARE; + + return CDIDebugModel.createFunctionDynamicPrintf( + fileName, + resource, + type, + getFunctionName(miBpt), + -1, + -1, + getLineNumber(miBpt), + miBpt.isEnabled(), + miBpt.getIgnoreCount(), + miBpt.getCondition(), + miBpt.getPrintfString(), + true); + } + + private ICBreakpoint createPlatformLineDynamicPrintf(String fileName, MIBreakpoint miBpt) throws CoreException { + IResource resource = getResource(fileName); + + int type = 0; + if (miBpt.isTemporary()) + type |= ICBreakpointType.TEMPORARY; + if (miBpt.isHardware()) + type |= ICBreakpointType.HARDWARE; + + return CDIDebugModel.createLineDynamicPrintf( + fileName, + resource, + type, + getLineNumber(miBpt), + miBpt.isEnabled(), + miBpt.getIgnoreCount(), + miBpt.getCondition(), + miBpt.getPrintfString(), + true); + } + private ICBreakpoint createPlatformWatchpoint(String fileName, MIBreakpoint miBpt) throws CoreException { IResource resource = getResource(fileName); @@ -774,6 +887,16 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI (Boolean)attributes.get(MIBreakpointDMData.IS_HARDWARE), (Boolean)attributes.get(MIBreakpointDMData.IS_TEMPORARY))); } + else if (MIBreakpoints.DYNAMICPRINTF.equals(type)) { + rm.done(getTargetDPrintf( + map.values(), + (String)attributes.get(MIBreakpoints.FILE_NAME), + (Integer)attributes.get(MIBreakpoints.LINE_NUMBER), + (String)attributes.get(MIBreakpoints.FUNCTION), + (String)attributes.get(MIBreakpoints.ADDRESS), + (Boolean)attributes.get(MIBreakpointDMData.IS_HARDWARE), + (Boolean)attributes.get(MIBreakpointDMData.IS_TEMPORARY))); + } else if (MIBreakpoints.WATCHPOINT.equals(type)) { rm.done(getTargetWatchpoint( map.values(), @@ -797,7 +920,7 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI Boolean isHardware, Boolean isTemporary) { for (MIBreakpoint miBpt : targetBreakpoints) { - if (!miBpt.isWatchpoint() && !isCatchpoint(miBpt) && !miBpt.isTracepoint() + if (!miBpt.isWatchpoint() && !isCatchpoint(miBpt) && !miBpt.isTracepoint() && !miBpt.isDynamicPrintf() && compareBreakpointAttributes( miBpt, fileName, lineNumber, function, address, isHardware, isTemporary)) return miBpt; @@ -821,6 +944,23 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI } return null; } + + private MIBreakpoint getTargetDPrintf( + Collection targetBreakpoints, + String fileName, + Integer lineNumber, + String function, + String address, + Boolean isHardware, + Boolean isTemporary) { + for (MIBreakpoint miBpt : targetBreakpoints) { + if (miBpt.isDynamicPrintf() + && compareBreakpointAttributes( + miBpt, fileName, lineNumber, function, address, isHardware, isTemporary)) + return miBpt; + } + return null; + } private MIBreakpoint getTargetWatchpoint( Collection targetBreakpoints, @@ -961,6 +1101,10 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI private boolean isPlatformTracepoint(ICTracepoint plBpt, MIBreakpoint miBpt, String fileName) { return isPlatformLineBreakpoint(plBpt, miBpt, fileName); } + + private boolean isPlatformDynamicPrintf(ICDynamicPrintf plBpt, MIBreakpoint miBpt, String fileName) { + return isPlatformLineBreakpoint(plBpt, miBpt, fileName); + } public boolean isTargetBreakpointDeleted(IBreakpointsTargetDMContext context, int bpId, boolean remove) { Set set = fDeletedTargetBreakpoints.get(context); @@ -1273,6 +1417,8 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI int index = origLocation.lastIndexOf(':'); String function = (index >= 0) ? origLocation.substring(index + 1) : origLocation; try { + //TODO This does not work for dprintf since the output of the orginal location can look like this: + //original-location="/home/lmckhou/runtime-TestDSF/Producer/src/Producer.cpp:100,\\"Hit line %d of /home/lmckhou/runtime-TestDSF/Producer/src/Producer.cpp\\\\n\\",100" Integer.valueOf(function); // Line breakpoint return ""; //$NON-NLS-1$ diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CLIEventProcessor_7_0.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CLIEventProcessor_7_0.java index b91401806dd..2195dd4ea0c 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CLIEventProcessor_7_0.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CLIEventProcessor_7_0.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2010 QNX Software Systems and others. + * Copyright (c) 2008, 2014 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 @@ -24,7 +24,6 @@ import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService; import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; import org.eclipse.cdt.dsf.debug.service.command.ICommandResult; import org.eclipse.cdt.dsf.debug.service.command.ICommandToken; -import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; import org.eclipse.cdt.dsf.mi.service.command.commands.CLICommand; import org.eclipse.cdt.dsf.mi.service.command.commands.MIInterpreterExecConsole; import org.eclipse.cdt.dsf.mi.service.command.events.MIBreakpointChangedEvent; @@ -32,7 +31,6 @@ import org.eclipse.cdt.dsf.mi.service.command.events.MIDetachedEvent; import org.eclipse.cdt.dsf.mi.service.command.events.MIEvent; import org.eclipse.cdt.dsf.mi.service.command.events.MIRunningEvent; import org.eclipse.cdt.dsf.mi.service.command.events.MISignalChangedEvent; -import org.eclipse.cdt.dsf.service.DsfServicesTracker; /** * GDB debugger output listener. @@ -44,11 +42,8 @@ public class CLIEventProcessor_7_0 { private final ICommandControlService fCommandControl; - private final DsfServicesTracker fServicesTracker; - public CLIEventProcessor_7_0(ICommandControlService connection, ICommandControlDMContext controlDmc) { fCommandControl = connection; - fServicesTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fCommandControl.getSession().getId()); fCommandControl.addCommandListener(this); fCommandControl.addEventListener(this); } @@ -57,7 +52,6 @@ public class CLIEventProcessor_7_0 public void dispose() { fCommandControl.removeCommandListener(this); fCommandControl.removeEventListener(this); - fServicesTracker.dispose(); } @Override diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CLIEventProcessor_7_7.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CLIEventProcessor_7_7.java new file mode 100644 index 00000000000..3cba21a4af5 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CLIEventProcessor_7_7.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.mi.service.command; + +import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor; +import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor; +import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService; +import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; +import org.eclipse.cdt.dsf.mi.service.IMICommandControl; +import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetDPrintfStyle; +import org.eclipse.cdt.dsf.mi.service.command.output.MIConsoleStreamOutput; +import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; +import org.eclipse.cdt.dsf.mi.service.command.output.MIOOBRecord; +import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput; + +/** + * @since 4.4 + */ +@ConfinedToDsfExecutor("fConnection#getExecutor") +public class CLIEventProcessor_7_7 extends CLIEventProcessor_7_0 + implements IEventProcessor +{ + private final ICommandControlService fControl; + private boolean fResetDPrintfStyle; + + public CLIEventProcessor_7_7(ICommandControlService connection, ICommandControlDMContext controlDmc) { + super(connection, controlDmc); + fControl = connection; + } + + @Override + public void eventReceived(Object output) { + if (!fResetDPrintfStyle) { + // Only do this if we haven't already reset the dprintf style + for (MIOOBRecord oobr : ((MIOutput)output).getMIOOBRecords()) { + if (oobr instanceof MIConsoleStreamOutput) { + MIConsoleStreamOutput exec = (MIConsoleStreamOutput) oobr; + + // Look for a printout that indicates that we cannot call inferior methods. + // This affects Ubuntu 32bit OS + if (exec.getCString().indexOf("Cannot call inferior functions") != -1) { //$NON-NLS-1$ + // In this case, make sure we use the 'gdb' style of dprintf + // and not the 'call' one. + fResetDPrintfStyle = true; + if (fControl instanceof IMICommandControl) { + CommandFactory factory = ((IMICommandControl)fControl).getCommandFactory(); + fControl.queueCommand( + factory.createMIGDBSetDPrintfStyle(fControl.getContext(), MIGDBSetDPrintfStyle.GDB_STYLE), + new ImmediateDataRequestMonitor() { + @Override + protected void handleCompleted() { + // We accept errors + } + }); + } + } + } + } + } + super.eventReceived(output); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CommandFactory.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CommandFactory.java index 6ccefadf562..8aa9548116f 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CommandFactory.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CommandFactory.java @@ -24,6 +24,7 @@ * Philippe Gil (AdaCore) - Add show/set language CLI commands (Bug 421541) * Dmitry Kozlov (Mentor Graphics) - New trace-related methods (Bug 390827) * Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730) + * Marc Khouzam (Ericsson) - Support for dynamic printf (Bug 400638) *******************************************************************************/ package org.eclipse.cdt.dsf.mi.service.command; @@ -75,6 +76,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakInsert; import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakList; import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakPasscount; import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakWatch; +import org.eclipse.cdt.dsf.mi.service.command.commands.MIDPrintfInsert; import org.eclipse.cdt.dsf.mi.service.command.commands.MIDataDisassemble; import org.eclipse.cdt.dsf.mi.service.command.commands.MIDataEvaluateExpression; import org.eclipse.cdt.dsf.mi.service.command.commands.MIDataListRegisterNames; @@ -114,6 +116,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetAutoSolib; import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetBreakpointPending; import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetCharset; import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetCircularTraceBuffer; +import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetDPrintfStyle; import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetDetachOnFork; import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetDisconnectedTracing; import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetEnv; @@ -502,6 +505,12 @@ public class CommandFactory { public ICommand createMIDataWriteMemoryBytes(IDMContext ctx, String address, byte[] contents) { return new MIDataWriteMemoryBytes(ctx, address, contents); } + + /** @since 4.4 */ + public ICommand createMIDPrintfInsert(IBreakpointsTargetDMContext ctx, boolean isTemporary, + String condition, int ignoreCount, int tid, boolean disabled, String location, String printfStr) { + return new MIDPrintfInsert(ctx, isTemporary, condition, ignoreCount, tid, disabled, true, location, printfStr); + } /** @since 4.0 */ public ICommand createMIEnablePrettyPrinting(ICommandControlDMContext ctx) { @@ -722,6 +731,11 @@ public class CommandFactory { return new MIGDBSetDisconnectedTracing(ctx, disconnectedTracing); } + /** @since 4.4 */ + public ICommand createMIGDBSetDPrintfStyle(ICommandControlDMContext ctx, String style) { + return new MIGDBSetDPrintfStyle(ctx, style); + } + public ICommand createMIGDBSetEnv(ICommandControlDMContext dmc, String name) { return new MIGDBSetEnv(dmc, name); } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIDPrintfInsert.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIDPrintfInsert.java new file mode 100644 index 00000000000..87a21fc161f --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIDPrintfInsert.java @@ -0,0 +1,170 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.mi.service.command.commands; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.cdt.dsf.gdb.breakpoints.GDBDynamicPrintfUtils; +import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo; +import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput; + +/** + * -dprintf-insert [ -t ] [ -f ] [ -d ] + * [ -c CONDITION ] [ -i IGNORE-COUNT ] + * [ -p THREAD ] [ LOCATION ] [ FORMAT ] [ ARGUMENT ] + * + * If specified, LOCATION, can be one of: + * * function + * * filename:linenum + * * filename:function + * * *address + * + * + * The possible optional parameters of this command are: + * + * '-t' + * Insert a temporary dprintf. + * + * '-c CONDITION' + * Make the dprintf conditional on CONDITION. + * + * '-i IGNORE-COUNT' + * Initialize the IGNORE-COUNT. + * + * '-f' + * If location cannot be parsed (for example if it refers to unknown files or + * functions), create a pending dprintf. Without this flag, if a location + * cannot be parsed, the dprintf will not be created and an error will be + * reported. + * + * '-d' + * Create a disabled dprintf. + * + * '-p THREAD' + * THREAD on which to apply the dprintf + * + * Available with GDB 7.7. + * + * @since 4.4 + */ +public class MIDPrintfInsert extends MICommand +{ + public MIDPrintfInsert(IBreakpointsTargetDMContext ctx, boolean isTemporary, + String condition, int ignoreCount, int tid, boolean disabled, + boolean allowPending, String location, String printfStr) { + super(ctx, "-dprintf-insert"); //$NON-NLS-1$ + + // Determine the number of optional parameters that are present + // and allocate a corresponding string array + int i = 0; + if (isTemporary) { + i++; + } + if (condition != null && condition.length() > 0) { + i += 2; + } + if (ignoreCount > 0) { + i += 2; + } + if (tid > 0) { + i += 2; + } + if (disabled) { + i++; + } + if (allowPending) { + i ++; + } + + String[] opts = new String[i]; + + // Fill in the optional parameters + i = 0; + if (isTemporary) { + opts[i] = "-t"; //$NON-NLS-1$ + i++; + } + if (condition != null && condition.length() > 0) { + opts[i] = "-c"; //$NON-NLS-1$ + i++; + opts[i] = condition; + i++; + } + if (ignoreCount > 0) { + opts[i] = "-i"; //$NON-NLS-1$ + i++; + opts[i] = Integer.toString(ignoreCount); + i++; + } + if (tid > 0) { + opts[i] = "-p"; //$NON-NLS-1$ + i++; + opts[i] = Integer.toString(tid); + i++; + } + if (disabled) { + opts[i] = "-d"; //$NON-NLS-1$ + i++; + } + if (allowPending) { + opts[i] = "-f"; //$NON-NLS-1$ + i ++; + } + + if (opts.length > 0) { + setOptions(opts); + } + + setParameters(createParameters(location, printfStr)); + } + + private Adjustable[] createParameters(String location, String printfStr) { + List paramsList = new ArrayList(); + + paramsList.add(new MIStandardParameterAdjustable(location)); + + GDBDynamicPrintfUtils.GDBDynamicPrintfString parsedStr = + new GDBDynamicPrintfUtils.GDBDynamicPrintfString(printfStr); + + if (parsedStr.isValid()) { + paramsList.add(new DPrintfAdjustable(parsedStr.getString())); + for (String arg : parsedStr.getArguments()) { + paramsList.add(new MIStandardParameterAdjustable(arg)); + } + } + + return paramsList.toArray(new Adjustable[paramsList.size()]); + } + + @Override + public MIBreakInsertInfo getResult(MIOutput output) { + return new MIBreakInsertInfo(output); + } + + /** + * This adjustable makes sure that the dprintf parameters will not be modified + * any further. The reason for that is that the -dprintf-insert command + * accepts the quoted string and any \n directly. + */ + private class DPrintfAdjustable extends MICommandAdjustable { + public DPrintfAdjustable(String value) { + super(value); + } + + @Override + public String getAdjustedValue() { + return getValue(); + } + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIGDBSetDPrintfStyle.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIGDBSetDPrintfStyle.java new file mode 100644 index 00000000000..873b062d420 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIGDBSetDPrintfStyle.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.mi.service.command.commands; + +import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; + +/** + * -gdb-set dprintf-style STYLE + * + * Set the dprintf output to be handled in one of several different styles enumerated below. + * A change of style affects all existing dynamic printfs immediately. + * + * gdb + * Handle the output using the gdb printf command. + * call + * Handle the output by calling a function in your program (normally printf). + * agent + * Have the remote debugging agent (such as gdbserver) handle the output itself. + * This style is only available for agents that support running commands on the target. + * + * @since 4.4 + */ +public class MIGDBSetDPrintfStyle extends MIGDBSet { + + public static final String GDB_STYLE = "gdb"; //$NON-NLS-1$ + public static final String CALL_STYLE = "call"; //$NON-NLS-1$ + public static final String AGENT_STYLE = "agent"; //$NON-NLS-1$ + + public MIGDBSetDPrintfStyle(ICommandControlDMContext dmc, String style) { + super(dmc, new String[] { "dprintf-style", style }); //$NON-NLS-1$ + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIBreakpoint.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIBreakpoint.java index f65e4a6b54f..1cfcfda46fa 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIBreakpoint.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIBreakpoint.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 QNX Software Systems and others. + * Copyright (c) 2000, 2014 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 @@ -12,6 +12,7 @@ * Ericsson - Added Tracepoint support (284286) * Abeer Bagul (Tensilica) - Differentiate between hw breakpoint and watchpoint * Marc Khouzam (Ericsson) - Add 'thread-group' field (bug 360735) + * Marc Khouzam (Ericsson) - Support for dynamic printf (bug 400628) *******************************************************************************/ package org.eclipse.cdt.dsf.mi.service.command.output; @@ -85,7 +86,9 @@ public class MIBreakpoint { // For tracepoints int passcount = 0; - + // For dynamic printf + String printfString; + boolean isWpt = false; boolean isAWpt = false; boolean isRWpt = false; @@ -102,6 +105,9 @@ public class MIBreakpoint { /** See {@link #getCatchpointType()} */ private String catchpointType; + /** See {@link #isDynamicPrintf()} */ + private boolean isDynPrintf; + /** * A pending breakpoint is a breakpoint that did not install properly, * but that will be kept in the hopes that it installs later, triggered by @@ -145,6 +151,7 @@ public class MIBreakpoint { isTpt = other.isTpt; isCatchpoint = other.isCatchpoint; catchpointType = other.catchpointType; + isDynPrintf = other.isDynPrintf; pending = other.pending; originalLocation = other.originalLocation; if (other.groupIds != null) { @@ -385,6 +392,15 @@ public class MIBreakpoint { return isCatchpoint; } + /** + * Indicates if we are dealing with a dynamic printf. + * + * @since 4.4 + */ + public boolean isDynamicPrintf() { + return isDynPrintf; + } + /** * Returns the passcount of a tracepoint. Will return 0 if this * breakpoint is not a tracepoint. @@ -423,6 +439,33 @@ public class MIBreakpoint { commands = cmds; } + /** + * Return the string the dynamic printf will print. + * Returns null if this breakpoint is not a dynamic printf + * + * @since 4.4 + */ + public String getPrintfString() { + if (!isDynamicPrintf()) return null; + + if (printfString == null) { + // The string is burried inside the list of commands. + // There should be only one command so we shouldn't need the delimiter but it does + // not hurt to use it. This delimeter is inserted when we parse the commands + // from the result obtained from GDB + String[] commands = getCommands().split(TracepointActionManager.TRACEPOINT_ACTION_DELIMITER); + final String printfToken = "printf"; //$NON-NLS-1$ + for (String cmd : commands) { + int pos = cmd.indexOf(printfToken); + if (pos != -1) { + printfString = cmd.substring(pos + printfToken.length() + 1); + } + } + // assert false : "Could not get printf string from gdb output"; //$NON-NLS-1$ + } + return printfString; + } + /** * Returns wether this breakpoint is pending * @@ -499,6 +542,9 @@ public class MIBreakpoint { if (type.startsWith("catchpoint")) { //$NON-NLS-1$ isCatchpoint = true; } + if (type.startsWith("dprintf")) { //$NON-NLS-1$ + isDynPrintf = true; + } // type="breakpoint" // default ok. } else if (var.equals("disp")) { //$NON-NLS-1$ diff --git a/dsf/org.eclipse.cdt.dsf.ui/META-INF/MANIFEST.MF b/dsf/org.eclipse.cdt.dsf.ui/META-INF/MANIFEST.MF index 5ffa11742c4..2dc2d0844c5 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/META-INF/MANIFEST.MF +++ b/dsf/org.eclipse.cdt.dsf.ui/META-INF/MANIFEST.MF @@ -27,7 +27,7 @@ Export-Package: org.eclipse.cdt.dsf.debug.internal.ui;x-internal:=true, org.eclipse.cdt.dsf.debug.internal.ui.debugview.layout;x-internal:=true, org.eclipse.cdt.dsf.debug.internal.ui.debugview.layout.actions, org.eclipse.cdt.dsf.debug.internal.ui.disassembly;x-internal:=true, - org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions;x-internal:=true, + org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions;x-friends:="org.eclipse.cdt.dsf.gdb.ui", org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model;x-internal:=true, org.eclipse.cdt.dsf.debug.internal.ui.disassembly.preferences;x-internal:=true, org.eclipse.cdt.dsf.debug.internal.ui.disassembly.presentation;x-internal:=true, diff --git a/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/GDBJtagDSFFinalLaunchSequence_7_7.java b/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/GDBJtagDSFFinalLaunchSequence_7_7.java new file mode 100644 index 00000000000..1f37be03b4d --- /dev/null +++ b/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/GDBJtagDSFFinalLaunchSequence_7_7.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.gdbjtag.core; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.concurrent.RequestMonitorWithProgress; +import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl; +import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetDPrintfStyle; +import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; +import org.eclipse.cdt.dsf.service.DsfSession; + +/** + * Subclass for GDB >= 7.7. + * + * @since 8.4 + */ +public class GDBJtagDSFFinalLaunchSequence_7_7 extends GDBJtagDSFFinalLaunchSequence_7_2 { + + public GDBJtagDSFFinalLaunchSequence_7_7(DsfSession session, Map attributes, RequestMonitorWithProgress rm) { + super(session, attributes, rm); + } + + @Override + protected String[] getExecutionOrder(String group) { + if (GROUP_TOP_LEVEL.equals(group)) { + // Initialize the list with the base class' steps + // We need to create a list that we can modify, which is why we create our own ArrayList. + List orderList = new ArrayList(Arrays.asList(super.getExecutionOrder(GROUP_TOP_LEVEL))); + + // Add the dprintf style steps before we source the gdbinit file + orderList.add(orderList.indexOf("stepSourceGDBInitFile"), "stepSetDPrinfStyle"); //$NON-NLS-1$ //$NON-NLS-2$ + + return orderList.toArray(new String[orderList.size()]); + } + + return super.getExecutionOrder(group); + } + + /** + * Specify how dynamic printf should be handled by GDB. + */ + @Execute + public void stepSetDPrinfStyle(final RequestMonitor rm) { + DsfServicesTracker tracker = new DsfServicesTracker(Activator.getBundleContext(), getSession().getId()); + IGDBControl gdbControl = tracker.getService(IGDBControl.class); + tracker.dispose(); + + if (gdbControl != null) { + // For hardware debug the 'call' style does not work with GDB + // Let's use the 'gdb' style instead + gdbControl.queueCommand( + gdbControl.getCommandFactory().createMIGDBSetDPrintfStyle(gdbControl.getContext(), + MIGDBSetDPrintfStyle.GDB_STYLE), + new ImmediateDataRequestMonitor(rm) { + @Override + protected void handleCompleted() { + // We accept errors + rm.done(); + } + }); + } + } +} diff --git a/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/dsf/gdb/service/GDBJtagControl_7_7.java b/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/dsf/gdb/service/GDBJtagControl_7_7.java new file mode 100644 index 00000000000..11e07d487bc --- /dev/null +++ b/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/dsf/gdb/service/GDBJtagControl_7_7.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.gdbjtag.core.dsf.gdb.service; + +import java.util.Map; + +import org.eclipse.cdt.debug.gdbjtag.core.GDBJtagDSFFinalLaunchSequence_7_7; +import org.eclipse.cdt.dsf.concurrent.RequestMonitorWithProgress; +import org.eclipse.cdt.dsf.concurrent.Sequence; +import org.eclipse.cdt.dsf.gdb.service.command.GDBControl_7_7; +import org.eclipse.cdt.dsf.mi.service.command.CommandFactory; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.debug.core.ILaunchConfiguration; + + +/** + * Jtag control service which selects the Jtag CompleteInitializationSequence. + * Use for GDB >= 7.7 + * @since 8.4 + */ +public class GDBJtagControl_7_7 extends GDBControl_7_7 { + + public GDBJtagControl_7_7(DsfSession session, ILaunchConfiguration config, CommandFactory factory) { + super(session, config, factory); + } + + @Override + protected Sequence getCompleteInitializationSequence(Map attributes, RequestMonitorWithProgress rm) { + return new GDBJtagDSFFinalLaunchSequence_7_7(getSession(), attributes, rm); + } +} \ No newline at end of file diff --git a/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/dsf/gdb/service/GdbJtagDebugServicesFactory.java b/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/dsf/gdb/service/GdbJtagDebugServicesFactory.java index 31aed552127..b226a1f38d1 100644 --- a/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/dsf/gdb/service/GdbJtagDebugServicesFactory.java +++ b/jtag/org.eclipse.cdt.debug.gdbjtag.core/src/org/eclipse/cdt/debug/gdbjtag/core/dsf/gdb/service/GdbJtagDebugServicesFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011 Ericsson and others. + * Copyright (c) 2011,2014 Ericsson 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 @@ -30,6 +30,9 @@ public class GdbJtagDebugServicesFactory extends GdbDebugServicesFactory { @Override protected ICommandControl createCommandControl(DsfSession session, ILaunchConfiguration config) { + if (GDB_7_7_VERSION.compareTo(getVersion()) <= 0) { + return new GDBJtagControl_7_7(session, config, new CommandFactory_6_8()); + } if (GDB_7_4_VERSION.compareTo(getVersion()) <= 0) { return new GDBJtagControl_7_4(session, config, new CommandFactory_6_8()); }