Skip to content

fix(attach): generous verify window + paused-stack readiness (load-flaky attach e2e) - #398

Merged
debugmcpdev merged 1 commit into
mainfrom
fix/attach-verify-and-paused-stack-hardening
Aug 21, 2026
Merged

fix(attach): generous verify window + paused-stack readiness (load-flaky attach e2e)#398
debugmcpdev merged 1 commit into
mainfrom
fix/attach-verify-and-paused-stack-hardening

Conversation

@debugmcpdev

Copy link
Copy Markdown
Collaborator

Context

Two attach-mode e2e tests failed in a full-suite run while passing in isolation — the parallel unit project runs alongside the serial e2e project, so e2e tests execute under heavy CPU load:

  1. mcp-server-smoke-js-function-bp.test.ts (attach mode)attach_to_process failed with "Attach did not become debuggable: no threads reported within 5000ms". For js-debug, threads is child-routed; until the child session is adopted the parent reports zero threads, and under load adoption exceeds the 5s default verify window. The adapter was healthy — the deadline hard-failed a good attach.
  2. mcp-server-smoke-dotnet-attach.test.ts — after the post-attach pause ([BUG] .NET attach: pause_execution doesn't suspend, and breakpoints refuse to bind despite a valid Portable PDB #353 fix), get_stack_trace issued 7ms after the stopped event got a successful DAP response with 0 frames from netcoredbg. A passing run shows identical timing with 2 frames, so this is netcoredbg's post-pause sync window (the milder sibling of [BUG] .NET attach: pause_execution doesn't suspend, and breakpoints refuse to bind despite a valid Portable PDB #353's 0x80131302), and/or the attach-discovered threads[0] being a frameless runtime thread.

Both are general contract gaps, so the fixes are implementation hardening — the e2e tests keep their strict semantics as the spec (only assertion diagnostics were added).

Changes

Attach verify window default 5s → 20s (attachVerifyTimeoutMs)

  • Adapter death still fails fast via the existing proxy-gone latch, and the thread poll exits the moment threads appear — so the deadline only ever bites when the adapter is alive but the target is slow to become debuggable, where a false "attach failed" is strictly worse for an agent than a slower genuine failure.
  • The verifyTimeout knob is unchanged (validated, clamped to 10 min); the failure-by-design attach probe in comprehensive-mcp-tools.test.ts now passes verifyTimeout: 2000 to stay fast. Tool descriptions, docs, and skill references updated.

Paused ⇒ usable stack on the agent-facing get_stack_trace path (ensureStackReady)

  • When a PAUSED session answers stackTrace with success + zero frames: bounded retry (~3s, 250ms interval, exits on first frame, aborts if the session leaves PAUSED), then a fallback scan of the other stopped threads — the first frame-bearing thread is adopted via setCurrentThreadId (so scopes/evaluate anchor correctly) and the response carries a note naming the switch.
  • If everything stays frameless, the honest empty result is returned with a note telling the agent what to try (list_threads, retry). The not-paused and no-known-thread empty results now carry explanatory notes too.
  • Error semantics unchanged: DAP success: false still throws (JavaScript attach mode: attach_to_process reports success + 'paused' but js-debug child session never connects to the target #124), missing stackFrames still throws. Internal callers keep the single-shot behavior — only the MCP tool path (which resolves the thread implicitly) opts in.

Verification

  • 6 new unit tests (retry-until-frames, thread-scan + adopt + annotate, honest-empty note, unchanged internal behavior, mid-retry abort, not-paused note), written failing-first.
  • Full npm test (unit + integration + e2e, 260 files / 3934 tests) green — the exact configuration that produced the original failures, with both previously failing tests passing under load.
  • comprehensive-mcp-tools attach-failure probe confirmed fast (~0.9s).

Follow-ups filed

🤖 Generated with Claude Code

…aky attach e2e)

Two attach-mode e2e tests failed under full-suite CPU load (parallel unit
project alongside the serial e2e project) while passing in isolation. Both
root causes were general contract gaps, fixed in the implementation rather
than by conforming the tests:

- attachVerifyTimeoutMs default 5s -> 20s. The verify deadline only ever
  bites when the adapter is alive but the target is slow to report threads
  (js-debug child adoption on a loaded host, warming JVM) - adapter death
  still fails fast via the proxyGone latch, and the poll exits as soon as
  threads appear. A false "attach failed" on a healthy target is strictly
  worse for an agent than a slower genuine failure. verifyTimeout knob
  unchanged; the failure-by-design probe in comprehensive-mcp-tools now
  passes a small verifyTimeout explicitly.

- Paused => usable stack on the agent-facing get_stack_trace path
  (ensureStackReady): an empty-but-successful stackTrace while PAUSED is
  nearly always a transient race (netcoredbg materializes the managed stack
  a beat after the post-attach pause stop - the milder sibling of #353's
  0x80131302) or a frameless runtime thread tracked as current. Bounded
  retry (~3s, exits on first frame), fallback scan of the other stopped
  threads (adopts the frame-bearing one so scopes/evaluate anchor to it),
  honest empty + explanatory note as last resort. Not-paused and
  no-known-thread empty results now carry a note too. Internal callers
  keep the single-shot behavior.

The two e2e tests keep their strict semantics (assertion diagnostics only).
Follow-ups filed: #396 (threads response clobbers currentThreadId), #397
(tool:response logs success:true for failed attach).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Aug 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.34146% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/session/session-manager-data.ts 97.26% 2 Missing ⚠️
src/server.ts 87.50% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@debugmcpdev
debugmcpdev merged commit 5d5e408 into main Aug 21, 2026
10 checks passed
@debugmcpdev
debugmcpdev deleted the fix/attach-verify-and-paused-stack-hardening branch August 21, 2026 21: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.

2 participants