Repository navigation
Clean up breakpoints after marker loss - #990
carstenartur wants to merge 1 commit into
Conversation
|
This pull request changes some projects for the first time in this development cycle. An additional commit containing all the necessary changes was pushed to the top of this PR's branch. To obtain these changes (for example if you want to push more changes) either fetch from your fork or apply the git patch. Git patchFurther information are available in Common Build Issues - Missing version increments. |
f1bee33 to
e5ec99a
Compare
2030bcd to
17bf4ae
Compare
Clean up VM/proxy processes and readers when launch, attach or program startup fails, including the path used directly by VirtualMachineTest. Make shutdown safe before the event reader exists and preserve the startup failure when cleanup also fails. Wait for owned processes after normal and forced termination using bounded waits, retain interruption, and attempt proxy cleanup even if VM termination fails. Reset test state and select the next automatic port after failed startup, preserving custom VM command ports. Add 15 regression tests to the JDI AutomatedSuite, including injected lifecycle failures, process termination test doubles and a real Java subprocess. Leave the connection timeout and PR eclipse-jdt#990 unchanged. Signed-off-by: Carsten Hammer <carsten.hammer@t-online.de>
Integrate df207ce as a separately reviewable prerequisite of the breakpoint-removal change in PR eclipse-jdt#990. The infrastructure commit passed upstream Jenkins PR-992 build 2, including 1474 tests and the overall build. Its JDI test bundle is copied byte-for-byte; the original seven breakpoint-change files are unchanged. Both changes share upstream base af15c26. This does not assert that the original connection-refused failures had the silent-peer cause. The combined change now needs its own upstream CI run. Merge eclipse-jdt#992 first; its commits remain distinguishable from the feature change, rather than being squashed into it. Signed-off-by: Carsten Hammer <carsten.hammer@t-online.de>
There was a problem hiding this comment.
🟡 Changes recommended
The PR description’s stated scope (marker-loss breakpoint cleanup) doesn’t cover the additional VM startup/timeout test-harness changes, and that scope needs clarification (update description or split) before approval.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR hardens breakpoint removal/cleanup in org.eclipse.jdt.debug against cases where a breakpoint’s backing marker has been deleted/detached, ensuring target/thread state is cleaned up even when marker-dependent operations fail. It also adds new regression tests around marker-loss removal and introduces additional JDI test-harness cleanup/timeout coverage for failed VM startup paths.
Changes:
- Make breakpoint removal cleanup rely on identity and installed-state tracking rather than marker-backed equality/support checks, and ensure target/thread references are cleared in
finally. - Guard install-count updates against missing markers via
markerExists()in breakpoint request deregistration. - Add new plug-in and JDI tests covering marker-loss breakpoint cleanup and failed/timeout VM startup cleanup behavior.
File summaries
| File | Description |
|---|---|
| org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java | Remove current breakpoints by object identity to avoid marker-dependent equality. |
| org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugTarget.java | Determine “installed” via tracked breakpoints and ensure thread/target cleanup in finally. |
| org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaClassPrepareBreakpoint.java | Use markerExists() when updating install count during request deregistration. |
| org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaBreakpoint.java | Use markerExists() when updating install count during request deregistration. |
| org.eclipse.jdt.debug/META-INF/MANIFEST.MF | Bump bundle version. |
| org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/BreakpointRemovalTests.java | New plug-in tests for breakpoint cleanup after marker deletion/detachment. |
| org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java | Add BreakpointRemovalTests to the automated suite. |
| org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/VMStartupCleanupTest.java | New tests for cleanup behavior on failed VM startup paths. |
| org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/VMConnectionTimeoutTest.java | New tests ensuring attach/handshake timeouts are bounded and cleanup runs. |
| org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/TestProcessCleanup.java | New helper for bounded process termination in JDI tests. |
| org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/AutomatedSuite.java | Add new VM startup/timeout tests to the JDI automated suite. |
| org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/AbstractJDITest.java | Add exception-safe startup cleanup, bounded attach timeouts, and bounded process termination. |
Review details
- Files reviewed: 12/12 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Clean up VM/proxy processes and readers when launch, attach or program startup fails, including the path used directly by VirtualMachineTest. Make shutdown safe before the event reader exists and preserve the startup failure when cleanup also fails. Wait for owned processes after normal and forced termination using bounded waits, retain interruption, and attempt proxy cleanup even if VM termination fails. Reset test state and select the next automatic port after failed startup, preserving custom VM command ports. Add 15 regression tests to the JDI AutomatedSuite, including injected lifecycle failures, process termination test doubles and a real Java subprocess. Leave the connection timeout and PR eclipse-jdt#990 unchanged. Signed-off-by: Carsten Hammer <carsten.hammer@t-online.de>
b336664 to
0df5c2c
Compare
Keep the JDI test-infrastructure changes needed by this branch as one separately reviewable dependency snapshot. The shared harness cleans up VM/proxy processes and readers when launch, attach or program startup fails, uses bounded process termination, and bounds individual JDI attach attempts so startup cleanup remains reachable if a JDWP peer stalls during the handshake. These changes belong to eclipse-jdt#992 and are not part of the breakpoint-removal fix. After eclipse-jdt#992 is merged, eclipse-jdt#990 should be rebased onto the resulting upstream state so this dependency commit disappears from the final breakpoint-specific history. Signed-off-by: Carsten Hammer <carsten.hammer@t-online.de>
0df5c2c to
98eb02e
Compare
|
Hi @SarikaSinha and @SougandhS, Could one of you review this PR and the separate JDI test-harness prerequisite #992, or suggest another committer familiar with this area? I previously summarized the marker-loss cleanup scenarios and regression coverage in #55. The proposed integration order is to review and merge #992 first, then rebase this PR so that its remaining diff contains only the breakpoint-specific changes and tests. I appreciate that review capacity is limited. It would help to know whether this approach is suitable for JDT Debug, whether you would prefer a different split, or whether anything else is needed from my side before a review. The intention remains to address the covered cleanup scenarios, not to claim that every scenario under umbrella issue #55 is resolved. Thank you! |
|
Will check 👍 |
Clean up owned VM and proxy processes when launch, attach or program startup fails, including when failed JUnit setup bypasses teardown. Preserve the original failure and interruption state, tolerate missing readers, and bound normal and forced process termination. Bound individual JDI attach attempts by the remaining connection budget so that a stalled JDWP handshake cannot prevent startup cleanup. Retain connection failures and process diagnostics before cleanup changes state. Add regression coverage for startup failures, process termination, repeated shutdown, unavailable process IDs and stalled JDWP handshakes. Keep these changes confined to the JDI test harness. The breakpoint cleanup implementation is reviewed separately in eclipse-jdt#990.
98eb02e to
9e74405
Compare
9e74405 to
9ea93a8
Compare
Clean up owned VM and proxy processes when launch, attach or program startup fails, including when failed JUnit setup bypasses teardown. Preserve the original failure and interruption state, tolerate missing readers, and bound normal and forced process termination. Bound individual JDI attach attempts by the remaining connection budget so that a stalled JDWP handshake cannot prevent startup cleanup. Retain connection failures and process diagnostics before cleanup changes state. Add regression coverage for startup failures, process termination, repeated shutdown, unavailable process IDs and stalled JDWP handshakes. Keep these changes confined to the JDI test harness. The breakpoint cleanup implementation is reviewed separately in eclipse-jdt#990.
9ea93a8 to
965becc
Compare
|
I've just rebased on latest master |
There was a problem hiding this comment.
🟡 Changes recommended
The separate #992 JDI infrastructure commit remains included despite the stated breakpoint-only scope.
1 open finding
1 resolved since last review
🧠 Review effort: Balanced
| addTest(new TestSuite(VMConnectionTimeoutTest.class)); | ||
| addTest(new TestSuite(VMStartupCleanupTest.class)); |
Clean up owned VM and proxy processes when launch, attach or program startup fails, including when failed JUnit setup bypasses teardown. Preserve the original failure and interruption state, tolerate missing readers, and bound normal and forced process termination. Bound individual JDI attach attempts by the remaining connection budget so that a stalled JDWP handshake cannot prevent startup cleanup. Retain connection failures and process diagnostics before cleanup changes state. Add regression coverage for startup failures, process termination, repeated shutdown, unavailable process IDs and stalled JDWP handshakes. Mark intentionally unused invocation-handler parameters explicitly. Keep these changes confined to the JDI test harness. They are reviewed separately in eclipse-jdt#992 and are not a prerequisite for the breakpoint regression tests in eclipse-jdt#990. Signed-off-by: Carsten Hammer <carsten.hammer@t-online.de>
965becc to
f971f9c
Compare
Clean up owned VM and proxy processes when launch, attach or program startup fails, including when failed JUnit setup bypasses teardown. Preserve the original failure and interruption state, tolerate missing readers, and bound normal and forced process termination. Bound individual JDI attach attempts by the remaining connection budget so that a stalled JDWP handshake cannot prevent startup cleanup. Retain connection failures and process diagnostics before cleanup changes state. Add regression coverage for startup failures, process termination, repeated shutdown, unavailable process IDs and stalled JDWP handshakes. Mark intentionally unused invocation-handler parameters explicitly. Keep these changes confined to the JDI test harness. The breakpoint cleanup implementation is reviewed separately in eclipse-jdt#990. Signed-off-by: Carsten Hammer <carsten.hammer@t-online.de>
|
Thanks @iloveeclipse for the rebase. I have pushed the code/test follow-up as The two commits are intentional: one carries the JDI test-harness change reviewed separately in #992, and one contains the breakpoint fix. The infrastructure commit was restored while investigating whether separating it explained the earlier CI regression. The description was not brought back in sync, which caused understandable confusion. The focused runs do not build or load the JDI test plugin, so I no longer describe #992 as a prerequisite for the breakpoint fix. This update preserves the same upstream base and the two separately squashed changes. Build 31 had reported 1,489 passed tests, but four new unused-lambda-parameter warnings made the compiler gate unstable. Those four warning sites are now fixed. This was a different reported failure from the earlier test-process exit code 143. The additional QA found two substantive gaps: the test helper used marker-dependent hashing when recording markerless removals, and a deregistration exception could stop cleanup while other real JDI requests remained installed. The helper now records removals by identity. Request cleanup continues after a All three original cases are retained and now check unexpected error-log entries. A fourth test checks the exception path against a real VM and real requests, including a working replacement breakpoint. The test-first run reproduced the listener errors and a surviving class-prepare request. The corrected implementation passes all 37 focused tests, including the existing listener tests. Restoring only the upstream target implementation makes the new test fail at The matching unused-parameter correction has also been applied to the standalone #992 without changing its base. No tests, warning gates or product build timeouts have been removed or relaxed. Jenkins build 32 and full-history Maven verification were still running when this implementation update was prepared. A preceding shallow-checkout diagnostic attempt stopped at the unchanged macOS plugin's baseline comparison before executing tests; it is not counted as a successful full run. The focused results are not being presented as a completed green overall build. |
f971f9c to
cc798f3
Compare
Clean up owned VM and proxy processes when launch, attach or program startup fails, including when failed JUnit setup bypasses teardown. Preserve the original failure and interruption state, tolerate missing readers, and bound normal and forced process termination. Bound individual JDI attach attempts by the remaining connection budget so that a stalled JDWP handshake cannot prevent startup cleanup. Retain connection failures and process diagnostics before cleanup changes state. Add regression coverage for startup failures, process termination, repeated shutdown, unavailable process IDs and stalled JDWP handshakes. Use named invocation-handler parameters for the existing Java 21 source level; unnamed lambda parameters must not require preview features. TEMPORARY CI DIAGNOSTICS: Jenkins build 9 passed all 276 JDI tests, but the separate UI test runtime exited with code 143 after about 20 minutes. Preserve the complete Maven output and repeat the UI output and Eclipse error log at the end of a failed build so the GitHub check includes the relevant evidence instead of only the subsequent successful JDI output. Preserve Maven's exit status, arguments, timeouts and quality gates. Remove the diagnostic Jenkinsfile change before merging. The breakpoint cleanup implementation is reviewed separately in eclipse-jdt#990. Signed-off-by: Carsten Hammer <carsten.hammer@t-online.de>
Clean up owned VM and proxy processes when launch, attach or program startup fails, including when failed JUnit setup bypasses teardown. Preserve the original failure and interruption state, tolerate missing readers, and bound normal and forced process termination. Bound individual JDI attach attempts by the remaining connection budget so a stalled JDWP handshake cannot prevent startup cleanup. Retain the connection failure and process diagnostics before cleanup changes state. Follow review by keeping the existing JDI suite unchanged, omitting the added infrastructure tests and temporary Jenkins diagnostics, and removing the configurable process timeout entry point used only by those tests. Explain why the forced-exit wait keeps its deadline across interruptions. The breakpoint cleanup implementation is reviewed separately in eclipse-jdt#990. Signed-off-by: Carsten Hammer <carsten.hammer@t-online.de> Assisted-by: OpenAI ChatGPT
Clean up owned VM and proxy processes when launch, attach or program startup fails, including when failed JUnit setup bypasses teardown. Preserve the original failure and interruption state, tolerate missing readers, and bound normal and forced process termination. Bound individual JDI attach attempts by the remaining connection budget so a stalled JDWP handshake cannot prevent startup cleanup. Retain the connection failure and process diagnostics before cleanup changes state. Follow review by keeping the existing JDI suite unchanged, omitting the added infrastructure tests and temporary Jenkins diagnostics, and removing the configurable process timeout entry point used only by those tests. Explain why the forced-exit wait keeps its deadline across interruptions. The breakpoint cleanup implementation is reviewed separately in eclipse-jdt#990. Signed-off-by: Carsten Hammer <carsten.hammer@t-online.de> Assisted-by: OpenAI ChatGPT
Clean up owned VM and proxy processes when launch, attach or program startup fails, including when failed JUnit setup bypasses teardown. Preserve the original failure and interruption state, tolerate missing readers, and bound normal and forced process termination. Bound individual JDI attach attempts by the remaining connection budget so a stalled JDWP handshake cannot prevent startup cleanup. Retain the connection failure and process diagnostics before cleanup changes state. Follow review by keeping the existing JDI suite unchanged, omitting the added infrastructure tests and temporary Jenkins diagnostics, and removing the configurable process timeout entry point used only by those tests. Explain why the forced-exit wait keeps its deadline across interruptions. The breakpoint cleanup implementation is reviewed separately in #990. Signed-off-by: Carsten Hammer <carsten.hammer@t-online.de> Assisted-by: OpenAI ChatGPT
Remove tracked breakpoints by identity after their marker is deleted or detached. Guard installation-count updates with markerExists() and clear target and current-thread references even when request cleanup fails. Continue removing remaining JDI requests after a deregistration CoreException. Complete breakpoint-side filter and installation cleanup before reporting the first failure, preserving later cleanup errors as suppressed exceptions. Clear installed-target state independently of plugin notification and remove all matching instance filters. Retain the marker-deletion and detached-marker regression tests. Record removals by identity in the global test listener and reject unexpected error-log entries. Real-VM failure-path tests verify request deletion, state on both sides, removal and installation notifications, repeated removal, and reinstalling and hitting the very same breakpoint. Also verify that a change-notification failure cannot mask the original request-deregistration failure or skip the removal notification. Addresses eclipse-jdt#55 Signed-off-by: Carsten Hammer <carsten.hammer@t-online.de>
cc798f3 to
8bf2de8
Compare


What this fixes
A Java breakpoint can lose its workspace marker after it has been installed in a debug target. When the removal callback arrives, the target already knows which breakpoint it installed. Consulting marker-backed state again during removal can prevent cleanup and leave the breakpoint associated with the target or thread.
A second failure path occurs when deregistering one of several JDI requests throws a
CoreException. The remaining requests, filters, and installed-target state still need to be cleaned up. Otherwise, reinstalling the same breakpoint object can suppress its next installation notification.This addresses the marker-loss removal paths reported in #55. The issue also tracks other stale-breakpoint scenarios.
Implementation
markerExists()before updating installation counts for regular and class-prepare breakpoints.CoreException, attempt the remaining requests and clear the request collection. Preserve the first exception and attach subsequent failures as suppressed exceptions.GlobalBreakpointListenerso the tests can verify which breakpoint was removed.Review scope
This PR contains one breakpoint commit across seven files. The JDI test-harness changes were merged separately in #992.
The rebase onto
efe9d966preserves the original breakpoint patch, including all five regression tests. The stable Git patch IDs before and after the rebase are identical.Regression tests
BreakpointRemovalTestsis registered inorg.eclipse.jdt.debug.tests.AutomatedSuite. Its five cases exercise removal against a real debug target and VM.HitCountLooperat a line breakpoint, delete its workspace marker, and verify removal notification and target/thread cleanup. A replacement breakpoint at the same location must be hit. This case also passed on the previous production code and protects existing behavior.fireChanged()throw during removal. Verify that cleanup and removal notification still complete, that the change-notification failure is suppressed on the original exception, and that the same breakpoint can be installed and hit again.Verification
8bf2de8bBreakpoint retained its installed targetwith the previous production code. The other 36 tests passed.BreakpointListenerTestsandJavaBreakpointListenerTests. The full-reactor run and Jenkins build 33 also passed before the rebase.Author checklist
Assisted-by: OpenAI ChatGPT