From 6cd2e974700c12276afaf21c027ac78871f4d246 Mon Sep 17 00:00:00 2001 From: Jonah Graham Date: Fri, 7 Oct 2022 12:20:23 -0400 Subject: [PATCH] Bug 580873: Remove error checking on dprintf parameters The parser for dprintf parameters was much too simplistic and prevents real uses cases from operating. It is not necessary to remove the , between the arguments to dprintf, so don't try to split on that anymore. That also means we can't check for and error on mismatch between format specifiers and number of arguments. e.g. "===> XML_EVENT_TEXT(%s)\n", (char *)strtok(Text,"\n") should be permitted. The alternative would be to write a more complete parser for both the printf specification and the arguments. Well out of scope and unnecessary. Some inputs may now be accepted by the GUI and then when inserted with GDB fail. These errors are displayed in the GUI already anyway. --- NewAndNoteworthy/CDT-11.0.md | 13 +++++ .../images/CDT-11.0-dprintf-gui.png | Bin 0 -> 30588 bytes .../GDBDynamicPrintfPropertyPage.java | 28 +++++++++++ .../breakpoints/GDBDynamicPrintfUtils.java | 46 +++--------------- .../cdt/dsf/gdb/breakpoints/Messages.java | 7 --- .../dsf/gdb/breakpoints/Messages.properties | 4 -- .../data/launch/src/BreakpointTestApp.cc | 2 + .../dsf/gdb/tests/MIBreakpointsTest.java | 21 ++++++++ 8 files changed, 71 insertions(+), 50 deletions(-) create mode 100644 NewAndNoteworthy/images/CDT-11.0-dprintf-gui.png diff --git a/NewAndNoteworthy/CDT-11.0.md b/NewAndNoteworthy/CDT-11.0.md index 6b0807873ff..8d87643c3f1 100644 --- a/NewAndNoteworthy/CDT-11.0.md +++ b/NewAndNoteworthy/CDT-11.0.md @@ -10,6 +10,19 @@ This is the New & Noteworthy page for CDT 11.0 which is part of Eclipse 2022-12 Jave 17 is now required to build and run Eclipse CDT. See https://github.com/eclipse-cdt/cdt/issues/80 +# Debug + +## C/C++ Dynamic Printf Breakpoints + +Prior to CDT 11 the Dynamic Printf GUI was somewhat over restrictive rejecting formats and parameters that would have been valid for dprintf in the GDB CLI. +To achieve this improvement the checks that verified that the number of format specifiers matched the number of parameters has been removed. +The check that the required the format string to not end with a `)` has been removed as valid format parameters can have a closing paranthesis. +Instead of doing that check, the GUI now displays a `)` to make it obvious to users that the closing `)` should not be included in the setting. + +

+ +See [Bug 580873](https://bugs.eclipse.org/bugs/show_bug.cgi?id=580873). + # API Changes, current and planned Please see [CHANGELOG-API](CHANGELOG-API.md) for details on the breaking API changes in this release as well as future planned API changes. diff --git a/NewAndNoteworthy/images/CDT-11.0-dprintf-gui.png b/NewAndNoteworthy/images/CDT-11.0-dprintf-gui.png new file mode 100644 index 0000000000000000000000000000000000000000..91874fbe443d633adc9812a0fbb448b537efc632 GIT binary patch literal 30588 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 F{{h0j7)t;E literal 0 HcmV?d00001 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 index 0ceb1eae21c..a540ce926aa 100644 --- 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 @@ -43,7 +43,9 @@ import org.eclipse.jface.preference.StringFieldEditor; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IWorkbenchPropertyPage; import org.eclipse.ui.model.IWorkbenchAdapter; @@ -305,6 +307,8 @@ public class GDBDynamicPrintfPropertyPage extends FieldEditorPreferencePage impl protected void createPrintStringEditor(Composite parent) { fPrintString = new DynamicPrintfStringFieldEditor(ICDynamicPrintf.PRINTF_STRING, Messages.DynamicPrintfPropertyPage_PrintString, parent) { + private Label closingParenLabel; + @Override protected boolean doCheckState() { GDBDynamicPrintfUtils.GDBDynamicPrintfString parsedStr = new GDBDynamicPrintfUtils.GDBDynamicPrintfString( @@ -317,6 +321,30 @@ public class GDBDynamicPrintfPropertyPage extends FieldEditorPreferencePage impl return valid; } + + @Override + public int getNumberOfControls() { + return super.getNumberOfControls() + 1; + } + + @Override + protected void adjustForNumColumns(int numColumns) { + super.adjustForNumColumns(numColumns - 1); + } + + @Override + protected void doFillIntoGrid(Composite parent, int numColumns) { + super.doFillIntoGrid(parent, numColumns - 1); + if (closingParenLabel == null) { + closingParenLabel = new Label(parent, SWT.LEFT); + closingParenLabel.setFont(parent.getFont()); + closingParenLabel.setText(")"); //$NON-NLS-1$ + closingParenLabel.addDisposeListener(event -> closingParenLabel = null); + } else { + checkParent(closingParenLabel, parent); + } + + } }; addField(fPrintString); } 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 index 74842f0383c..12d798b46a7 100644 --- 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 @@ -15,7 +15,6 @@ 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. @@ -51,17 +50,10 @@ public class GDBDynamicPrintfUtils { return; } - if (str.charAt(str.length() - 1) == ')') { - fErrorMessage = Messages.DynamicPrintf_Printf_not_expecting_a_closing_parenthesis; - 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 \") + // Now go through the string and find the closing + // double-quote (but ignore any \") char[] chars = str.toCharArray(); int closingQuoteIndex = 0; - int numArgExpected = 0; for (int i = 1; i < chars.length; i++) { switch (chars[i]) { case '\\': @@ -72,11 +64,6 @@ public class GDBDynamicPrintfUtils { closingQuoteIndex = i; break; case '%': - if (chars.length > 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. @@ -101,40 +88,21 @@ public class GDBDynamicPrintfUtils { // 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; + // Remove the first , that separates the format + // from the arguments + String printfArguments = argString.substring(1); + fArgs = new String[] { printfArguments }; } // Everything is ok! 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 index d1b0ce2f6cf..0d3abead7df 100644 --- 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 @@ -22,14 +22,7 @@ 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; - /** - * @since 5.3 - */ - public static String DynamicPrintf_Printf_not_expecting_a_closing_parenthesis; 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 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 index 09b6d693573..d63e9672c17 100644 --- 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 @@ -15,8 +15,4 @@ 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_Printf_not_expecting_a_closing_parenthesis=Specify Printf parameters without a closing parenthesis 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.tests.dsf.gdb/data/launch/src/BreakpointTestApp.cc b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/data/launch/src/BreakpointTestApp.cc index c74cd664715..5e2c6bda59a 100644 --- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/data/launch/src/BreakpointTestApp.cc +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/data/launch/src/BreakpointTestApp.cc @@ -25,6 +25,8 @@ void zeroBlocks(int abc) void setBlocks() { for (int i = 0; i < ARRAY_SIZE; i++) { // LINE_NUMBER_3 + char Text[1000]; + sprintf(Text, "Text %d\nAfter", i); charBlock[i] = (char) i; // LINE_LOOP_1 integerBlock[i] = i; } diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIBreakpointsTest.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIBreakpointsTest.java index a1bfabf7236..66fb1b137e5 100644 --- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIBreakpointsTest.java +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIBreakpointsTest.java @@ -3336,6 +3336,27 @@ public class MIBreakpointsTest extends BaseParametrizedTestCase { for (int i = 0; i < 256; i++) { assertEquals("format " + i, contents[i].trim()); } + } + @Test + public void insertDprintfBreakpointBug580873() throws Throwable { + Map printfBreakpoint = new HashMap<>(); + printfBreakpoint.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.DYNAMICPRINTF); + printfBreakpoint.put(MIBreakpoints.FILE_NAME, SOURCE_NAME); + printfBreakpoint.put(MIBreakpoints.LINE_NUMBER, LINE_LOOP_1); + printfBreakpoint.put(MIBreakpoints.PRINTF_STRING, + "\"===> XML_EVENT_TEXT(%s)\\n\", (char *)strtok(Text,\"\\n\")"); + + IBreakpointDMContext printfRef = insertBreakpoint(fBreakpointsDmc, printfBreakpoint); + waitForBreakpointEvent(1); + insertBreakpoint(fBreakpointsDmc, Map.of(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG, FILE_NAME_TAG, SOURCE_NAME, + LINE_NUMBER_TAG, LINE_NUMBER_5)); + SyncUtil.resumeUntilStopped(5000); + IProcess[] processes = getGDBLaunch().getProcesses(); + IStreamMonitor outputStreamMonitor = processes[1].getStreamsProxy().getOutputStreamMonitor(); + String[] contents = outputStreamMonitor.getContents().split("\n"); + for (int i = 0; i < 256; i++) { + assertEquals("===> XML_EVENT_TEXT(Text " + i + ")", contents[i].trim()); + } } }