Skip to content
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

[tools][trace] Add stopping event options to dotnet-trace #4363

Merged
merged 3 commits into from
Nov 2, 2023

Conversation

mdh1418
Copy link
Member

@mdh1418 mdh1418 commented Oct 25, 2023

Fixes #3125

This PR provides users another method to stop a dotnet-trace via a stopping event similar to that of dotnet-monitor, originally implemented in dotnet/dotnet-monitor#2557.

Three arguments are added to the dotnet-trace collect command to specify a stopping event:

Argument Description
--stopping-event-provider-name A string, parsed as-is, that will stop the trace upon hitting an event with the matching provider name. For a more specific stopping event, additionally provide --stopping-event-event-name and/or --stopping-event-payload-filter.
--stopping-event-event-name A string, parsed as-is, that will stop the trace upon hitting an event with the matching event name. Requires --stopping-event-provider-name to be set. For a more specific stopping event, additionally provide --stopping-event-payload-filter.
--stopping-event-payload-filter A string, parsed as [payload_field_name]:[payload_field_value] pairs separated by commas, that will stop the trace upon hitting an event with a matching payload. Requires --stopping-event-provider-name and --stopping-event-event-name to be set.

Note: Though technically --stopping-event-payload-filter can be set without needing a --stopping-event-event-name, this may lead to mismatched payloads should another TraceEvent under the same provider not have that particular payload field name. Until there is a good reason to stop a trace given a payload filter regardless of the event name, we require --stopping-event-event-name to be set whenever --stopping-event-payload-filter is provided.

To stop a trace at a particular event, dotnet-monitor's approach using an EventMonitor is adopted. Upon hitting a TraceEvent with a matching ProviderName, EventName (if specified), and PayloadFilter (if specified), we trigger dotnet-trace's fallback logic to stop the EventPipeSession before the EventStream ends.

Note: As the EventStream is being parsed asynchronously, there will be some events that pass through between the time a trace event matching the specified stopping event arguments is parsed and the EventPipeSession is stopped.

In addition, this PR modifies EventMonitor to use the ClrTraceEventParser to parse TraceEvent objects under the Microsoft-Windows-DotNETRuntime provider, and the DynamicTraceEventParser otherwise. The ClrTraceEventParser is generated to understand the ETW event manifest for Microsoft-Windows-DotNETRuntime events. The previous implementation defaulting to DynamicTraceEventParser would not work on non-Windows platforms such as OSX which could not parse the payload to populate PayloadNames and PayloadValue(i) because there was no manifest available. On the other hand, Windows is able to locate manifest data for known events through the OS.


Testing

With an Android App

    private static void PrintA()
    {
        Console.WriteLine("A");
        Thread.Sleep(1000);
    }
    
    ...
    
    private static void PrintK()
    {
        Console.WriteLine("K");
        Thread.Sleep(1000);
    }

    public static void Main(string[] args)
    {
        Console.WriteLine("Hello, Android!"); // logcat
        PrintA();
        PrintB();
        PrintC();
        PrintD();
        PrintE();
        PrintF();
        PrintG();
        PrintH();
        PrintI();
        PrintJ();
        PrintK();

        while (true)
        {
            Thread.Sleep(100);
        }
    }

Running dotnet-dsrouter to connect the diagnostic tooling with the android device
./artifacts/bin/dotnet-dsrouter/Debug/net6.0/dotnet-dsrouter android -v debug

Tracing with a stopping event args provided
./artifacts/bin/dotnet-trace/Debug/net6.0/dotnet-trace collect -p 16683 --providers Microsoft-Windows-DotNETRuntime:0x1F000080018:5 --stopping-event-provider-name Microsoft-Windows-DotNETRuntime --stopping-event-event-name Method/JittingStarted --stopping-event-payload-filter MethodName:PrintA

dotnet-dsrouter_20231024_165648.nettrace.zip

There are no Method/JittingStarted events with MethodName PrintC through PrintK in the .nettrace, showing that the trace was indeed stopped after seeing the PrintA event. The events after PrintA are an artifact of the second note above. Below is the JITStats of the .nettrace opened in perfview, showing that the last method was PrintB.

JITStatsPrintA

@mdh1418 mdh1418 requested a review from a team as a code owner October 25, 2023 00:45
@mdh1418
Copy link
Member Author

mdh1418 commented Oct 25, 2023

Copy link
Member

@lateralusX lateralusX left a comment

Choose a reason for hiding this comment

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

Overall LGTM!

Since the original need for this is to replace Androids profiled AOT scenario where they run automated tooling capturing startup traces that will be passed to dotnet-pgo using the new filter capabilities in dotnet-pgo. The generated mibc file could then be shipped with the release and used when building apps using Mono AOT compiler to optimize Android startup scenarios.

@jonathanpeppers This PR + changes included in dotnet-pgo dotnet/runtime#89853 should give you all tooling needed to fully replace old Mono profiled AOT with use of dotnet-trace and dotnet-pgo. dotnet-monitor already included the stop trigger solution for sometime, but having the same capabilities in dotnet-trace reduce the complexity running this in automation scenarios and the new filters in dotnet-pgo gives you fine grained control on what methods to take from nettrace file -> mibc file(s) for profiled AOT scenarios.

Copy link
Member

@mikelle-rogers mikelle-rogers left a comment

Choose a reason for hiding this comment

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

Will you please update the dotnet-trace documentation, which is found here?

Copy link
Member

@schmittjoseph schmittjoseph left a comment

Choose a reason for hiding this comment

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

LGTM, I also ran the dotnet-monitor tests relating to stop-on-event with your changes and everything looks good.

@mdh1418
Copy link
Member Author

mdh1418 commented Nov 2, 2023

@mikelle-rogers @dotnet/dotnet-diag Could I get another review to get this in?

Copy link
Member

@mikelle-rogers mikelle-rogers left a comment

Choose a reason for hiding this comment

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

Looks good to me! Thank you

@mdh1418
Copy link
Member Author

mdh1418 commented Nov 2, 2023

I don't have permissions to merge in this repo, can I get some help with that too 😄

@hoyosjs hoyosjs merged commit 66f7ca0 into dotnet:main Nov 2, 2023
19 checks passed
@mdh1418 mdh1418 deleted the stopping_event_option branch November 3, 2023 01:34
@github-actions github-actions bot locked and limited conversation to collaborators Jan 8, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[dotnet-trace] Add option to stop tracing on trigger
5 participants