Skip to content

[CollectLinux] Fix no-tty crash with console capability aware ProgressWriter#5771

Open
mdh1418 wants to merge 2 commits intodotnet:mainfrom
mdh1418:fix/collect-linux-cursor-position-crash
Open

[CollectLinux] Fix no-tty crash with console capability aware ProgressWriter#5771
mdh1418 wants to merge 2 commits intodotnet:mainfrom
mdh1418:fix/collect-linux-cursor-position-crash

Conversation

@mdh1418
Copy link
Copy Markdown
Member

@mdh1418 mdh1418 commented Mar 19, 2026

When CursorTop is 0 (e.g., in environments where cursor positioning isn't available), LineToClear was set to -1, causing SetCursorPosition to throw ArgumentOutOfRangeException on progress callbacks.

Extract the progress display concern from OutputHandler into a nested ProgressWriter class that:

  • Probes console capability on first Update() call
  • Interactive: rewrites status line in-place with 1s throttle
  • Non-interactive: prints a static message once, silently no-ops after
  • Owns LineRewriter and LineToClear internally

OutputHandler's status block reduces to progressWriter.Update(), fully decoupling it from LineRewriter. Matches CollectCommand's pattern of probing capability upfront and gating on it.

Also adds bounds validation to MockConsole.SetCursorPosition and a regression test for the CursorTop=0 case.

…riter

When CursorTop is 0 (e.g., in environments where cursor positioning
isn't available), LineToClear was set to -1, causing SetCursorPosition
to throw ArgumentOutOfRangeException on progress callbacks.

Extract the progress display concern from OutputHandler into a nested
ProgressWriter class that:
- Probes console capability once at construction
- Interactive: rewrites status line in-place with 1s throttle
- Non-interactive: prints a static message once, silently no-ops after
- Owns LineRewriter and LineToClear internally

OutputHandler's status block reduces to progressWriter.Update(), fully
decoupling it from LineRewriter. Matches CollectCommand's pattern of
probing capability upfront and gating on it.

Also adds bounds validation to MockConsole.SetCursorPosition and two
regression tests for the CursorTop=0 case.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mdh1418 mdh1418 requested a review from a team as a code owner March 19, 2026 16:34
Copilot AI review requested due to automatic review settings March 19, 2026 16:34
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a crash in dotnet-trace collect-linux progress callbacks in environments where console cursor positioning isn’t available (or behaves unexpectedly), by centralizing progress output behavior behind a capability-aware writer.

Changes:

  • Refactors progress/status rendering in CollectLinuxCommand into a nested ProgressWriter that gates rewrites and throttles updates.
  • Adds functional regression tests intended to cover CursorTop == 0 / unsupported cursor repositioning scenarios.
  • Tightens MockConsole.SetCursorPosition by adding row bounds validation.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
src/Tools/dotnet-trace/CommandLine/Commands/CollectLinuxCommand.cs Introduces ProgressWriter to manage progress output and console rewrite capability checks.
src/tests/dotnet-trace/CollectLinuxCommandFunctionalTests.cs Adds regression tests for cursor-top/cursor-repositioning edge cases.
src/tests/Common/MockConsole.cs Adds bounds checking to better surface invalid cursor positioning in tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

noahfalk
noahfalk previously approved these changes Mar 19, 2026
- Make LineRewriter._isSetCursorPositionSupported instance-scoped so each
  LineRewriter probes independently with its own LineToClear value
- Guard lineToClear < 0 in ProgressWriter.Initialize before constructing
  LineRewriter, avoiding probing with an invalid row
- Add Thread.Sleep(1100) between callbacks in regression tests to exceed
  the 1-second throttle, ensuring RewriteConsoleLine is actually invoked
  (verified: test fails without the lineToClear guard)
- Standardize Ctrl-C to Ctrl+C across status messages and test data
- Add column bounds validation to MockConsole.SetCursorPosition

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

3 participants