Before you can ask ETW to collect PMCs, you have to know the indexes of those PMCs, since ETW wants to talk about PMCs by index (not by name). How do you find these indexes?
That’s the subject of today’s hint: ETW doesn’t provide an API for mapping a PMC name to a PMC index. To do so, you will need to retrieve the list of PMCs from ETW and search it yourself.
To retrieve the list, use TraceQueryInformation with TraceProfileSourceListInfo
. Call it once to get the total size of the list, then call it a second time to have it copy the list into a properly-sized buffer you’ve allocated:
ULONG BufferSize;
TraceQueryInformation(0, TraceProfileSourceListInfo, 0, 0, &BufferSize);
BYTE *Buffer = // ... allocate BufferSize worth of space here ...
TraceQueryInformation(0, TraceProfileSourceListInfo, Buffer, BufferSize, &BufferSize);
The resulting buffer will contain the PROFILE_SOURCE_INFO
structures you need to do the PMC name-to-index mapping.
That concludes today’s hint. Until tomorrow, good luck making progress on the Spooktacular Challenge!
I will post additional hints here every day until Halloween. If you’d like the rest of the Spooktacular Challenge to be delivered automatically to your inbox, you can select a subscription option here:
By luck, I'm a bit ahead of this hint and this API keeps on feeling like it was designed for DEFCON participants. Thank you for turning The Ultimate Sadness into a fun challenge
Hi Casey!
Some sources indicate that you should be able to PMC data to an ETW event:
* https://learn.microsoft.com/en-us/windows-hardware/test/wpt/recording-pmu-events#collecting-pmu-events--on-etw-events
* https://randomascii.wordpress.com/2016/11/27/cpu-performance-counters-on-windows/
So my wild guess is the following: would it be possible to emit a custom ETW event for "begin" and "end" sample and request that PMC data is attached to it..
You would then parse the ETW log (oh, joy!) file search for begin/end traces and extract the PMC values. The Benchmark.net library might be doing something similar (https://github.com/dotnet/BenchmarkDotNet/blob/master/samples/BenchmarkDotNet.Samples/IntroHardwareCounters.cs).
Not sure if the counter values are maintained per-thread. So we might also handle context switch events..