fix(#465): java attach actually pauses the JVM; get_stack_trace gains threadId - #483
Merged
Conversation
… threadId
Root cause: attach defaults to the PAUSED branch (stopOnEntry !== false),
but the JDI bridge never suspends the VM on attach and java's policy had
no pauseAfterAttach — so the session reported paused while the JVM kept
running, every thread refused stackTrace ("not suspended"), and the
session was uninspectable except via an undocumented continue -> pause.
- JavaAdapterPolicy declares pauseAfterAttach + new pauseAllThreads: the
post-attach pause is sent with threadId 0, the bridge suspends the
whole VM and anchors its stopped event to a thread that can actually
report frames (its pickReportableThread hardening from #352).
- get_stack_trace now accepts threadId (ids from list_threads); when the
chosen thread reports frames it becomes the anchor for follow-up
scopes/locals/evaluate — the note's escape hatch now exists.
- The frameless-thread note names the real recovery (threadId or
continue+pause) instead of pointing at a tool that couldn't help, and
get_local_variables no longer claims "the debugger may not be paused"
when the session is paused with a frameless anchor.
Verified live against the issue repro (java -agentlib:jdwp ... suspend=n,
attach): get_stack_trace returns PauseTest.main and get_local_variables
returns the counter on the first try, and threadId targeting works.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #465.
Root cause
Not a frameless-thread anchor after all: the JDI bridge never suspends the VM on attach (its attach handler only suspends for
stopOnEntryin the DAP args, which the transform doesn't send), and java's policy lackedpauseAfterAttach— the only mainstream policy without it. So the session reportedpausedwhile the JVM kept running, and every thread refusedstackTrace("not suspended") — which is why the existing frameless-thread scan found nothing anywhere, and whycontinue→pause(a realvm.suspend()) fixed it.Fix (issue asks 1–4)
JavaAdapterPolicy.getAttachBehavior→pauseAfterAttach: true, pauseAllThreads: true(new knob): the post-attach pause is sent withthreadId 0, so the bridge suspends the whole VM and anchors its stopped event via its ownpickReportableThreadhardening ([BUG] Java attach pause_execution doesn't actually suspend the target #352) — a thread that can actually report frames.get_stack_traceacceptsthreadId(ids fromlist_threads); when that thread reports frames it is adopted as the anchor for follow-up scopes/locals/evaluate. The escape hatch the old note pointed at now exists. (No silent re-anchor scan on explicit requests — an empty answer for the asked-about thread stays honest.)threadIdtargeting orcontinue_execution+pause_execution— instead of advice that couldn't be followed.get_local_variablesno longer contradicts session state: paused-with-frameless-anchor now says exactly that, with the same recovery pointers.Verification
java -agentlib:jdwp=...,suspend=n,attach_to_process):get_stack_tracereturnsPauseTest.mainandget_local_variablesreturnscounteron the first try (previously: empty frames, unactionable note, "may not be paused").threadId: 1targeting verified too.threadId: 0) post-attach; policy pin for the attach behavior; the policies-without-behavior pin moved from java to go (java joining was the point).Note: the issue's C/C++ observation (pause anchoring to an arbitrary thread, e.g. LLDB's injected
DbgBreakPointthread) now has a complete discoverable path:list_threads→get_stack_trace {threadId}→ locals anchored there. Composes with #482's frame walk-down.🤖 Generated with Claude Code