microsoft / perfview

PerfView is a CPU and memory performance-analysis tool
http://channel9.msdn.com/Series/PerfView-Tutorial
MIT License
4.2k stars 712 forks source link

Add a public API to read call stacks in EventPipeEventSource #2084

Open ocoanet opened 4 months ago

ocoanet commented 4 months ago

EventPipeEventSource writes call stacks into the trace event eventRecord internal field (here).

There is no public API to read the call stacks from the eventRecord, so call stacks are not accessible, particularly when using the "push" model with EventPipeEventSource. The only public way the read call stacks is to use TraceLog, which reads the eventRecord (here).

Would it be possible to add a public API to read the call stacks from the events generated by EventPipeEventSource?

API example:

public class EventPipeStack
{
    public EventPipeStack(ulong[] addresses);

    public int Length { get; }

    public ulong this[int index] { get; }
}

public class EventPipeEventSource
{
    // Reads call stack from `eventRecord`
    public static bool TryGetStack(TraceEvent traceEvent, out EventPipeStack stack);
}

Of course, there are many design options for the API. I simply thought that adding TryGetStack in EventPipeEventSource next to GetEventRecordForEventData would make sense.

brianrob commented 3 months ago

@ocoanet, can you please share some details about what you're trying to do? As with other source types such as ETWTraceEventSource, stacks are really only usable via TraceLog. It is possible to get the raw IPs from ETWTraceEventSource by parsing the stack events, but symbol resolution requires a full pass through the trace, including rundown data. This is why we only expose stacks through TraceLog, which does the first pass during creation of the TraceLog.

It would be technically possible to expose the raw stack data, but this generally isn't useful unless/until you can resolve it. Do you have a scenario that requires raw data without resolution?

ocoanet commented 3 months ago

My goal is to do real-time profiling on a running application. I have a working solution that reads call stacks addresses using unsafe code and resolve method names using MethodLoad / MethodUnload events. I know a PR recently added real-time support for EventPipe in TraceLog but I suspect that my custom solution might still be more interesting because I can explicitly ignore many trace events and only load / resolve the call stacks of specific events, with a low memory footprint.