Skip to content

Prevent TieredPGO inlining from breaking stack trace walking logic - #2620

Merged
Max Schmitt (mxschmitt) merged 8 commits into
microsoft:mainfrom
slang25:fix-stacktrace-logic
Jun 26, 2023
Merged

Max Schmitt (mxschmitt) merged 8 commits into
microsoft:mainfrom
slang25:fix-stacktrace-logic

Conversation

@slang25

@slang25 Stuart Lang (slang25) commented Jun 18, 2023 •

Copy link
Copy Markdown
Contributor

Fixes #2617

I've recreated the issue locally on macOS on my M2 MBP, this fixes the exception, I need to check that the traces have the right API names captured still.

namespaceName.StartsWith("Microsoft.Playwright.Helpers", StringComparison.InvariantCultureIgnoreCase));
}

[MethodImpl(MethodImplOptions.NoInlining)] // This method is also a stacktrace marker.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

While not strictly necessary, it seems a good idea to make this explicit

@slang25
Stuart Lang (slang25) marked this pull request as draft June 18, 2023 09:13
@slang25

Copy link
Copy Markdown
Contributor Author

Unfortunately I've done some further testing and it looks like a lot of the method names captured in the trace will change to base types, which isn't desired, I'll look to improve this PR.

@slang25

Copy link
Copy Markdown
Contributor Author

Update:

So this PR fixes the NullReferenceException, but in order to get the right API name captured like this:

Assert.GreaterOrEqual(events.Where(e => e?.ApiName == "Page.GotoAsync").Count(), 1);
Assert.GreaterOrEqual(events.Where(e => e?.ApiName == "Page.SetContentAsync").Count(), 1);
Assert.GreaterOrEqual(events.Where(e => e?.ApiName == "Page.ClickAsync").Count(), 1);
Assert.GreaterOrEqual(events.Where(e => e?.ApiName == "Mouse.MoveAsync").Count(), 1);
Assert.GreaterOrEqual(events.Where(e => e?.ApiName == "Mouse.DblClickAsync").Count(), 1);
Assert.GreaterOrEqual(events.Where(e => e?.ApiName == "Keyboard.InsertTextAsync").Count(), 1);
Assert.GreaterOrEqual(events.Where(e => e?.ApiName == "Page.CloseAsync").Count(), 1);

we're going to need to sprinkle NoInlining over all of the public APIs. I've been thinking about other approaches that don't do stack frame walking, however some public APIs flow through other public APIs , for example Page.GotoAsync → Frame.GotoAsync (see here), which makes that harder to do in a non-breaking way.

@slang25
Stuart Lang (slang25) marked this pull request as ready for review June 23, 2023 22:59
@slang25

Copy link
Copy Markdown
Contributor Author

So this is now working and tested with some traces. Unfortunately the cleanest way I could think to do this was add [MethodImpl(MethodImplOptions.NoInlining)] absolutely everywhere on the public APIs of anything that inherits ChannelOwnerBase, this is enforced with a convention test.

Comment thread src/Playwright.Tests/ConventionTests.cs Outdated

@mxschmitt Max Schmitt (mxschmitt) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Amazing work!

Comment thread src/Playwright.Tests/ConventionTests.cs Outdated
{
if (!method.MethodImplementationFlags.HasFlag(MethodImplAttributes.NoInlining))
{
#pragma warning disable CA1305

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

would be nice to get rid of that.

Comment thread src/Playwright.Tests/ConventionTests.cs
@mxschmitt
Max Schmitt (mxschmitt) merged commit fba5017 into microsoft:main Jun 26, 2023
@mxschmitt

Copy link
Copy Markdown
Contributor

Stuart Lang (@slang25) thank you so much for looking into this and Andy Ayers (@AndyAyersMS) for filing it inside this repo with all the details!

@slang25
Stuart Lang (slang25) deleted the fix-stacktrace-logic branch June 26, 2023 21:09
@slang25

Copy link
Copy Markdown
Contributor Author

My pleasure Max Schmitt (@mxschmitt) 🙂

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Stack inspection done by playwright is fragile and breaks with Dynamic PGO enabled

3 participants