Skip to content

Commit

Permalink
Merge pull request #1934 from brianrob/dev/brianrob/thread-safe-trace…
Browse files Browse the repository at this point in the history
…eventsession

Protect Initialization of TraceEventSession Provider Lists
  • Loading branch information
brianrob authored Oct 19, 2023
2 parents d52d78f + e76170f commit a6c8791
Showing 1 changed file with 37 additions and 20 deletions.
57 changes: 37 additions & 20 deletions src/TraceEvent/TraceEventSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1631,27 +1631,35 @@ internal static SortedDictionary<string, Guid> ProviderNameToGuid
{
if (s_providersByName == null)
{
s_providersByName = new SortedDictionary<string, Guid>(StringComparer.OrdinalIgnoreCase);
int buffSize = 0;
var hr = TraceEventNativeMethods.TdhEnumerateProviders(null, ref buffSize);
Debug.Assert(hr == 122); // ERROR_INSUFFICIENT_BUFFER
var buffer = stackalloc byte[buffSize];
var providersDesc = (TraceEventNativeMethods.PROVIDER_ENUMERATION_INFO*)buffer;

hr = TraceEventNativeMethods.TdhEnumerateProviders(providersDesc, ref buffSize);
if ((hr == 0) && (providersDesc != null))
lock (s_lock)
{
var providers = (TraceEventNativeMethods.TRACE_PROVIDER_INFO*)&providersDesc[1];
for (int i = 0; i < providersDesc->NumberOfProviders; i++)
if (s_providersByName == null)
{
var name = new string((char*)&buffer[providers[i].ProviderNameOffset]);
s_providersByName[name] = providers[i].ProviderGuid;
SortedDictionary<string, Guid> providersByName = new SortedDictionary<string, Guid>(StringComparer.OrdinalIgnoreCase);
int buffSize = 0;
var hr = TraceEventNativeMethods.TdhEnumerateProviders(null, ref buffSize);
Debug.Assert(hr == 122); // ERROR_INSUFFICIENT_BUFFER
var buffer = stackalloc byte[buffSize];
var providersDesc = (TraceEventNativeMethods.PROVIDER_ENUMERATION_INFO*)buffer;

hr = TraceEventNativeMethods.TdhEnumerateProviders(providersDesc, ref buffSize);
if ((hr == 0) && (providersDesc != null))
{
var providers = (TraceEventNativeMethods.TRACE_PROVIDER_INFO*)&providersDesc[1];
for (int i = 0; i < providersDesc->NumberOfProviders; i++)
{
var name = new string((char*)&buffer[providers[i].ProviderNameOffset]);
providersByName[name] = providers[i].ProviderGuid;
}

s_providersByName = providersByName;
}
else
{
Trace.WriteLine("TdhEnumerateProviders failed HR = " + hr);
}
}
}
else
{
Trace.WriteLine("TdhEnumerateProviders failed HR = " + hr);
}
}
return s_providersByName;
}
Expand All @@ -1663,10 +1671,18 @@ internal static Dictionary<Guid, string> ProviderGuidToName
{
if (s_providerNames == null)
{
s_providerNames = new Dictionary<Guid, string>(ProviderNameToGuid.Count);
foreach (var keyValue in ProviderNameToGuid)
lock (s_lock)
{
s_providerNames[keyValue.Value] = keyValue.Key;
if (s_providerNames == null)
{
Dictionary<Guid, string> providerNames = new Dictionary<Guid, string>(ProviderNameToGuid.Count);
foreach (var keyValue in ProviderNameToGuid)
{
providerNames[keyValue.Value] = keyValue.Key;
}

s_providerNames = providerNames;
}
}
}
return s_providerNames;
Expand Down Expand Up @@ -1721,6 +1737,7 @@ private int ComputeEventIdsBufferSize(IList<int> eventIds)
return (eventIds.Count - 1) * 2 + sizeof(TraceEventNativeMethods.EVENT_FILTER_EVENT_ID);
}

private static object s_lock = new object();
private static SortedDictionary<string, Guid> s_providersByName;
private static Dictionary<Guid, string> s_providerNames;

Expand Down

0 comments on commit a6c8791

Please # to comment.