diff options
author | Stephan Herrmann | 2020-02-20 17:17:15 +0000 |
---|---|---|
committer | Stephan Herrmann | 2020-02-20 20:22:09 +0000 |
commit | 27e8ae4f1f4b520ff95a8e618b5ef9add0426831 (patch) | |
tree | e77dcff41abe93f7165ed5310831f34a10178de7 | |
parent | 9a20b327ccaa1613afe3510164856013b164e9bd (diff) | |
download | eclipse.jdt.debug-27e8ae4f1f4b520ff95a8e618b5ef9add0426831.tar.gz eclipse.jdt.debug-27e8ae4f1f4b520ff95a8e618b5ef9add0426831.tar.xz eclipse.jdt.debug-27e8ae4f1f4b520ff95a8e618b5ef9add0426831.zip |
Bug 559742 - Overenthusiastic Repeated exception occurrenceX20200223-1900X20200223-0700X20200223-0250X20200222-0700X20200221-1130X20200221-0700I20200223-2335I20200223-1800I20200223-0600I20200222-1800I20200222-0600I20200221-1800
Change-Id: I14d2552b61cc74d0359cd278662d240eb283c312
5 files changed, 221 insertions, 2 deletions
diff --git a/org.eclipse.jdt.debug.tests/testprograms/ErrorRecurrence.java b/org.eclipse.jdt.debug.tests/testprograms/ErrorRecurrence.java new file mode 100644 index 000000000..916db7cac --- /dev/null +++ b/org.eclipse.jdt.debug.tests/testprograms/ErrorRecurrence.java @@ -0,0 +1,28 @@ + +public class ErrorRecurrence { + + public static void main(String[] args) { + m0(); // L5 + } + static void m0() { + try { + m1(); + } finally { + System.out.println("finally"); + } // L12 + } + + static void m1() { + try { + m2(); + } catch (Error e) { + System.out.println("caught"); + throw e; // L20 + } + } + + static void m2() { + System.out.println("before throw"); + throw new Error(); // L26 + } +} diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java index ea193de06..9aa6ac1fa 100644 --- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java +++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java @@ -205,7 +205,8 @@ public abstract class AbstractDebugTest extends TestCase implements IEvaluation "org.eclipse.debug.tests.targets.HcrClass5", "org.eclipse.debug.tests.targets.HcrClass6", "org.eclipse.debug.tests.targets.HcrClass7", "org.eclipse.debug.tests.targets.HcrClass8", "org.eclipse.debug.tests.targets.HcrClass9", "TestContributedStepFilterClass", "TerminateAll_01", "TerminateAll_02", "StepResult1", "StepResult2", "StepResult3", "StepUncaught", "TriggerPoint_01", "BulkThreadCreationTest", "MethodExitAndException", - "Bug534319earlyStart", "Bug534319lateStart", "Bug534319singleThread", "Bug534319startBetwen", "MethodCall", "Bug538303", "Bug540243", "OutSync", "OutSync2", "ConsoleOutputUmlaut" }; + "Bug534319earlyStart", "Bug534319lateStart", "Bug534319singleThread", "Bug534319startBetwen", "MethodCall", "Bug538303", "Bug540243", + "OutSync", "OutSync2", "ConsoleOutputUmlaut", "ErrorRecurrence" }; /** * the default timeout diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java index 8ed5ac98a..8b73956bf 100644 --- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java +++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2019 IBM Corporation and others. + * Copyright (c) 2000, 2020 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -39,6 +39,7 @@ import org.eclipse.jdt.debug.tests.breakpoints.MiscBreakpointsTests; import org.eclipse.jdt.debug.tests.breakpoints.PatternBreakpointTests; import org.eclipse.jdt.debug.tests.breakpoints.PreLaunchBreakpointTest; import org.eclipse.jdt.debug.tests.breakpoints.RunToLineTests; +import org.eclipse.jdt.debug.tests.breakpoints.SpecialExceptionBreakpointTests; import org.eclipse.jdt.debug.tests.breakpoints.SuspendVMBreakpointsTests; import org.eclipse.jdt.debug.tests.breakpoints.TargetPatternBreakpointTests; import org.eclipse.jdt.debug.tests.breakpoints.TestToggleBreakpointsTarget; @@ -343,6 +344,7 @@ public class AutomatedSuite extends DebugSuite { addTest(new TestSuite(BreakpointWorkingSetTests.class)); addTest(new TestSuite(MethodBreakpointTests.class)); addTest(new TestSuite(ExceptionBreakpointTests.class)); + addTest(new TestSuite(SpecialExceptionBreakpointTests.class)); addTest(new TestSuite(WatchpointTests.class)); addTest(new TestSuite(PatternBreakpointTests.class)); addTest(new TestSuite(TargetPatternBreakpointTests.class)); diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/SpecialExceptionBreakpointTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/SpecialExceptionBreakpointTests.java new file mode 100644 index 000000000..dfdcc5a83 --- /dev/null +++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/SpecialExceptionBreakpointTests.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * Copyright (c) 2020 GK Software SE and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Stephan Herrmann - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.debug.tests.breakpoints; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint; +import org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint.SuspendOnRecurrenceStrategy; +import org.eclipse.jdt.debug.core.IJavaStackFrame; +import org.eclipse.jdt.debug.core.IJavaThread; +import org.eclipse.jdt.debug.core.JDIDebugModel; +import org.eclipse.jdt.debug.tests.AbstractDebugTest; +import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin; +import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants; +import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; +import org.eclipse.jdt.internal.debug.ui.JavaDebugOptionsManager; +import org.eclipse.jface.preference.IPreferenceStore; + +public class SpecialExceptionBreakpointTests extends AbstractDebugTest { + + private boolean fDefaultSuspendOnUncaught; + private boolean fDefaultSuspendOnCompilationErrors; + private SuspendOnRecurrenceStrategy fDefaultRecurrenceStrategy; + + public SpecialExceptionBreakpointTests(String name) { + super(name); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + IPreferenceStore uiPrefStore = JDIDebugUIPlugin.getDefault().getPreferenceStore(); + fDefaultSuspendOnUncaught = uiPrefStore.getBoolean(IJDIPreferencesConstants.PREF_SUSPEND_ON_UNCAUGHT_EXCEPTIONS); + fDefaultSuspendOnCompilationErrors = uiPrefStore.getBoolean(IJDIPreferencesConstants.PREF_SUSPEND_ON_COMPILATION_ERRORS); + IEclipsePreferences prefs = InstanceScope.INSTANCE.getNode(JDIDebugPlugin.getUniqueIdentifier()); + String val = prefs.get(JDIDebugModel.PREF_SUSPEND_ON_RECURRENCE_STRATEGY, SuspendOnRecurrenceStrategy.RECURRENCE_UNCONFIGURED.name()); + fDefaultRecurrenceStrategy = SuspendOnRecurrenceStrategy.valueOf(val); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + setPreferences(fDefaultSuspendOnUncaught, fDefaultSuspendOnCompilationErrors, fDefaultRecurrenceStrategy); + } + + void setPreferences(boolean suspUncaught, boolean suspCompErr, SuspendOnRecurrenceStrategy recurr) { + IPreferenceStore uiPrefStore = JDIDebugUIPlugin.getDefault().getPreferenceStore(); + uiPrefStore.setValue(IJDIPreferencesConstants.PREF_SUSPEND_ON_UNCAUGHT_EXCEPTIONS, suspUncaught); + uiPrefStore.setValue(IJDIPreferencesConstants.PREF_SUSPEND_ON_COMPILATION_ERRORS, suspCompErr); + IEclipsePreferences prefs = InstanceScope.INSTANCE.getNode(JDIDebugPlugin.getUniqueIdentifier()); + prefs.put(JDIDebugModel.PREF_SUSPEND_ON_RECURRENCE_STRATEGY, recurr.name()); + } + + public void testCaughtException_compErr() throws Exception { + caughtException(true); + } + public void testCaughtException() throws Exception { + caughtException(false); + } + void caughtException(boolean suspendOnCompErr) throws Exception { + setPreferences(true, suspendOnCompErr, SuspendOnRecurrenceStrategy.SUSPEND_ALWAYS); + + String typeName = "ErrorRecurrence"; + IJavaExceptionBreakpoint ex = createExceptionBreakpoint("java.lang.Error", true, true); + + IJavaThread thread = null; + try { + thread = launchToBreakpoint(typeName); + assertNotNull("1. Breakpoint not hit within timeout period", thread); + assertEquals("Line of 1. suspend", 26, thread.getTopStackFrame().getLineNumber()); + assertExceptionBreakpointHit(thread, ex); + + thread = resume(thread); + assertExceptionBreakpointHit(thread, ex); + assertNotNull("2. Breakpoint not hit within timeout period", thread); + assertEquals("Line of 2. suspend", 20, thread.getTopStackFrame().getLineNumber()); + + thread = resume(thread); + assertExceptionBreakpointHit(thread, ex); + assertNotNull("3. Breakpoint not hit within timeout period", thread); + assertEquals("Line of 3. suspend", 12, thread.getTopStackFrame().getLineNumber()); + + resumeAndExit(thread); + ex.delete(); + } finally { + terminateAndRemove(thread); + removeAllBreakpoints(); + } + } + + public void testCaughtExceptionSkip_uncaught_compErr() throws Exception { + caughtExceptionSkip_uncaught(true); + } + public void testCaughtExceptionSkip_uncaught() throws Exception { + caughtExceptionSkip_uncaught(false); + } + void caughtExceptionSkip_uncaught(boolean suspendOnCompErr) throws Exception { + setPreferences(true, suspendOnCompErr, SuspendOnRecurrenceStrategy.SKIP_RECURRENCES); + + String typeName = "ErrorRecurrence"; + IJavaExceptionBreakpoint ex = createExceptionBreakpoint("java.lang.Error", true, true); + + IJavaThread thread = null; + try { + thread = launchToBreakpoint(typeName); + assertNotNull("1. Breakpoint not hit within timeout period", thread); + assertEquals("Line of 1. suspend", 26, thread.getTopStackFrame().getLineNumber()); + assertExceptionBreakpointHit(thread, ex); + + // L20 skipped recurrence + + // L12: uncaught: + thread = resume(thread); + assertExceptionBreakpointHit(thread, ex); + assertNotNull("2. Breakpoint not hit within timeout period", thread); + assertEquals("Line of 2. suspend", 12, thread.getTopStackFrame().getLineNumber()); + + resumeAndExit(thread); + ex.delete(); + } finally { + terminateAndRemove(thread); + removeAllBreakpoints(); + } + } + + public void testCaughtExceptionSkip_compErr() throws Exception { + caughtExceptionSkip(true); + } + public void testCaughtExceptionSkip() throws Exception { + caughtExceptionSkip(false); + } + void caughtExceptionSkip(boolean suspendOnCompErr) throws Exception { + setPreferences(false, suspendOnCompErr, SuspendOnRecurrenceStrategy.SKIP_RECURRENCES); + + String typeName = "ErrorRecurrence"; + IJavaExceptionBreakpoint ex = createExceptionBreakpoint("java.lang.Error", true, true); + + IJavaThread thread = null; + try { + thread = launchToBreakpoint(typeName); + assertNotNull("1. Breakpoint not hit within timeout period", thread); + assertEquals("Line of 1. suspend", 26, thread.getTopStackFrame().getLineNumber()); + assertExceptionBreakpointHit(thread, ex); + + // L20 skipped recurrence + + // L12 suspend on uncaught disabled + resumeAndExit(thread); + ex.delete(); + } finally { + terminateAndRemove(thread); + removeAllBreakpoints(); + } + } + + private void assertExceptionBreakpointHit(IJavaThread thread, IJavaExceptionBreakpoint ex) throws DebugException { + IMarker problem = JavaDebugOptionsManager.getDefault().getProblem((IJavaStackFrame) thread.getTopStackFrame()); + if (problem != null) { + fail("unexpected problem marker "+problem); + } + IBreakpoint hit = getBreakpoint(thread); + assertNotNull("suspended, but not by breakpoint", hit); + assertEquals("suspended, but not by expected exception", ex.getExceptionTypeName(), ((IJavaExceptionBreakpoint) hit).getExceptionTypeName()); + } +} diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugOptionsManager.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugOptionsManager.java index 63c1ff99c..d1fe3b709 100644 --- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugOptionsManager.java +++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugOptionsManager.java @@ -583,6 +583,15 @@ public class JavaDebugOptionsManager implements IDebugEventSetListener, IPropert @Override public int breakpointHit(IJavaThread thread, IJavaBreakpoint breakpoint) { if (thread instanceof JDIThread && breakpoint instanceof IJavaExceptionBreakpoint) { + try { + String[] breakpointListeners = breakpoint.getBreakpointListeners(); + if (breakpointListeners.length == 1 + && SuspendOnCompilationErrorListener.ID_COMPILATION_ERROR_LISTENER.equals(breakpointListeners[0])) { + return DONT_CARE; // not a user breakpoint + } + } catch (CoreException e1) { + // continue + } if (shouldSkipSubsequentOccurrence((JDIThread) thread, (IJavaExceptionBreakpoint) breakpoint)) { return DONT_SUSPEND; } |