Skip to content

fix(debugger): make completion markers unique per session - #137

Merged
svnscha merged 1 commit into
developfrom
fix/unique-markers
Oct 8, 2026
Merged

svnscha merged 1 commit into
developfrom
fix/unique-markers

Conversation

@svnscha

@svnscha svnscha commented Oct 8, 2026

Copy link
Copy Markdown
Owner

Addresses the marker-isolation half of #125, and supersedes #128.

The defect

Every session mints COMMAND_COMPLETED_MARKER_<n> from a counter that starts at 1, so all sessions use the same marker names. Several clients attached to one shared -remote debug server see each other's output, so another client's marker can complete the wrong command. The completion test was also a bare substring match, so _1 matched inside _10.

A random per-session nonce makes a foreign marker unrecognisable, and the match is now anchored at the end of the line.

Why it stays prompt-agnostic

Real cdb and kd write their prompt without a trailing newline, so the completion marker always arrives prefixed by it. Measured here on SDK 10.0.26100 against the committed dumps:

'0:000> COMMAND_COMPLETED_MARKER_1\n'      # cdb -z DemoCrash1.exe.7088.dmp
'8: kd> COMMAND_COMPLETED_MARKER_1\n'      # kd  -z KernelMiniDump.0xE2.dmp

The processor number varies, a remote client with no current process shows ?:???> , and a busy engine prefixes *BUSY* . So two approaches both break:

  • requiring the marker to stand alone on its line rejects every real marker;
  • parsing the prompt works until it meets a form it does not know, and then wedges that session type.

This takes neither. The existing rule that a line containing the marker base is ours and never the target's is what makes prompt knowledge unnecessary, and it is unchanged. Only the completion test moved from in to an end-anchored match, which also covers a marker glued onto a command's last output line.

The test fake was certifying the bug

_FakeProc emitted a bare marker, which no real debugger does. It now emits a prompt-prefixed one and accepts any of the real prompt forms, so a matcher that fails against a live debugger can no longer pass the suite.

Verification

uv run pytest src/mcp_windbg/tests/ -q   ->  198 passed, 2 skipped

Baseline before this change is 189 passed; the 9 added are the 8 real prompt forms plus nonce uniqueness across sessions. Live tests included, driving real cdb and kd.

Real-target acceptance, with the nonce in place:

cdb user-mode dump   opened in  0.22s   marker=COMMAND_COMPLETED_MARKER_c0f4e9be...
kd  kernel dump      opened in  0.23s   marker=COMMAND_COMPLETED_MARKER_466fa336...

Relationship to #128

#128 diagnosed this correctly and I have credited that in the commit trailer of the follow-up discussion on the issue. Its implementation required a standalone marker line, which rejects all of the real output above: measured, develop opens a dump in 0.2s where that branch times out after 15s on both cdb and kd. It also carried a 1036-line module split that the fix does not need. This is the four-line equivalent, so #128 will be closed with the measurement rather than merged.

Markers were `COMMAND_COMPLETED_MARKER_<n>` from a counter that restarts at 1
in every session. Several clients attached to one shared `-remote` debug server
see each other's output, so a marker from another client could complete the
wrong command, and `_1` also matched inside `_10`. A random per-session nonce
makes a foreign marker unrecognisable, and the completion test is now anchored
at the end of the line rather than being a bare substring match.

Deliberately still prompt-agnostic. Real cdb and kd write their prompt without
a trailing newline, so the marker always arrives prefixed by it (`0:000> ...`,
`8: kd> ...`, and `?:???> ...` on a remote target with no process yet). Any
matcher that requires the marker to stand alone, or that parses the prompt and
then meets a form it does not know, wedges every session of that kind. The
rule that a line containing the marker base is ours and never the target's is
what makes prompt knowledge unnecessary, and it stays as it was.

The test fake emitted a bare marker, which no real debugger does. It now emits
a prompt-prefixed one and can be given any of the real prompt forms, so the
suite can no longer pass while the protocol is broken against a live debugger.
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.

1 participant