Skip to content

fix(#465): java attach actually pauses the JVM; get_stack_trace gains threadId - #483

Merged
debugmcpdev merged 3 commits into
mainfrom
fix/465-attach-thread-anchor
Aug 25, 2026
Merged

fix(#465): java attach actually pauses the JVM; get_stack_trace gains threadId#483
debugmcpdev merged 3 commits into
mainfrom
fix/465-attach-thread-anchor

Conversation

@debugmcpdev

Copy link
Copy Markdown
Collaborator

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 stopOnEntry in the DAP args, which the transform doesn't send), and java's policy lacked pauseAfterAttach — the only mainstream policy without it. So the session reported paused while the JVM kept running, and every thread refused stackTrace ("not suspended") — which is why the existing frameless-thread scan found nothing anywhere, and why continuepause (a real vm.suspend()) fixed it.

Fix (issue asks 1–4)

  1. JavaAdapterPolicy.getAttachBehaviorpauseAfterAttach: true, pauseAllThreads: true (new knob): the post-attach pause is sent with threadId 0, so the bridge suspends the whole VM and anchors its stopped event via its own pickReportableThread hardening ([BUG] Java attach pause_execution doesn't actually suspend the target #352) — a thread that can actually report frames.
  2. get_stack_trace accepts threadId (ids from list_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.)
  3. The note names the real recoverythreadId targeting or continue_execution + pause_execution — instead of advice that couldn't be followed.
  4. get_local_variables no longer contradicts session state: paused-with-frameless-anchor now says exactly that, with the same recovery pointers.

Verification

  • Live repro (java -agentlib:jdwp=...,suspend=n, attach_to_process): get_stack_trace returns PauseTest.main and get_local_variables returns counter on the first try (previously: empty frames, unactionable note, "may not be paused"). threadId: 1 targeting verified too.
  • New unit tests: java sends pause-all (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).
  • Full unit suites: 3207 passed.

Note: the issue's C/C++ observation (pause anchoring to an arbitrary thread, e.g. LLDB's injected DbgBreakPoint thread) now has a complete discoverable path: list_threadsget_stack_trace {threadId} → locals anchored there. Composes with #482's frame walk-down.

🤖 Generated with Claude Code

… 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

codecov Bot commented Aug 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 68.75000% with 5 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/server.ts 58.33% 5 Missing ⚠️

📢 Thoughts on this report? Let us know!

@debugmcpdev
debugmcpdev merged commit 1828e8f into main Aug 25, 2026
9 of 10 checks passed
@debugmcpdev
debugmcpdev deleted the fix/465-attach-thread-anchor branch August 25, 2026 15:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Java attach anchors to a frameless thread — session reports paused but is uninspectable, and the suggested recovery isn't possible with existing tools

2 participants