Fix TraceEvent CaptureState API to work with keywords not previously enabled in session#2222
Fix TraceEvent CaptureState API to work with keywords not previously enabled in session#2222
Conversation
Query existing provider keywords and merge with requested keywords before CaptureState. Enables provider with merged keywords if necessary to ensure CaptureState works even when using keywords that haven't been previously enabled. Co-authored-by: brianrob <6210322+brianrob@users.noreply.github.com>
src/TraceEvent/TraceEventSession.cs
Outdated
| } | ||
| // Query existing keywords and merge them with requested keywords before capture state | ||
| ulong mergedKeywords = matchAnyKeywords; | ||
| Guid* providerPtr = stackalloc Guid[1]; |
There was a problem hiding this comment.
Instead of using stackalloc, you should be able to use the fixed keyword to convert the Guid to a Guid*.
There was a problem hiding this comment.
Done. Replaced stackalloc with fixed keyword using an array to get the Guid pointer. Commit: 2659beb
src/TraceEvent/TraceEventSession.cs
Outdated
| ulong mergedKeywords = matchAnyKeywords; | ||
| Guid* providerPtr = stackalloc Guid[1]; | ||
| *providerPtr = providerGuid; | ||
| long? existingKeywords = GetEnabledKeywordsForProviderAndSession(providerPtr, (ulong)m_SessionId); |
There was a problem hiding this comment.
We will also need the level. Please modify GetEnabledKeywordsForProviderAndSession instead return a struct containing the keywords and level. You can rename it GetEnabledInfoForProviderAndSession. The level in the setruct should be of type TraceEventLevel. Then, pass the level to the call to EnableTraceEx2 that enables the provider. Leave the call to CAPTURE_STATE with a Verbose level.
There was a problem hiding this comment.
Done. Modified the method to return EnabledProviderInfo struct containing both keywords and level, renamed it to GetEnabledInfoForProviderAndSession, and now pass the returned level to EnableTraceEx2. CAPTURE_STATE still uses Verbose level as requested. Commit: 9c4bdaf
…level support Co-authored-by: brianrob <6210322+brianrob@users.noreply.github.com>
Co-authored-by: brianrob <6210322+brianrob@users.noreply.github.com>
…eviously enabled.
|
@ivberg, do you have a repro handy that you can test this with? |
|
Spoke with @ivberg offline and I have tested this locally. |
src/TraceEvent/TraceEventSession.cs
Outdated
| EnabledProviderInfo? existingInfo = GetEnabledInfoForProviderAndSession(&providerGuid, (ulong)m_SessionId); | ||
| if (existingInfo.HasValue) | ||
| { | ||
| mergedKeywords = matchAnyKeywords | existingInfo.Value.MatchAnyKeywords; |
There was a problem hiding this comment.
NIT: mergedKeywords |= existingInfo.Value.MatchAnyKeywords; better reflects the "merge" operation and the content of the variable. I would also write it this way to avoid the future bug where you merge something before this and lose it because you're not accumulating.
The
TraceEventSession.CaptureStateAPI was not working correctly when called with keywords that hadn't already been enabled for the provider in the current ETW session. This caused CaptureState events to not be triggered, even though the API call appeared to succeed.Problem
When a provider was enabled with specific keywords and then
CaptureStatewas called with different keywords, the capture state events would not be generated:Solution
The fix queries the ETW session to determine the currently enabled keywords for the provider and merges them with the requested capture state keywords before sending the command:
GetEnabledKeywordsForProviderAndSessionmethod to retrieve currently enabled keywordsThis ensures that CaptureState works consistently regardless of previously enabled keywords, matching the behavior of tools like xperf:
# This works in xperf regardless of previously enabled keywords xperf -capturestate SessionName 3a26b1ff-7484-7484-7484-15261f42614d:1:5Changes
TraceEventSession.CaptureStatemethod to query and merge existing provider keywordsFixes #2132.
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.