Skip to content

Conversation

@yotsuda
Copy link
Contributor

@yotsuda yotsuda commented Nov 27, 2025

PR Summary

Fix Set-PSDebug -Trace to display all lines of multiline commands.

PR Context

Fixes #8113

When using Set-PSDebug -Trace 1 or -Trace 2, multiline commands (e.g., using backtick line continuation) only showed the first line in debug output. This made it difficult to trace and debug scripts with multiline commands.

Before this fix:

Set-PSDebug -Trace 1

Write-Output "foo `
bar"

Output:

DEBUG:    3+  >>>> Write-Output "foo `

foo
bar

After this fix:

Output:

DEBUG:    3+  >>>> Write-Output "foo `
DEBUG:    4+  >>>> bar"
foo
bar

PR Checklist

Description

Root Cause

The TraceLine method in the debugger was calling PositionUtilities.BriefMessage(extent.StartScriptPosition), which only considers the start position of an extent. For multiline commands, this meant only the first line was displayed.

Solution

  1. Added a new overload PositionUtilities.BriefMessage(IScriptExtent extent) that handles multiline extents by:

    • Detecting if an extent spans multiple lines
    • For single-line extents, delegating to the existing method
    • For multiline extents, formatting each line with appropriate line numbers and markers
  2. Changed TraceLine to call the new extent-based overload and write each line separately so each gets the DEBUG: prefix.

Files Changed

  • src/System.Management.Automation/engine/debugger/debugger.cs - Changed TraceLine to use extent-based BriefMessage and write each line separately
  • src/System.Management.Automation/engine/parser/Position.cs - Added new BriefMessage(IScriptExtent) overload
  • test/powershell/Modules/Microsoft.PowerShell.Core/Set-PSDebug.Tests.ps1 - Added tests for multiline command tracing with -Trace 1 and -Trace 2

Testing

Test Coverage

Added test cases that:

  1. Create a script with a multiline command using backtick line continuation
  2. Run it in a separate process to capture trace output
  3. Verify both the first line (Write-Output) and continuation line (bar") appear in debug output with DEBUG: prefix

Tests cover both -Trace 1 and -Trace 2 options.

Automated Tests

All tests pass:

Context Tracing can be used
  [+] Should be able to go through the tracing options
  [+] Should be able to set strict
  [+] Should skip magic extents created by pwsh
  [+] Should trace all lines of a multiline command
  [+] Should trace all lines of a multiline command with -Trace 2

Tests Passed: 5, Failed: 0

@microsoft-github-policy-service microsoft-github-policy-service bot added the Review - Needed The PR is being reviewed label Dec 4, 2025
@iSazonov iSazonov added the CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log label Dec 5, 2025

ui.WriteDebugLine(msg, ref pref);
// Write each line separately so each gets the DEBUG: prefix
string[] lines = msg.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we split at "\r" here as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for catching this! Updated to include "\r" for consistency with the existing pattern used elsewhere in the same file (line 5316).

string[] lines = msg.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);

Commit: feecda0

@yotsuda yotsuda requested a review from a team as a code owner January 14, 2026 02:06

ui.WriteDebugLine(msg, ref pref);
// Write each line separately so each gets the DEBUG: prefix
string[] lines = msg.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can BriefMessage() return string[]?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestion! I've updated BriefMessage(IScriptExtent) to return string[] directly instead of building a single concatenated string.

Commit: 71d46a1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log Review - Needed The PR is being reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Set-PSDebug -Trace 1 prints only first line of a multiline command

3 participants