Commit d8acc17
authored
fix: read command output from a UTF-16 log on multibyte code pages
Fixes #102.
## Problem
On Windows whose **system code page is multibyte** (Chinese 936,
Japanese 932, Korean 949, or the "Use Unicode UTF-8" setting 65001), the
debugger truncates its text output over a pipe: each line is written
short by its multibyte expansion, dropping the tail (and newline) of any
line that contains non-ASCII text. This lost the end of `du` strings and
other Unicode output, and a line cut in the middle of a character left
the session unresponsive to every later command.
Reproduced on a Windows 11 VM. It affects **every command that prints
Unicode**, not just `du`, and no pipe output mode avoids it:
interactive, `-c` batch, and `.logopen` to an ANSI file all truncate,
because the miscount is in the debugger's writer.
## Fix (transport level, not per-command)
`.logopen /u` writes a **UTF-16 log** that is complete and flushes per
command. On a multibyte code page the session opens such a log at
startup and reads each command's output from it, keyed by the same
`.echo` markers the pipe already uses to synchronize.
- **The pipe stays the control channel** for markers, timeouts,
go-commands and break-in; only the returned command output comes from
the log. All the existing sync logic is untouched.
- **Only for sessions whose engine is local** - a crash dump and a
kernel target on the wire, where the debugger is our own subprocess and
the log opens on this machine. A user-mode `-remote` client drives the
engine on the server, so it keeps the pipe (see Limitations).
- **Single-byte code pages** (Western 1252 and the like), where the pipe
is lossless, are detected with `GetCPInfo` and keep the pipe path,
byte-for-byte unchanged.
- **Prompt scaffolding stripped** from the log transcript: the bare
`0:000>`, kernel `0: kd>` / local `lkd>`, WOW64 `1:001:x86>`, and remote
`[server (tcp ...)] 0:000>` forms.
- **Reader hardened**: the pipe is decoded with the debugger's own ANSI
code page and `errors="replace"`, so a split multibyte sequence can no
longer raise in the reader thread on the paths that still read the pipe.
- **Cleaned up**: the temporary log is deleted on session shutdown (with
a short retry, since a force-killed debugger may still be releasing the
handle).
## Research: can the pipe itself be UTF-16?
Checked before going the log route. A Windows pipe is a raw byte stream;
the writer picks the encoding, and cdb/kd convert their internal Unicode
to the ANSI code page (the truncating `WriteFile` path) whenever stdout
is a redirected handle. There is no cdb.exe switch to emit UTF-16/UTF-8
to the pipe. The only native Unicode sinks the engine offers are the
wide output callback `IDebugOutputCallbacksWide` (which would mean
hosting `dbgeng.dll` ourselves, a full re-architecture) and the Unicode
log (`.logopen /u`, or the command-line `-logou`/`-logau`). A
pseudo-console (ConPTY) would make cdb call `WriteConsoleW`, but its
output arrives wrapped in VT escape sequences and hard-wrapped at the
console width, which is worse to parse than the log. The log is the
supported, clean mechanism.
## Verification
Reproduced at the 1.2.1 release commit and verified with this branch on
a Windows 11 VM, stock SDK cdb/kd 10.0.26100.1742:
| System code page | before | this branch |
| :-- | :-- | :-- |
| 1252 (Western) | works | passthrough, byte-for-byte unchanged |
| 936 (Chinese) | empty / truncated / wedged | full Unicode for every
command |
| 65001 (UTF-8) | empty / truncated / wedged | full Unicode for every
command |
`du`, `dw`, `db`, `.echo`, `version` and the rest return complete text;
the temp log leaves nothing behind. Full suite: 106 passed on the 1252
host and 111 on the VM under both 936 and 65001; the hermetic tests
drive the log path on any platform (a fake debugger mirrors a UTF-16
log) and are pinned to the single-byte path by default so they behave
the same regardless of the host's real code page.
- **Crash dump:** full CJK strings recovered for `du`/`du <addr> L<n>`
under 936 and 65001.
- **Kernel (kd.exe):** verified against a live kernel via local kernel
debugging on the UTF-8 VM - the log transport engages, and `version`,
`lm m nt` and a live kernel-memory read return complete output with the
`lkd>` prompt stripped and the temp log cleaned up.
- **Remote process debugging (`-remote`):** end-to-end against a real
`.server` host - attach, process (`|`), threads (`~`), modules (`lm`)
and registers all work. The log stays off (engine is on the server), so
this is unchanged from before.
## Limitations
- A `-remote` **client on a multibyte code page** still truncates
Unicode output: the engine runs on the server, so its Unicode log is not
on our machine (and for a cross-machine server would not be reachable at
all). Remote debugging otherwise works; this is unchanged from before
the fix.
- A **live target's asynchronous output** (a go/break-in bugcheck
banner) still comes from the pipe, so a bugcheck message containing
non-ASCII text could still truncate. Ordinary command output, which is
what #102 is about, is fully covered.1 parent d3d1fd0 commit d8acc17
5 files changed
Lines changed: 348 additions & 1 deletion
File tree
- src/mcp_windbg
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
8 | 14 | | |
9 | 15 | | |
10 | 16 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
83 | 83 | | |
84 | 84 | | |
85 | 85 | | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
86 | 90 | | |
87 | 91 | | |
88 | 92 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| 31 | + | |
31 | 32 | | |
32 | 33 | | |
33 | 34 | | |
34 | 35 | | |
| 36 | + | |
35 | 37 | | |
| 38 | + | |
36 | 39 | | |
37 | 40 | | |
38 | 41 | | |
| |||
132 | 135 | | |
133 | 136 | | |
134 | 137 | | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
135 | 201 | | |
136 | 202 | | |
137 | 203 | | |
| |||
145 | 211 | | |
146 | 212 | | |
147 | 213 | | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
148 | 220 | | |
149 | 221 | | |
150 | 222 | | |
| |||
185 | 257 | | |
186 | 258 | | |
187 | 259 | | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
188 | 266 | | |
189 | 267 | | |
190 | 268 | | |
191 | 269 | | |
192 | 270 | | |
193 | 271 | | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
194 | 278 | | |
195 | 279 | | |
196 | 280 | | |
197 | 281 | | |
| 282 | + | |
198 | 283 | | |
199 | 284 | | |
200 | 285 | | |
| |||
438 | 523 | | |
439 | 524 | | |
440 | 525 | | |
441 | | - | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
| 542 | + | |
| 543 | + | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
442 | 614 | | |
443 | 615 | | |
444 | 616 | | |
| |||
710 | 882 | | |
711 | 883 | | |
712 | 884 | | |
| 885 | + | |
713 | 886 | | |
714 | 887 | | |
715 | 888 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
| |||
88 | 89 | | |
89 | 90 | | |
90 | 91 | | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
91 | 96 | | |
92 | 97 | | |
93 | 98 | | |
| |||
96 | 101 | | |
97 | 102 | | |
98 | 103 | | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
99 | 114 | | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
100 | 118 | | |
101 | 119 | | |
102 | 120 | | |
| |||
105 | 123 | | |
106 | 124 | | |
107 | 125 | | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
108 | 130 | | |
109 | 131 | | |
110 | 132 | | |
| |||
113 | 135 | | |
114 | 136 | | |
115 | 137 | | |
| 138 | + | |
| 139 | + | |
116 | 140 | | |
117 | 141 | | |
118 | 142 | | |
| |||
158 | 182 | | |
159 | 183 | | |
160 | 184 | | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
161 | 194 | | |
162 | 195 | | |
163 | 196 | | |
| |||
599 | 632 | | |
600 | 633 | | |
601 | 634 | | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
| 682 | + | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
0 commit comments