Skip to content

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

@AndyAyersMS

Description

@AndyAyersMS

Context:

We enabled DynamicPGO in .NET 8 Preview 5 and are seeing reports of some failures in applications that use playwright.

See for instance dotnet/runtime#87628

This should readily repro if you run release mode builds with .NET 8 Preview 5 and default runtime options.

Describe the bug

for (int i = 0; i < st.FrameCount; ++i)
{
var sf = st.GetFrame(i);
string fileName = sf.GetFileName();
if (IsPlaywrightInternalNamespace(sf.GetMethod().ReflectedType?.Namespace))
{
string methodName = $"{sf?.GetMethod()?.DeclaringType?.Name}.{sf?.GetMethod()?.Name}";
if (methodName.Contains("WrapApiBoundaryAsync"))
{
apiBoundaryReached = true;
}
var hasCleanMethodName = !methodName.StartsWith("<", StringComparison.InvariantCultureIgnoreCase);
if (hasCleanMethodName)
{
lastInternalApiName = methodName;
}
}
else if (!string.IsNullOrEmpty(fileName))
{
stack.Add(new() { File = fileName, Line = sf.GetFileLineNumber(), Column = sf.GetFileColumnNumber() });
if (!string.IsNullOrEmpty(lastInternalApiName) && !apiBoundaryReached)
{
apiName = lastInternalApiName;
}
}
}

is looking for a specific pattern of method names in the stack trace. This is fragile unless all the methods being looked for are marked with [MethodImpl(MethodImplOptions.NoInlining)]. Note that with PGO the JIT may now inline methods at virtual, interface, and delegate call sites.

I suspect the fix may be as simple as marking this method noinline

internal Task WrapApiCallAsync(Func<Task> action, bool isInternal = false)
=> WrapApiCallAsync(
async () =>
{
await action().ConfigureAwait(false);
return true;
},
isInternal);

but there may be more cases elsewhere in this code that need similar treatment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions