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

Created on 24 Oct 2018  路  11Comments  路  Source: PowerShell/PowerShell

Steps to reproduce

Set-PSDebug -Trace 1

Write-Output "foo `
bar"

Expected behavior

Something like:

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

foo
bar

Actual behavior

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

foo
bar

Environment data

> $PSVersionTable
Name                           Value
----                           -----
PSVersion                      6.2.0-preview.1
PSEdition                      Core
GitCommitId                    6.2.0-preview.1
OS                             Microsoft Windows 10.0.17134
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Hacktoberfest Up-for-Grabs WG-Interactive-Debugging

Most helpful comment

@iSazonov thanks for pointing that out! We should focus on when a single logical line is multiple physical lines and not the general multi line case

All 11 comments

@the-ress Can you repo without PSReadline loaded?

It repros without PSReadLine. Seems like it should be outputting the logical line and not the physical line

The problem is here. Basically it only traces the line at the start of the extent.

I'd be interested in picking this issue up if it's still available. Based on @SteveL-MSFT 's previous comment, it looks like the BriefMessage method of PositionUtilities needs to be multi-line aware. Does that sound about right?

@dwalleck yes, seems correct. Consider it yours!

It will take some smarts to provide a better experience. Most statements have multiple lines, e.g. an if statement. If you make a change, compare the output to the following and decide if it's an improvement or not.

PS> dir $env:TEMP | ForEach-Object {
>>     if ((Get-Random -Maximum 15) -lt 1) {
>>         "Lucky file is $_"
>>         break
>>     }
>> }
DEBUG:    1+  >>>> dir $env:TEMP | ForEach-Object {
DEBUG:     ! CALL function '<ScriptBlock>'
DEBUG:    1+ dir $env:TEMP | ForEach-Object  >>>> {
DEBUG:     ! CALL function '<ScriptBlock>'
DEBUG:    2+     if ( >>>> (Get-Random -Maximum 15) -lt 1) {
DEBUG:    6+  >>>> }
DEBUG:    1+ dir $env:TEMP | ForEach-Object  >>>> {
DEBUG:     ! CALL function '<ScriptBlock>'
DEBUG:    2+     if ( >>>> (Get-Random -Maximum 15) -lt 1) {
DEBUG:    6+  >>>> }
DEBUG:    1+ dir $env:TEMP | ForEach-Object  >>>> {
DEBUG:     ! CALL function '<ScriptBlock>'
DEBUG:    2+     if ( >>>> (Get-Random -Maximum 15) -lt 1) {
DEBUG:    6+  >>>> }
DEBUG:    1+ dir $env:TEMP | ForEach-Object  >>>> {
DEBUG:     ! CALL function '<ScriptBlock>'
DEBUG:    2+     if ( >>>> (Get-Random -Maximum 15) -lt 1) {
DEBUG:    6+  >>>> }
DEBUG:    1+ dir $env:TEMP | ForEach-Object  >>>> {
DEBUG:     ! CALL function '<ScriptBlock>'
DEBUG:    2+     if ( >>>> (Get-Random -Maximum 15) -lt 1) {
DEBUG:    6+  >>>> }
DEBUG:    1+ dir $env:TEMP | ForEach-Object  >>>> {
DEBUG:     ! CALL function '<ScriptBlock>'
DEBUG:    2+     if ( >>>> (Get-Random -Maximum 15) -lt 1) {
DEBUG:    6+  >>>> }
DEBUG:    1+ dir $env:TEMP | ForEach-Object  >>>> {
DEBUG:     ! CALL function '<ScriptBlock>'
DEBUG:    2+     if ( >>>> (Get-Random -Maximum 15) -lt 1) {
DEBUG:    6+  >>>> }
DEBUG:    1+ dir $env:TEMP | ForEach-Object  >>>> {
DEBUG:     ! CALL function '<ScriptBlock>'
DEBUG:    2+     if ( >>>> (Get-Random -Maximum 15) -lt 1) {
DEBUG:    6+  >>>> }
DEBUG:    1+ dir $env:TEMP | ForEach-Object  >>>> {
DEBUG:     ! CALL function '<ScriptBlock>'
DEBUG:    2+     if ( >>>> (Get-Random -Maximum 15) -lt 1) {
DEBUG:    3+          >>>> "Lucky file is $_"
Lucky file is wct721E.tmp
DEBUG:    4+          >>>> break

Based on @lzybkr's feedback on the PR, it seems that we should conclude on what we think is the optimal expected output for multiline. I would also suggest that it should be enabled via a parameter on Set-PSDebug rather than changing existing default behavior as some people may prefer the existing single line.

I should point that the original repo sample is about multiline with _backtick_.

The actual code I was debugging looked like this: (Note the extra backtick on line 3.)

msbuild /m /restore MyApp.sln `
    /p:Configuration="$Configuration" `
    /p:Platform="$Platform" `
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }

Seeing only the first line of the command wasn't really helpful.

@iSazonov thanks for pointing that out! We should focus on when a single logical line is multiple physical lines and not the general multi line case

We should be able to simply check if the line referenced ends with a backtick, and if it does, grab the next line as well, loop until we find a line that doesn't end in a backtick.

Was this page helpful?
0 / 5 - 0 ratings