Skip to content

Fix debug tracing error with magic extents #25726

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

Merged
merged 3 commits into from
Jul 15, 2025

Conversation

jborean93
Copy link
Collaborator

@jborean93 jborean93 commented Jul 4, 2025

PR Summary

Fixes the error when PowerShell attempts to print the debug trace line for functions generated with an invalid extent. For example PowerShell creates an extent with a column and line of 0 for things like the default class constructors. This is an issue as the trace debug line always subtracts by 1 to make the value start at 0 rather than 1.

It also adds the DebuggerHidden attribute to the class default constructor to avoid confusing end users from seeing a trace line for something they did not write.

Edit: Removed this due to build issues.

PR Context

Fixes: #16874

I can remove the added attribute on the scriptblock and the fix will still be present but I thought it best to keep it there anyway. It doesn't hurt to be present and have that particular scenario skip the tracing altogether.

Edit: Was removed due to build issues.

Also Pester code coverage and Profiler uses this tracing so it's commonly seen even if people don't enable the tracing themselves.

PR Checklist

Fixes the error when PowerShell attempts to print the debug trace line
for functions generated with an invalid extent. For example PowerShell
creates an extent with a column and line of 0 for things like the
default class constructors. This is an issue as the trace debug line
always subtracts by 1 to make the value start at 0 rather than 1.

It also adds the DebuggerHidden attribute to the class default
constructor to avoid confusing end users from seeing a trace line for
something they did not write.
{
Set-PSDebug -Trace 1
[ClassWithDefaultCtor]::new()
} | Should -Not -Throw
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does the test really throw before the fix?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Run it yourself and see :)

@iSazonov iSazonov added the CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log label Jul 4, 2025
@microsoft-github-policy-service microsoft-github-policy-service bot added the Review - Needed The PR is being reviewed label Jul 11, 2025
if (_context.ShouldTraceStatement &&
!_callStack.Last().IsFrameHidden &&
!functionContext._debuggerStepThrough &&
functionContext.CurrentPosition.StartScriptPosition.ColumnNumber > 0)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Both StartScriptPosition and InternalScriptPosition.ColumnNumber are calculated in the getter, so while tracing isn't exactly perf focused hopefully something like this will work:

Suggested change
functionContext.CurrentPosition.StartScriptPosition.ColumnNumber > 0)
functionContext.CurrentPosition is not EmptyScriptExtent &&
(functionContext.CurrentPosition is InternalScriptExtent ||
functionContext.CurrentPosition.StartColumnNumber > 0))

Thoughts?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Just tested it locally and looks like it works for this scenario. I wasn't sure whether the fix should have been done here or just a check in the BriefMessage to just treat it as the start column or the change in this PR.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I see EmptyScriptExtent is used only in scenario where an error is in script file. So it makes no sense to check the both types.

Copy link
Collaborator

@SeeminglyScience SeeminglyScience Jul 15, 2025

Choose a reason for hiding this comment

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

I see EmptyScriptExtent is used only in scenario where an error is in script file. So it makes no sense to check the both types.

I think you may have followed the wrong reference, it's used in a ton of places including this one. It's typically accessed via PositionUtilities.EmptyExtent so maybe you were just looking for the type itself.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Just tested it locally and looks like it works for this scenario. I wasn't sure whether the fix should have been done here or just a check in the BriefMessage to just treat it as the start column or the change in this PR.

Yeah kind of a toss up, realistically any code that accesses IScriptExtent should be way more careful. It tends to assume we're talking about InternalScriptExtent but it could be external code.

@microsoft-github-policy-service microsoft-github-policy-service bot added Waiting on Author The PR was reviewed and requires changes or comments from the author before being accept and removed Review - Needed The PR is being reviewed labels Jul 14, 2025
Co-authored-by: Patrick Meinecke <SeeminglyScience@users.noreply.github.com>
@microsoft-github-policy-service microsoft-github-policy-service bot removed the Waiting on Author The PR was reviewed and requires changes or comments from the author before being accept label Jul 15, 2025
@SeeminglyScience
Copy link
Collaborator

/azp run PowerShell-CI-linux-packaging, PowerShell-Windows-Packaging-CI

Copy link

Azure Pipelines could not run because the pipeline triggers exclude this branch/path.

@SeeminglyScience SeeminglyScience merged commit ce76ae1 into PowerShell:master Jul 15, 2025
37 checks passed
@jborean93 jborean93 deleted the tracing-columns branch July 15, 2025 20:15
@jborean93
Copy link
Collaborator Author

Any chance for a backport with this? Seems like a simple fix to include.

@SeeminglyScience
Copy link
Collaborator

Any chance for a backport with this? Seems like a simple fix to include.

We don't typically backport unless it's a regression or a new high impact scenario is discovered. Is it a blocker for you in something?

Note that I know it's a simple code change, but when doing a servicing release even an unexpected false positive on an analyzer could cost a day of release time. That can be especially impactful for the servicing releases that are security related.

@jborean93
Copy link
Collaborator Author

Not a blocker, just didn’t seem like a big change and would have been nice to see in earlier releases.

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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

When tracing, Language.PositionUtilities.BriefMessage() passes an out-of-range index to StringBuilder.Insert()
4 participants