Skip to content

Rust/Windows: pause_execution reports stopReason 'exception' (0x80000003 break-in) instead of 'pause' #275

Description

@debugmcpdev

Context

Found during the post-#272/#273/#274 /testdebugger sweep (2026-08-06, Windows, CodeLLDB 1.11.8, GNU-toolchain binaries). Reproduced identically on 4 server variants (local HTTP/SSE/stdio, NPX-tarball HTTP), both on the first pause and after a continue→re-pause cycle.

Problem

On Windows, pause_execution against a running Rust debuggee succeeds, but the resulting stop reports stopReason: 'exception' with description Exception 0x80000003 and the stopped thread parked in the injected break-in frames (DbgUiRemoteBreakinDbgBreakPoint). Callers that check lastStop.reason === 'pause' (the documented contract for a user-initiated pause) see an exception instead. get_local_variables on the synthetic break-in frame also returns an empty array (the user's threads are listed and inspectable via list_threads/frame selection — this part is inherent to the break-in mechanism).

This is the Windows analog of the SIGSTOP case already handled by RustAdapterPolicy.normalizeStopReason (which maps CodeLLDB's SIGSTOP-delivered pause, reported as 'exception', back to 'pause' on POSIX). Windows delivers the pause via DebugBreakProcess → breakpoint exception 0x80000003, which the current normalizer leaves untouched because the detail text is non-empty and doesn't match /SIGSTOP/i.

Suggested fix

Extend the existing reason === 'exception' branch in packages/shared/src/interfaces/adapter-policy-rust.ts: when context.pausePending is true and the detail matches the Windows break-in signature (0x80000003 / EXCEPTION_BREAKPOINT / DbgBreakPoint), normalize to 'pause'. Keep it gated on pausePending so a genuine __debugbreak()/int3 in user code that fires while no pause is in flight stays an exception stop. Unit cases mirror the SIGSTOP suite in packages/shared/tests/unit/adapter-policy-rust.test.ts:67+.

Evidence

  • P3/P8 of the pause workflow on all 4 tested variants: stop body Exception 0x80000003, top frame @DbgBreakPoint, thread DbgUiRemoteBreakin.
  • POSIX path already normalizes (SIGSTOP → 'pause'), so this is a Windows-only contract gap.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions