DISCLAIMER: Unless you've spent some time with debuggers, and specifically with the PowerShell debugger, this may confuse you.
As a PowerShell user,
I want the entire debugging experience focused on "Just My Code" (JMC) by default,
so that I can debug that code effectively and optimally without getting lost in or distracted by other code used in PowerShell.
As a PowerShell user,
I want scripts and/or modules installed from a gallery to be automatically recognized as "not my code",
so that my debugging experience does not debug into those scripts/modules by default.
As a PowerShell tool author,
I want properly defined and properly functioning DebuggerHidden
and DebuggerStepThrough
attributes,
so that I can leverage those attributes in my tools and provide users of my tool with an optimal debugging experience.
As a PowerShell user,
I want an option to allow me to turn off "Just My Code" (JMC) debugging,
so that I can debug into installed (but not internal) PowerShell code when I need to.
For reference: Debug user code with Just My Code.
This issue is all about the following debugger attributes that can be used in any script, function, or script block:
[System.Diagnostics.DebuggerHidden()]
[System.Diagnostics.DebuggerStepThrough()]
[System.Diagnostics.DebuggerNonUserCode()]
Since PowerShell is interpreted rather than compiled, we need to be more vigilant when it comes to debugger behavior so that scripters can debug their own code more effectively. This means preventing scripters from debugging code that is meant to be entirely internal (hidden from the end user) as well as preventing users from unintentionally debugging scripts or modules that are considered stable (these may include scripts that they installed, or scripts that they wrote themselves but that they consider fully debugged). Essentially, some code should be treated as much like a black box as an executable or binary module would. These attributes are key to making that happen, but up to this point, the debugger has not been properly implemented to provide an optimal debugging experience for users when those attributes are used.
If you would like to better understand the problems, try some of the scenarios listed below using PowerShell 7 preview 3 or earlier.
Scenario 1: Set a command breakpoint on Set-StrictMode
.
Open a new session, and then invoke the following:
Set-PSBreakpoint -Command Set-StrictMode
When you do this, you'll immediately hit a breakpoint because PSReadline internally invokes PowerShell, and the PSConsoleHostReadLine
function does not use a debugger attribute to tell PowerShell that they aren't meant for end-user debugging.
If you did this, the only way out is to remove your breakpoint and then quit the debugger.
Scenario 2: Set a command breakpoint on Set-StrictMode
with PSReadline unloaded, and generate an error.
Open a new session, and then invoke the following:
Remove-Module PSReadline
Set-PSBreakpoint -Command Set-StrictMode
Get-Process -Id 12345678
When you invoke these commands, the moment the error is raised you'll hit a breakpoint inside the formatting code. This happens because the formatting code invokes nested script blocks, and at the moment these script blocks do not pick up on the DebuggerHidden
attribute that is set on the parent script block.
Note that in this and the previous example, I'm just using Set-StrictMode
because it is an easy example to pick on. The point is that there are plenty of tools, including PowerShell itself, that invoke PowerShell in a way that is supposed to be internal (a black box to the end user), but that the debugger can still see and trigger breakpoints on. It all depends on the commands or variables that those tools invoke, and the level of effort the tool authors made in order to prevent their internal logic written in an interpreted language from being visible to the PowerShell debugger.
Scenario 3: Set a breakpoint on Get-Help
in Visual Studio Code.
Open Visual Studio Code, and in the embedded PowerShell terminal, invoke the following:
Set-PSBreakpoint -Command Get-Help
Now move your mouse around over a tab that has a PowerShell ps1
file open in it. Eventually you'll probably see the terminal crash. This is because it tries to enter the debugger in a call to Get-Help
, which is invoked in a mouse hover event handler. Either that, or something similar...I haven't read through the code to see what is actually going on, but regardless, setting a breakpoint should _not_ cause a crash.
Scenario 4: Set a breakpoint on something used inside of a Where-Object
or ForEach-Object
script block, when that command is invoked from a script block that is configured with DebuggerHidden
.
Open a new PowerShell session and invoke the following:
Set-PSBreakpoint -Variable i -Mode ReadWrite
& {
[System.Diagnostics.DebuggerHidden()]
param()
$i = 0
1..5 | ForEach-Object {$i += $_}
}
When you invoke that code, notice that the debugger does not stop on the line where $i
is initialized, but that it does stop inside the ForEach-Object
invocation where $i
is changed, even though this is inside of a parent script block with the DebuggerHidden
attribute. Support for the DebuggerHidden
attribute in PowerShell was simply not implemented to handle scenarios like this, but it must be because otherwise it can be very difficult for tool builders to create truly internal code that is written in PowerShell.
Scenario 5: Set a breakpoint on something used inside of a script block defined in user scope, but pass that script block into a command that is configured with DebuggerHidden
.
Open a new PowerShell session and invoke the following:
$sb = {$global:i += $_}
Set-PSBreakpoint -Variable i -Mode Read
$i = 0
function Invoke-FiveTimes {
[System.Diagnostics.DebuggerHidden()]
param(
[Parameter(Mandatory)]
[ValidateNotNull()]
[scriptblock]
$ScriptBlock
)
1..5 | ForEach-Object $ScriptBlock
}
Invoke-FiveTimes -ScriptBlock $sb
When you invoke that code, the debugger will stop on the line in the script block that you passed into the function each time it reads the value of $i
. This may seem like the correct behavior, because the script block is defined outside of the function that uses the DebuggerHidden
attribute, but that's not true. DebuggerHidden
is meant to act as bouncer to a black box -- the debugger is simply not allowed in. On the other hand, DebuggerStepThrough
is meant to allow a debugger to pass through a script block and then debug other commands or script blocks that are invoked that are defined outside of the script block that has the attribute.
Scenario 6: Stepping into a function that invokes a script block passed in as a parameter, when that function uses DebuggerStepThrough
.
Open a new PowerShell session and invoke the following:
& {
$sb = {
Get-Process -Id $PID
}
function Test-StepInto {
[CmdletBinding()]
[System.Diagnostics.DebuggerStepThrough()]
param(
[scriptblock]$ScriptBlock
)
& $ScriptBlock
}
Wait-Debugger
Test-StepInto -ScriptBlock $sb
}
When you invoke this script, you'll be dropped into the debugger on the Test-StepInto
command invocation. Invoke the debugger s
command to step into the Test-StepInto
function. The debugger is supposed to step through that function because of the DebuggerStepThrough
attribute, and bring you into the script block that is invoked, but it doesn't. Instead, it just bounces you out the door to the closing curly brace after the invocation.
Most of these scenarios use command breakpoints, but as you can see some also use variable breakpoints to have similar impacts if I choose the right variable names. A key point is that command breakpoints and variable breakpoints are very powerful debugging tools, and should be capable of bringing you very close to _your_ issues in _your_ scripts or modules when you want them to, but as long as other tools and PowerShell itself can get in the way, which they do when they use the same commands or variable names in their implementation, the usefulness of these breakpoints is greatly diminished. You can work around the breakpoint challenges by scoping these types of breakpoints to specific files (one breakpoint is created per file), but that requires much more work, especially if you're just working from the command line, and it is more complicated if you're working across multiple files in an automated solution.
For the last few scenarios, they show how stepping is not working the way it should when these attributes are defined. The entire reason for the existence of these attributes is efficient debugging, yet PowerShell is not handling them properly, and debugging is anything but efficient as a result.
Wouldn't it be great if you could count on command breakpoints and variable breakpoints to hit breakpoints in _your code_, and not get caught up in code from any of the other PowerShell tools you have on your system?
As a tool author, wouldn't it be great if you could more easily author your code and be able to count on it being treated like a black box when it is installed on other systems?
And when you are stepping through the debugger, wouldn't it be great if the debugger properly avoided code that it shouldn't?
The proposed solutions below are designed to solve those problems and make debugging much, much easier.
Debugger*
attributesThe current behavior of the debugger attributes isn't very appropriate for an interpreted language. Here's how these attributes work today:
DebuggerHidden
(DH)If you apply this attribute to a script block (or an entire script), the contents of the root scope of that script block will be hidden from the debugger. Breakpoints will not trigger within that script block, but they will trigger in script blocks defined and invoked within that script block, or in script blocks defined outside of that script block but invoked internally as parameters. Wait-Debugger
, and ActionPreference.Break
preferences work the same way. Users will not be able to step through the root scope of the script block using the debugger.
You can toggle the DH behavior on a script block today by changing the boolean value of a script block's DebuggerHidden
property.
DebuggerStepThrough
(DST)If you apply this attribute to a script block (or an entire script), the contents of the root scope of that script block will be hidden from the debugger. Breakpoints will not trigger within the root scope of that script block, but they will trigger in script blocks defined and invoked within that script block. Wait-Debugger
, and ActionPreference.Break
preferences work the same way. If you try to step into a script block that uses this attribute, you cannot. If, however, you are in the debugger on a breakpoint that is in a nested scope where the parent scope has the DST attribute, you can step out of that scope and step through the internals that are supposed to be hidden via DST.
You cannot toggle the DH behavior on a script block today by changing the boolean value of a script block's DebuggerStepThrough
property because that property is internal. This is unfortunate, and it would be better if that property was made public so that you could toggle it on a single function/script block if needed to do some debugging without changing the code.
DebuggerNonUserCode
(DNUC)This attribute is simply linked to the DST behavior, and functions the exact same way.
To correct the issues identified above, along with other issues not specifically called out here, the debugger attribute behavior in PowerShell should be defined as follows:
DebuggerHidden
(DH), aka the debugger bouncer)Breakpoints: Breakpoints do not trigger within a script block that has the DH attribute, nor do they trigger in anything that is invoked from within that script block. This attribute acts as a bouncer for the PowerShell debugger, and simply does not let it come in and hang out, at all.
Step Into: You cannot step into a script block that has the DH attribute. Step into is simply treated as step over.
Step Out: N/A. Since the debugger is bounced, you can never step out to a DH script block.
Step Over: N/A. Since the debugger is bounced, you can never step over from within a DH script block.
Toggle behavior: Script blocks expose a DebuggerHidden
property that can be changed to toggle this behavior without changing code. This is useful when you want to temporarily allow debugging for something that is normally hidden from the debugger, assuming you have access to the actual script block to toggle the flag.
Recommended Usage: Use this attribute in tooling on code that is meant to be internal, invisible to the PowerShell debugger. For example, formatting code in PowerShell itself, functions that are internal (not exported) from a module, or any calls made to PowerShell from a tool that are only meant for internal use and shouldn't be visible to the debugger as users debug their own scripts.
DebuggerStepThrough
(DST)Breakpoints: Breakpoints do not trigger within a script block that has the DST attribute, nor do they trigger in any script block defined within and invoked from that script block, recursively. Breakpoints will trigger in commands or script blocks that are defined outside of that script block, if the attributes on those commands allow it.
Step Into: If you step into a script block that has the DST attribute, the debugger will step through that command to the first script block defined externally to that command that is visible to the debugger. This means if you pass in a script block as a parameter and then invoke it, the debugger can step into that script block.
Step Out from nested: If you are on a breakpoint in a scope that is nested under a script block that has the DST attribute and you step out, the debugger will step out of that script block, and out of the script block that has the DST attribute.
Step Over: If you are on a breakpoint in a scope that is nested under a script block that has the DST attribute and you step over, the debugger will step out of that script block, and through the script block that has the DST attribute until it steps out of that script block or into a script block that the debugger can step into.
Toggle behavior: Script blocks should expose their DebuggerStepThrough
property as public so that it can be changed to toggle DST behavior without changing code. This is useful when you want to temporarily allow debugging for something that is normally hidden from the debugger. The DebugPx module has a command that makes this possible on single functions or an entire module as needed, which keeps debugging efficient and focused.
Recommended Usage: Use this attribute in tooling on code that is not internal but that is considered stable/debugged. For example, if you and/or your team create some scripts or modules and debug them, and you don't want to go through that code with the debugger, use this attribute. Another example: if you publish stable releases of scripts or modules to the gallery for others to download and use and you don't want users to debug them, set this attribute in the scripts or in the functions included in those modules so that your users don't get confused by the debugger taking them into that stable, debugged code. Note that with the published module/script scenario, you could instead rely on Just My Code handling that for you.
DebuggerNonUserCode
(DNUC)This attribute is special, because nobody should ever have to set it in their code. Instead, PowerShell should automatically distinguish between user code and non-user code, taking a conservative approach so that it doesn't make mistakes.
User code is a script or module that is written by an end user and needs support for debugging. Non-user code is a script or module or tool that is written by someone else and installed on a system for use as a tool. It _generally_ doesn't need to be debugged, because it is a tool, but users may want to debug it, especially if it is not a stable release.
Debugging-functionality-wise, DNUC should function just like DST; however, there are two key differences between the current functionality of this attribute today and how it should work going forward:
For the automatic, dynamic application of the DNUC attribute, scripts or modules installed using PowerShellGet should automatically be treated as DNUC. Code that is installed under specific directories ("Program Files", "Program Files (x86)", and "Windows" on Windows operating systems, or "/usr" or "/opt" on Linux or macOS -- please comment on these directories) should also automatically be treated as DNUC. Everything else should be treated as user code. Tool builders that ship scripts that are not meant to be treated as user code but that install outside of these paths can manually apply the DNUC attribute (or one of the other attributes) to that code.
Another option would be to define an environment variable that identifies DNUC base paths, so that installers or users can extend it if they want to mark additional DNUC folders.
For the "Just My Code" option, that could be provided as an automatic PowerShell variable ($PSDebugJustMyCode
) that is set to true by default but can be set to false to enable debugging of all non-user code. Additionally, I have seen tools show a "MyCode" flag on modules (libraries), and would like to add that as a session-specific read/write flag to modules and scripts (commands), so that instead of allowing debugging of all non-user code, scripters could toggle the flag on a specific script or module that they want to debug in that session.
I've listed what makes sense to me for this feature. Are the paths listed not conservative enough? Are there other paths that should be included by default?
$env:PSNonUserCodePath
?Such an environment variable would allow users to configure specific paths where they install scripts that they don't want to debug day-to-day.
Does PowerShell use these attributes with classes today? I haven't dug into how these attributes work with classes/methods/properties in PowerShell at all yet, but from the outside I think the exact same behavior would apply, and the only decisions would be whether or not these attributes can be applied on classes, methods, properties, accessors, etc.
Since the debugger needs to be designed to be able to step through a block of script, it would be helpful if users using the debugger could invoke a stepThrough
command (t
for short) to step through the current block of script into the first nested block defined outside of this block that the debugger can step into. That will enable faster debugging in scenarios where you temporarily stop inside of a command to look around, and then want to go through that command into other commands that it invokes.
ScriptBlock.DebuggerStepThrough
property as public?DebuggerHidden
is already public. If we were to decide to make just one of these properties public, I would have argued for DebuggerStepThrough
instead, since that would actually be used on code where you can access that attribute. At any rate, I think DebuggerStepThrough
should be public so that it can be modified without changing code, which allows commands like what I have in DebugPx do their work without mucking around with internals.
In general, I think the majority of the community shouldn't have to use debugger attributes or worry about debugger attributes, although tool builders will need to consider DebuggerHidden
. Efficient debugging should be possible automatically if scripts/modules are distributed through a repository (which can be as simple as a file share).
That said, I think it would be useful to consider a few PSSA rules. Generally speaking, DebuggerNonUserCode
should not be used in scripts. Users who use that in scripts should really consider DebuggerStepThrough
instead. Script blocks should not have more than one debugger attribute associated with them, because there is no point to that (one would override another, so only one would be in effect). Those scenarios could be handled in PSSA rules if desired.
The end result of these changes should result in debugger attributes behaving as follows:
||Step into|Breakpoints triggerable|
|--|--|--|
|DebuggerHidden|Treated as step over|Never|
|DebuggerStepThrough|Treated as step through 1|Never|
|DebuggerNonUserCode|Treated as step through 1|Depends on JMC settings 2|
1 t
, stepThrough
will be added as a new debugger options, allowing users to get into nested code more efficiently from the debugger.
2 New option added to ScriptDebugger
class exposed via a $PSDebugJustMyCode
automatic variable, set by default to $true
.
That's enough of my thoughts on this for now.
The good news is that the outcome of this should help end users not have to think about any of this -- they should simply be able to use the debugger to debug only their code. At the same time, developers will have options that allow them to dig in deeper with the debugger when needed.
If you care about debugging PowerShell, specifically in how to help others debug PowerShell more easily and more efficiently, please share your thoughts on this so that we can make the debugging experience as easy as possible for the PowerShell community.
cc: @lzybkr, @PaulHigin, @rkeithhill, @TylerLeonhardt: There's a lot to read here, but your feedback in particular on this would be appreciated.
Are the listed DNUC paths correct/enough?
Should we have $env:PSNonUserCodePath?
It seems PSModulePath contains the paths.
@iSazonov: Not necessarily. Products installed via installers update PSModulePath
. Users update PSModulePath
. How can we tell which is user code and which is not? Plus, that's just modules, not scripts. We argued for a PSScriptPath
environment variable in the past (before open source) but that idea was shot down.
Anyone care to share thoughts on the intent of the current implementation of the debugger attributes, or thoughts about where I'm trying to take this?
There's a pretty cool opportunity here to make the debugging experience much, much better and much more focused for all users, without much effort on the part of scripters.
Also, a few more things I believe are incorrect and would like to change:
If you set a command breakpoint on a command that happens to have the DebuggerHidden
attribute, the debugger will not stop on the invocation of that command. I believe that behavior is wrong, because the attribute's effect should apply to the script block where it is used, not to invocations outside of that script block.
If you set a command breakpoint on a function, when that breakpoint triggers, you are already inside of the function. I believe that behavior is also incorrect, because it's inconsistent (command breakpoints for cmdlets break on the command invocations) and it causes the previous issue. No matter what type of command being invoked, a command breakpoint should enter the debugger on the invocation of that command when triggered.
~Lastly, on the notion of non-user code (DebuggerNonUserCode
), there is another issue that causes pain for tool builders, where tools can be influenced by user preferences (#10334). User preferences such as $PSDefaultParameterValues
and $*Preference
variables should not influence internal PowerShell invocations inside of tools that users use. I was thinking today that an easy application of the DebuggerNonUserCode
attribute on PowerShell invocations from within tools would be helpful in preventing user preferences from impacting code that is meant to be run as a black box.~ (Strike that, the thoughts in this paragraph are better covered in #10334).
@KirkMunro I like your ideas shared here, they are clear and clean.
I have one concern about "As a PowerShell tool author,". I don't like that as module author I _should_ think how another user want to debug _his_ code. I hope PowerShell debugger could be more smart. (Ex.: VS Code ask me "Do you want jump in/debug the module too or ignore it?") I鈥檓 afraid that there will be modules that use these attributes incorrectly and this will annoy users that the debugger will behave strangely and it will be necessary to somehow deal with it.
Also you could get a feedback in VS Code PowerShell extension repo.
In the end, I want to share an idea that only you could develop/weight. Related https://github.com/pester/Pester/issues/1318 Pester set breakpoints on every line in code coverage scenario. It looks very expensive. We could make special debugger mode for the scenario.
Thanks @iSazonov! Sometimes I wonder if anyone else even cares about the things I'm trying to fix. PowerShell has the potential to offer very efficient debugging, but it isn't there yet.
One of my goals with these changes is that the majority of the community shouldn't have to think much about them. Users publishing modules or scripts shouldn't need to apply these attributes in their functions or scripts at all -- they should be able to simply rely on JMC-debugging keeping the debugging experience focused for them and for users who download their scripts/modules.
I would also want some specific PSSA rules in place to correct users who do apply debugger attributes incorrectly.
On the code coverage scenario, I'm thinking about it.
Sometimes I wonder if anyone else even cares about the things I'm trying to fix.
Nevermind. It is natural. Usually, users prefer a quick workaround to achieve _business_ goals instead of many months of discussion.
MSFT PowerShell team could ask partner teams, partner firms to participate in the repo, share their experience, thoughts and plans (as feature requests).
On the other hand, MSFT PowerShell team does not have enough resources to process all the PRs and, especially, the overdue ideas.
@KirkMunro I appreciate you following the new proposed process by initiating discussion in an issue and driving towards consensus. However, we need more varied feedback from the community. I've tweeted this issue so hopefully that'll encourage more diverse discussion on agreement on the issue and then agreement on a proposed solution. The PowerShell team is busy trying to complete commitments we've made to PS7 so it's unlikely this will make it into PS7, but we can certainly spend time on this early in vNext.
For me as a user the most annoying and confusing thing are the PSReadline breakpoints.
It would be nice to properly solve the underlying problem but if there is an easier/quicker way to prevent this from happening, then I'd prefer this over something that takes longer to be delivered and agreed upon.
After carefully reading ... I have to say:
Here are my reservations:
I think even in the compiled world, people use it instead of more appropriate flags because they don't know the difference, and end up hiding stuff that shouldn't be hidden.
I really don't like the idea that (for example) a ForEach-Object command with DebuggerHidden could make it impossible for me to set breakpoints on the scriptblocks that I'm passing to it or inside commands that it calls. For one, I think that if it's running my code, I need to be able to debug my code.
_I probably just don't understand the scenario_ that makes it necessary. That said (with the understanding I have now), I don't object to the idea -- but I do feel like if it worked as you proposed, I would want a toggle I could set to force DebuggerHidden to act like DebuggerStepThrough (or disable it altogether).
PSDebuggerNonUserPath
(or something) would be a good idea.Each host pre-initializes PSModulePath differently (in theory), so the host needs to also initialize the NonUserPath locations, but still allow 3rd parties (e.g. a product installer), and the user to add additional things to the list.
As for PSDefaultParameterValues, I think that's a completely separate issue we should discuss separately. I think it's super useful, but I also feel like it could be much improved. I think we should _probably_ just always re-define it in module scope. That is, currently authors can, at the top of a module, set $Script:PSDefaultParameterValues = @{}
to protect themselves from changes at the global scope. It makes sense to me that this should be the default behavior for that variable. In fact, I think that's probably what users actually expect to happen.
As for code-coverage, that's also a completely separate issue. It's deffinitely something PowerShell should add (the breakpoint counter is a hack that produces weird counts, and it's painfully slow).
It would be nice to properly solve the underlying problem but if there is an easier/quicker way to prevent this from happening, then I'd prefer this over something that takes longer to be delivered and agreed upon.
@bergmeister This is much bigger than just PSReadline. This problem has impacted every PowerShell tool that I know of. I don't know of a quicker fix, and the debugger attributes currently are not functioning the way they should, so correcting how those work is a good approach to this problem. Note, however, that the fixes proposed here should not take long to deliver -- I've been in that code quite a bit. We just need consensus on how this should be fixed, which hopefully we'll work out with the additional eyes on this.
I am _very_ nervous about DebuggerHidden.
I think even in the compiled world, people use it instead of more appropriate flags because they don't know the difference, and end up hiding stuff that shouldn't be hidden.
I really don't like the idea that (for example) a ForEach-Object command with DebuggerHidden could make it impossible for me to set breakpoints on the scriptblocks that I'm passing to it or inside commands that it calls. For one, I think that if it's running my code, I need to be able to debug my code.
_I probably just don't understand the scenario_ that makes it necessary. That said (with the understanding I have now), I don't object to the idea -- but I do feel like if it worked as you proposed, I would want a toggle I could set to force DebuggerHidden to act like DebuggerStepThrough (or disable it altogether).
@Jaykul Despite how I think DebuggerHidden
should be used, it's more important to note where it shouldn't be used. If you look at PowerShell 7, all formatting script blocks have DebuggerHidden
applied to them automatically. We still end up in formatting because of how DebuggerHidden
is implemented (it doesn't affect nested script blocks today), but the single line of code that sets DebuggerHidden
on any internal format script block should be enough. Another example where DebuggerHidden
should be used is the prompt
function.
In actual scripts or functions, it should be very rare to see DebuggerHidden
, to the point where I would suggest if you're using it, you probably shouldn't be, and I would want PSSA to raise visibliity of that with a warning. With respect to passing script blocks in to a function that has DebuggerHidden
, PSSA should raise an error on any script or function that accepts a script block and has the DebuggerHidden
attribute set. In those cases, the author should be using DebuggerStepThrough
.
Rare use aside, I wanted to describe how it would work, which is why I provided the scenarios above. _If DebuggerHidden
gets in the way of you debugging something, the author is doing it wrong._
As for PSDefaultParameterValues, I think that's a completely separate issue we should discuss separately. I think it's super useful, but I also feel like it could be much improved. I think we should _probably_ just always re-define it in module scope. That is, currently authors can, at the top of a module, set
$Script:PSDefaultParameterValues = @{}
to protect themselves from changes at the global scope. It makes sense to me that this should be the default behavior for that variable. In fact, I think that's probably what users actually expect to happen.
I agree, that should be a separate issue. I was reading this back again, and think Debugger*
attributes need to be just for debugging. I'll continue thoughts related to that point in the discussion on #10334.
Modules already redefine $PSDefaultParameterValues
, since PowerShell 5, so there's nothing more needed there.
As for code-coverage, that's also a completely separate issue. It's deffinitely something PowerShell should add (the breakpoint counter is a hack that produces weird counts, and it's painfully slow).
Agreed.
Thank you @KirkMunro for bringing all this up. It's something that has bothered me tremendously for a long time. I've mostly skimmed the original so far, I'll do a more in-depth read tomorrow but I wanted to mention one thing that caught my eye:
Debugging-functionality-wise, DNUC should function just like DST; however, there are two key differences between the current functionality of this attribute today and how it should work going forward:
The automatic, dynamic application of that attribute to any file that comes from an installed tool (i.e. the debugger needs to recognize which files are non-user files, and treat them accordingly).
By default, PowerShell would be configured to only debug user code ("Just My Code"), but an option would have to be provided to allow users to debug non-user code when needed.
I think this as a default across the board would make it a lot harder to cross the initial bridge of "tons of Read-Host/Write-Host" to utilizing the debugger. It's already extremely difficult for folks who have never used a debugger to even understand what's going on and why it's useful. If they can't easily tell why there breakpoint isn't working, a lot will just give up. I think from a normal shell it's next to impossible to get an acceptable rate of false positives.
From an editor though, I'm all for it. I think it should be up to PSES/PS Studio/etc to declare what is and isn't user code (unless overridden by the user of course).
Thanks again for taking on the arduous task of putting all of those issues into words, I look forward to reading the rest in detail tomorrow 鉂わ笍
I think this as a default across the board would make it a lot harder to cross the initial bridge of "tons of Read-Host/Write-Host" to utilizing the debugger. It's already extremely difficult for folks who have never used a debugger to even understand what's going on and why it's useful. If they can't easily tell why there breakpoint isn't working, a lot will just give up. I think from a normal shell it's next to impossible to get an acceptable rate of false positives.
I have a few thoughts related to this @seeminglyscience:
I'm hopeful that this combination will increase ease of use by focusing the experience on what users are actually trying to debug. You are right though, the combination of things that does this needs to be geared for easy use by less experienced folk.
Most helpful comment
@KirkMunro I appreciate you following the new proposed process by initiating discussion in an issue and driving towards consensus. However, we need more varied feedback from the community. I've tweeted this issue so hopefully that'll encourage more diverse discussion on agreement on the issue and then agreement on a proposed solution. The PowerShell team is busy trying to complete commitments we've made to PS7 so it's unlikely this will make it into PS7, but we can certainly spend time on this early in vNext.