Skip to content

private provider not correctly initialized when starting process after etw session is started #115420

Open
@Maoni0

Description

@Maoni0

Description

I started perfview this way
.\perfview /nogui /accepteula /GCCollectOnly /NoV2Rundown /NoNGENRundown /NoRundown collect temp.etl
and then started a test that does some BGCs
and the private GC events are not in the trace. this is because each time EtwCallBack is called, context->RegistrationHandle only gets initialized after the call is finished but we are using this handle to do the comparison instead of context.

1st time this happens to be called with the public provider. 2nd time this is called with the private provider. and this time context->RegistrationHandle, Microsoft_Windows_DotNETRuntimeRundownHandle and Microsoft_Windows_DotNETRuntimePrivateHandle are all 0's, and because we do this if (context->RegistrationHandle == Microsoft_Windows_DotNETRuntimeRundownHandle) first, and this will be true, it will then do

            providerIndex = DotNETRuntimeRundown;
            providerContext = MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context;

and treat this as the rundown provider. if you change the code to use context to compare instead of handle, it'll work -

        BOOLEAN bIsPublicTraceHandle = (context== MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context.EtwProvider);

        BOOLEAN bIsPrivateTraceHandle = (context== MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_DOTNET_Context.EtwProvider);

        BOOLEAN bIsRundownTraceHandle = (context== MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context.EtwProvider);

        BOOLEAN bIsStressTraceHandle = (context == MICROSOFT_WINDOWS_DOTNETRUNTIME_STRESS_PROVIDER_DOTNET_Context.EtwProvider);

        // EventPipeEtwCallback contains some GC eventing functionality shared between EventPipe and ETW.
        // Eventually, we'll want to merge these two codepaths whenever we can.
        CallbackProviderIndex providerIndex = DotNETRuntime;
        DOTNET_TRACE_CONTEXT providerContext = MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context;
        if (bIsPublicTraceHandle)
        {
            providerIndex = DotNETRuntime;
            providerContext = MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context;
        }
        else if (bIsRundownTraceHandle)
        {
            providerIndex = DotNETRuntimeRundown;
            providerContext = MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context;
        }
        else if (bIsStressTraceHandle)
        {
            providerIndex = DotNETRuntimeStress;
            providerContext = MICROSOFT_WINDOWS_DOTNETRUNTIME_STRESS_PROVIDER_DOTNET_Context;
        }
        else if (bIsPrivateTraceHandle)
        {
            providerIndex = DotNETRuntimePrivate;
            providerContext = MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_DOTNET_Context;
        } else {
            assert(!"unknown registration handle");
            return;
        }

Reproduction Steps

I started perfview this way
.\perfview /nogui /accepteula /GCCollectOnly /NoV2Rundown /NoNGENRundown /NoRundown collect temp.etl
and then started a test that does some BGCs
stop the trace

Expected behavior

you should see BGC events from the private runtime provider
Image

Actual behavior

there are no BGC events

Regression?

unknown

Known Workarounds

none

Configuration

No response

Other information

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions