Skip to content

Conversation

@daxian-dbw
Copy link
Member

@daxian-dbw daxian-dbw commented Jul 18, 2018

PR Summary

Fix #7150

  • Make switch-statement report correct error position when it fails to evaluate the condition.
  • Make for-statement report correct error position when it fails to evaluate the initializer.

Before:

PS> $test = 1; switch ($null[0]) { default {} }
Cannot index into a null array.
At line:1 char:1
+ $test = 1; switch ($null[0]) { default {} }
+ ~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray

PS> $test = 1; for ($null[0];;) {}
Cannot index into a null array.
At line:1 char:1
+ $test = 1; for ($null[0];;) {}
+ ~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray

After:

PS> $test = 1; switch ($null[0]) { default {} }
Cannot index into a null array.
At line:1 char:20
+ $test = 1; switch ($null[0]) { default {} }
+                    ~~~~~~~~
+ CategoryInfo          : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray

PS> $test = 1; for ($null[0];;) {}
Cannot index into a null array.
At line:1 char:17
+ $test = 1; for ($null[0];;) {}
+                 ~~~~~~~~
+ CategoryInfo          : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray

Break point check

For switch-statement condition, retain the same behavior as is:

Script Content

PS> cat .\about2.ps1
$Test = 1..2
switch ($Test)
{
    default {'a'}
}
PS> .\about2.ps1
Entering debug mode. Use h or ? for help.

Hit Line breakpoint on 'F:\tmp\about2.ps1:1'

At F:\tmp\about2.ps1:1 char:1
+ $Test = 1..2
+ ~~~~~~~~~~~~
PS>> v
At F:\tmp\about2.ps1:2 char:9
+ switch ($Test)
+         ~~~~~
PS>> v
At F:\tmp\about2.ps1:4 char:14
+     default {'a'}
+              ~~~
PS>> v
a
At F:\tmp\about2.ps1:2 char:9
+ switch ($Test)
+         ~~~~~
PS>> v
At F:\tmp\about2.ps1:4 char:14
+     default {'a'}
+              ~~~
PS>> v
a
At F:\tmp\about2.ps1:2 char:9
+ switch ($Test)
+         ~~~~~
PS>> v

For for-statement initializer, fix the incorrect breaking point position when the initializer is a simple command expression:

Script Content

PS> cat .\about2.ps1
$i = 1
for ('str'.Length;
     $i -gt 0; $i--)
{
    "v"
}

Before:

PS> .\about2.ps1
Hit Line breakpoint on 'F:\tmp\about2.ps1:1'

At F:\tmp\about2.ps1:1 char:1
+ $i = 1
+ ~~~~~~
PS>> v
At F:\tmp\about2.ps1:3 char:6
+      $i -gt 0; $i--)
+      ~~~~~~~~
PS>> v
At F:\tmp\about2.ps1:5 char:5
+     "v"
+     ~~~
PS>> v
v
At F:\tmp\about2.ps1:3 char:16
+      $i -gt 0; $i--)
+                ~~~~
PS:40>> v
At F:\tmp\about2.ps1:3 char:6
+      $i -gt 0; $i--)
+      ~~~~~~~~
PS>> v

After:

PS> .\about2.ps1
Hit Line breakpoint on 'F:\tmp\about2.ps1:1'

At F:\tmp\about2.ps1:1 char:1
+ $i = 1
+ ~~~~~~
PS>> v
At F:\tmp\about2.ps1:2 char:6
+ for ('str'.Length;
+      ~~~~~~~~~~~~
PS>> v
At F:\tmp\about2.ps1:3 char:6
+      $i -gt 0; $i--)
+      ~~~~~~~~
PS>> v
At F:\tmp\about2.ps1:5 char:5
+     "v"
+     ~~~
PS>> v
v
At F:\tmp\about2.ps1:3 char:16
+      $i -gt 0; $i--)
+                ~~~~
PS>> v
At F:\tmp\about2.ps1:3 char:6
+      $i -gt 0; $i--)
+      ~~~~~~~~
PS>> v

PR Checklist

@daxian-dbw daxian-dbw requested a review from BrucePay July 18, 2018 01:03
}

internal Expression UpdatePosition(Ast ast)
private int AddSequencePoint(IScriptExtent extent)
Copy link
Member Author

Choose a reason for hiding this comment

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

Note: this method is added to make sure that one extent can only be added to the sequence list once.

@daxian-dbw
Copy link
Member Author

@BrucePay Can you please review this PR when you have time? Thanks!

@daxian-dbw daxian-dbw self-assigned this Jul 21, 2018
@daxian-dbw daxian-dbw added WG-Interactive-Debugging debugging PowerShell script WG-Engine core PowerShell engine, interpreter, and runtime labels Jul 21, 2018
$errorRecord.ScriptStackTrace | Should -Match "SwitchError2.ps1: line 3"
}

It "for statement initializer evaluation failure should report correct error position" {
Copy link
Member

Choose a reason for hiding this comment

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

There should also be a test for while/do loops

Copy link
Member Author

Choose a reason for hiding this comment

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

More tests added.


$script3 = @'
$test = 2
for ("string".Length;
Copy link
Member

Choose a reason for hiding this comment

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

In the product code, there's a special check for while/do loops, but I don't see a test here for that?

Copy link
Member Author

Choose a reason for hiding this comment

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

More test added.

@daxian-dbw
Copy link
Member Author

@SteveL-MSFT I corrected the condition sequence point update for while/do-while/do-until loops and if-statement as well. More tests are added. Please take another look when you have time. Thanks!

Copy link
Contributor

@PaulHigin PaulHigin left a comment

Choose a reason for hiding this comment

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

LGTM

}
else
{
// For switch statement, we don't want the debugger to stop at 'stmt.Condition' before evaluating it.
Copy link
Contributor

Choose a reason for hiding this comment

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

From this comment it is not clear how the code prevents these two undesirable behaviors. Can you clarify?

Copy link
Member Author

@daxian-dbw daxian-dbw Jul 24, 2018

Choose a reason for hiding this comment

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

The argument checkBreakpoints: false when calling UpdatePositionExpr means not checking breaking point for this sequence point update.

"line 1"
"line 2"
"line 3"
$path = Setup -PassThru -File BasicTest.ps1 -Content $script
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we add debugger stop position tests as well as hit count (similar to error position tests)?

Copy link
Member Author

Choose a reason for hiding this comment

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

That sounds good. Can you please show an example of how to check for debugger stop position?

Copy link
Contributor

Choose a reason for hiding this comment

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

You can create a type (Add-Type) that has a method to handle the runspace.debugger.DebuggerStop event and then check the event argument InvocationInfo extent (I think). Contact me offline for more info.

Copy link
Member Author

@daxian-dbw daxian-dbw Jul 24, 2018

Choose a reason for hiding this comment

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

OK. I will play with it, and add more tests in a separate PR. Thanks!

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

Labels

WG-Engine core PowerShell engine, interpreter, and runtime WG-Interactive-Debugging debugging PowerShell script

Projects

None yet

Development

Successfully merging this pull request may close these issues.

switch statement report incorrect error position when it fails to evaluate the condition

3 participants