-
Notifications
You must be signed in to change notification settings - Fork 8.1k
New New-PSBreakpoint cmdlet & new -Breakpoint parameter for Debug-Runspace
#8923
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New New-PSBreakpoint cmdlet & new -Breakpoint parameter for Debug-Runspace
#8923
Conversation
8b61269 to
28b03b5
Compare
src/Microsoft.PowerShell.Commands.Utility/commands/utility/DebugRunspaceCommand.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.PowerShell.Commands.Utility/commands/utility/Enable-PSBreakpoint.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.PowerShell.Commands.Utility/commands/utility/PSBreakpointCreationBase.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.PowerShell.Commands.Utility/commands/utility/New-PSBreakpoint.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.PowerShell.Commands.Utility/commands/utility/PSBreakpointCreationBase.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.PowerShell.Commands.Utility/commands/utility/PSBreakpointCreationBase.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.PowerShell.Commands.Utility/commands/utility/PSBreakpointCreationBase.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.PowerShell.Commands.Utility/commands/utility/PSBreakpointCreationBase.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.PowerShell.Commands.Utility/commands/utility/PSBreakpointCreationBase.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.PowerShell.Commands.Utility/commands/utility/PSBreakpointCreationBase.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.PowerShell.Commands.Utility/commands/utility/DebugRunspaceCommand.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.PowerShell.Commands.Utility/commands/utility/DebugRunspaceCommand.cs
Outdated
Show resolved
Hide resolved
723f2a7 to
ae096f5
Compare
|
@TylerLeonhardt, your last commit had failures in |
PaulHigin
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks really good. I have just a couple of minor comments.
src/System.Management.Automation/engine/remoting/server/ServerRunspacePoolDriver.cs
Outdated
Show resolved
Hide resolved
|
@PaulHigin I've made two more APIs public: It seemed like the right thing to do considering the SetBreakpoints method public. This is now fully ready for review with tests. |
|
@TylerLeonhardt, your last commit had 1 failures in The term 'New-PSBreakpoint' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At D:\a\1\s\test\powershell\Modules\Microsoft.PowerShell.Utility\Enable-RunspaceDebug.Tests.ps1:64 char:27 |
|
@PoshChan please restart CI-windows |
|
@TylerLeonhardt, I do not understand: please restart CI-windows |
|
@TylerLeonhardt, your last commit had 56 failures in ParserTests (admin\monad\tests\monad\src\engine\core\ParserTests.cs).Numerical Notations Tests (starting at line 2374 to line 2452).0b0 should return 0, with type [int] Expected '0', but got $null.
at <ScriptBlock>, D:\a\1\s\test\powershell\Language\Parser\Parser.Tests.ps1: line 949
949: ExecuteCommand $Script | Should -Be $ExpectedValueParserTests (admin\monad\tests\monad\src\engine\core\ParserTests.cs).Numerical Notations Tests (starting at line 2374 to line 2452).0b10 should return 2, with type [int] Expected '2', but got $null.
at <ScriptBlock>, D:\a\1\s\test\powershell\Language\Parser\Parser.Tests.ps1: line 949
949: ExecuteCommand $Script | Should -Be $ExpectedValueParserTests (admin\monad\tests\monad\src\engine\core\ParserTests.cs).Numerical Notations Tests (starting at line 2374 to line 2452).-0b10 should return -2, with type [int] Expected '-2', but got $null.
at <ScriptBlock>, D:\a\1\s\test\powershell\Language\Parser\Parser.Tests.ps1: line 949
949: ExecuteCommand $Script | Should -Be $ExpectedValueParserTests (admin\monad\tests\monad\src\engine\core\ParserTests.cs).Numerical Notations Tests (starting at line 2374 to line 2452).0b11111111 should return -1, with type [int] Expected '-1', but got $null.
at <ScriptBlock>, D:\a\1\s\test\powershell\Language\Parser\Parser.Tests.ps1: line 949
949: ExecuteCommand $Script | Should -Be $ExpectedValueParserTests (admin\monad\tests\monad\src\engine\core\ParserTests.cs).Numerical Notations Tests (starting at line 2374 to line 2452).0b1111111111111111 should return -1, with type [int] Expected '-1', but got $null.
at <ScriptBlock>, D:\a\1\s\test\powershell\Language\Parser\Parser.Tests.ps1: line 949
949: ExecuteCommand $Script | Should -Be $ExpectedValue |
3f03ea1 to
8e17db1
Compare
|
The single Codacy failure is not important here. |
test/powershell/Modules/Microsoft.PowerShell.Utility/Enable-RunspaceDebug.Tests.ps1
Outdated
Show resolved
Hide resolved
test/powershell/Modules/Microsoft.PowerShell.Utility/Enable-RunspaceDebug.Tests.ps1
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like this test is unnecessary and we should assume that Experimental feature works correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this test has validity. It makes sure that experimental feature was added to to the Breakpoint parameter because that could be forgotten.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But then you could just test that it's not in the list of Get-ExperimentalFeature?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That won't test to make sure the parameter was marked as a part of the experimental feature though... as in...
This test makes sure that this line was added:
[Experimental("Microsoft.PowerShell.Utility.PSDebugRunspaceWithBreakpoints", ExperimentAction.Show)]If that line was removed by any reason, or if the list of experimental features was tampered with, this test would fail.
All in all, I was following the examples of the other experimental feature tests but I can refactor this to only have Feature-Enabled tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's probably ok to leave it then
|
@PoshChan please retry windows |
|
@TylerLeonhardt, successfully started retry of |
|
I don't mind flushing out the POC and submitting a PR. Some questions first: As far as PSES goes, if you set the breakpoint in the runspace via |
Yes. Under no circumstances should a editor debugger break unless:
|
|
Got it, thanks. |
|
@TylerLeonhardt: FYI, I'm making good progress on this, but I have something I need help with.
If I go for job support as well, I could also store the job instance id on the breakpoint as well, so that I can pipe breakpoints that I'm managing in a job, and have the runspace instance id for use within that job to set the breakpoint accordingly. Does that make sense? Any problems you forsee with this approach before I go down this path? |
|
I'd like to hear @PaulHigin's thoughts on this. |
|
Adding @PaulHigin's reply that happened on in email discussion about this.
|
|
One thing you'll wanna watch out for is that the RemoteDebugger type does not have any SetBreakpoint() APIs. Paul's recommendation is to add to/leverage this part of the code to handle setting the breakpoints on the remote runspace |
|
Could we consolidate results of the discussion in new Issue to have publicly a clear plan for community? |
|
Keep in mind that modifying RemoteDebugger function means we also have to update the remoting protocol version and document, and ensure backwards compatibility. |
|
@PaulHigin Out of curiousity, why would you recommend modifying PreProcessDebuggerCommand instead of either...
What does using |
|
A The idea is that within the Does that make sense? |
|
@TylerLeonhardt Technically that makes sense to me, sure, and I have no problem implementing it that way, but I still wonder why you would suggest that approach vs making the |
|
Yes, as Tyler mentions, the PreProcessDebuggerCommand is where we process remote debugging commands as defined in the protocol. |
|
I appreciate the extra details @TylerLeonhardt and @PaulHigin, but I'm still missing some pieces of the puzzle. The fog is clearing up a little though. Here's where I'm at right now:
If those questions don't make sense, please let me know. |
|
The MS-PSRP and MS-PSRDP protocol documents are Windows documents that we manage internally. The protocol is how we execute remote debugging commands over the wire, so we have to extend it when adding new functionality, and this includes updating the document. This was not implemented originally because there was no need for it. But now that there is, we need to do it using the current protocol implementation mechanism. You can look at the 'PreProcessDebuggerCommand' in the 'ServerRunspacePoolDriver.cs' source file to see how other functions are implemented. |
|
Thanks @PaulHigin. On your last reply, I should add one point of clarification that is needed. When @TylerLeonhardt implemented this PR, one of the changes he made was to add @TylerLeonhardt, based on what I've heard from Paul here, it sounds like |
|
Yep, after further inspection of my code, I made an assumption that the RemoteDebugger (which has a Debugger property) was a reference to the ScriptDebugger... But it's not the case. It's totally circular (still a Remote Debugger type) myRemoteDebugger.Debugger.Debugger.Debugger.Debugger |
|
@TylerLeonhardt Thank you for confirming, and @PaulHigin, thank you for the protocol details. This all makes so much more sense now. :) |
|
What is conclusion about the PR? Should we revert it? |
|
I'd prefer just fixing it with another PR. I'm already well on my way with those changes, and many of the changes Tyler made will remain in place. |
|
@PaulHigin Am I correct in my understanding (based on reading the code) that "Get" commands sent over the MS-PSRDP do not use the pre-processor, because they need to return data back to the caller and it doesn't seem that there is a way to do that aside from creating/invoking a For example, the only "Get" command prior to needing to add |
|
Yes, that is correct. For any over the wire debugger command that doesn't return data and just sets debugger state, PreProcessDebuggerCommand() simply sets the debugger state and stops. But for for debugger commands that returns data (currently only GetDebuggerStopArgs), a script has to run so that data can be returned via the normal remoting mechanism. |
|
Hey @PaulHigin, I was trying to get this PR submitted today, but stumbled upon an ugly bug in how breakpoints are handled that got in the way. I want to fix that bug as part of the PR I'm working on. It's a pretty weird bug, and definitely needs fixing. Here's a repro scenario that works in 5.1 and 6.2.1 that should work in 7 preview as well: # Create a job that writes a bunch of different types of stream data
$job = Start-Job -ScriptBlock {
1..1000 | ForEach-Object {
Start-Sleep -Seconds 1
$_
Write-Error 'boo'
Write-Verbose 'Verbose' -Verbose
$DebugPreference = 'Continue'
Write-Debug 'Debug'
Write-Warning 'Warning'
}
}
# Set a local breakpoint on the Get-Process command
Set-PSBreakpoint -Command Get-Process
# Take note that the breakpoint with ID 0 is a command breakpoint for Get-Process
# Debug the job
Debug-Job -Job $job
# In your nested debugger, create a breakpoint inside of the job that triggers when the DebugPreference variable is written
Set-PSBreakpoint -Variable DebugPreference
# Detach your debugger
d
# Now that you're back in your main PowerShell runspace, have a look at your breakpoints
Get-PSBreakpointThe reason this happens is because of an event loop. The What I could use some help on here is how best to solve it. What was the original intent behind having a job or nested debugger trigger an event handler in a parent Please give this a look and let me know how you feel I should proceed as soon as you can. Thanks! cc: @TylerLeonhardt |
|
It feels to me that this work is getting out of hand. I think we need to take a step back and be more clear about what debugging changes need to be made, the scope and motivation of those changes. The best way to do this is via RFC and design documents. Let's start with an RFC and a short summary of what we want to achieve along with scenarios we want to support. Remote and job debugging support may be a separate effort. cc: SteveL-MSFT, @TylerLeonhardt |
|
@PaulHigin What?!? That is a horrible suggestion. Seriously, just horrible. I'm just a contributor here, but I've put a lot of time into this. I've pushed another PR on the side because I felt getting this corrected (the design of this functionality and the issues in its implementation) were more important than finishing up tests on the other PR work. Now you want to put all of that work on hold when I'm just about to submit a PR, slam on the brakes, and push it through the terribly slow RFC process, where I have many, many RFCs that just are not progressing, throwing my efforts to get some of these things corrected and into PowerShell 7 out the door completely? Thanks but no thanks. The original work @TylerLeonhardt did skipped the RFC process, and was merged. Now here we are with me having finished my dev work, but I found a bug that should be looked at, so I reached out because I can't make assumptions about why the existing implementation is there, and I don't have the luxury of being on your team to talk directly to you about this, so I ask questions here. I know that interrupts your other work. I'm trying to help you guys, and PowerShell as a whole (the product and the community). You're making it really hard for me to do that. cc: @SteveL-MSFT |
|
I understand your frustration, but we need a way to manage extensive changes to the code base and RFCs are the current way to do that. PRs are fine for small scope changes, but I feel this has gone beyond that and we need step back and think carefully about what we want to do and how to move forward. I know that RFCs are a slow process, but really it is meant to be so that we don't make decisions we later regret. Also, I have other high priority work to do so I cannot always be as responsive as I would like. Regarding RFCs, I find that smaller, well scoped, clear and concise writing gets better and quicker responses. Verbose writing is harder to parse and understand. Large scope changes are harder approve since it is difficult to think through all implications, including compatibility and documentation. In general I prefer incremental changes where possible. |
|
Just to add… the original scope of this work was to make the VSCode extension better by providing APIs (as in PowerShell’s C# API) for managing breakpoints. We expanded on that by exposing a few additions to cmdlets so that folks debugging from the CLI could take advantage of these features - thus Upon seeing @KirkMunro’s original thoughts on cmdlet design, I agreed that As @KirkMunro continued this work, it’s clear that there are edge cases in the debugging stack. That’s not surprising - it’s a piece of software. I personally think that we should not include any bug fixes with this change and instead, should address bug fixes in a separate PR so to make the size of the PR that adds this feature smaller. The PR should only:
This is why we didn’t originally open an RFC for this is because the extension needs this functionality to act in the way other language debuggers in vscode do. It was scoped to this. |
|
I'm good with that, for the most part. The other issues will quickly fall into my short list of items to resolve after this work. |
|
Even if you disagree strongly with something, please remember to follow our code of conduct when posting in issues or PRs. Locking out the rest of this one as I think we're closed here. If you still want to push for some of your changes that weren't merged, feel free to open a discussion issue. I'll be publishing a blog on RFCs and feature additions soon, hopefully it should address some of the confusion around scenarios like this one. |
PR Summary
This PR does 4 things:
New-PSBreakpointwhich creates newBreakpointobjects and writes them to the pipeline-Breakpointparameter toDebug-Runspacewhich will receiveBreakpointobjects*Breakpointpublic for use with the APIDebugger.GetBreakpoint(string id)andDebugger.GetBreakpoints()public sinceSetBreakpointsis publicNote:
New-PSBreakpointandSet-PSBreakpoint(which already exists) are similar... butSet-PSBreakpointalso sets the breakpoints in the current runspace. This is not ideal if we want to set breakpoints in a different runspace than the current one.PR Context
The "Attach to process" debugging experience in the PowerShell extension for VSCode is ok but it's not great.
The reason it's not great is due to the
BreakAllfeature of PowerShell debugging which, when you runDebug-Runspace, will break at the first piece of code that gets run. This is not ideal when you "Attach to process" and then run your code in the other runspace.Today, the experience drops you in
PSReadLine's psm1 if PSRL is available or in the vscode PowerShell helper psm1.It's unexpected for the user and not ideal.
This PR will allow the extension to pass in the breakpoints that need to be set initially with
BreakAllturned off for none of this silly behavior.Silly behavior example
If you want a repro, try this:
PowerShell instance 1:
PowerShell instance 2:
Note that you end up NOT
runfoo.ps1PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright headerWIP:or[ WIP ]to the beginning of the title (theWIPbot will keep its status check atPendingwhile the prefix is present) and remove the prefix when the PR is ready.New-PSBreakpointMicrosoftDocs/PowerShell-Docs#4140[feature]to your commit messages if the change is significant or affects feature tests