Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit a0a1e56

Browse files
noahfalkdanmoseley
authored andcommitted
Support large EventSource filter args (#27522)
1. Fix NullReferenceException. When the filter args exceeded the hard-coded size limit GetDataFromController would return data = null. The code previously asserted that data was not null and triggered NRE when it was. The fix correctly null checks the value instead of asserting and uses an empty args dictionary in this case, the same as if filter args had been empty to begin with. 2. ETW has always limited filter args to 1024 bytes but EventPipe has no such restriction. When using DiagnosticSourceEventSource it can be useful to specify a larger filter arg blob. I can't do anything about ETW's restriction but there is no need for the runtime to force EventPipe to be equally limited. The larger size also reduces the chance that we need to hit the fallback path above causing filter args to be ignored.
1 parent 934ef61 commit a0a1e56

File tree

1 file changed

+17
-11
lines changed

1 file changed

+17
-11
lines changed

src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventProvider.cs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -322,19 +322,22 @@ unsafe void EtwEnableCallBack(
322322
GetDataFromController(etwSessionId, filterData, out command, out data, out keyIndex))
323323
{
324324
args = new Dictionary<string, string?>(4);
325-
Debug.Assert(data != null);
326-
while (keyIndex < data.Length)
325+
// data can be null if the filterArgs had a very large size which failed our sanity check
326+
if (data != null)
327327
{
328-
int keyEnd = FindNull(data, keyIndex);
329-
int valueIdx = keyEnd + 1;
330-
int valueEnd = FindNull(data, valueIdx);
331-
if (valueEnd < data.Length)
328+
while (keyIndex < data.Length)
332329
{
333-
string key = System.Text.Encoding.UTF8.GetString(data, keyIndex, keyEnd - keyIndex);
334-
string value = System.Text.Encoding.UTF8.GetString(data, valueIdx, valueEnd - valueIdx);
335-
args[key] = value;
330+
int keyEnd = FindNull(data, keyIndex);
331+
int valueIdx = keyEnd + 1;
332+
int valueEnd = FindNull(data, valueIdx);
333+
if (valueEnd < data.Length)
334+
{
335+
string key = System.Text.Encoding.UTF8.GetString(data, keyIndex, keyEnd - keyIndex);
336+
string value = System.Text.Encoding.UTF8.GetString(data, valueIdx, valueEnd - valueIdx);
337+
args[key] = value;
338+
}
339+
keyIndex = valueEnd + 1;
336340
}
337-
keyIndex = valueEnd + 1;
338341
}
339342
}
340343

@@ -635,7 +638,10 @@ private unsafe bool GetDataFromController(int etwSessionId,
635638
}
636639
else
637640
{
638-
if (filterData->Ptr != 0 && 0 < filterData->Size && filterData->Size <= 1024)
641+
// ETW limited filter data to 1024 bytes but EventPipe doesn't. DiagnosticSourceEventSource
642+
// can legitimately use large filter data buffers to encode a large set of events and properties
643+
// that should be gathered so I am bumping the limit from 1K -> 100K.
644+
if (filterData->Ptr != 0 && 0 < filterData->Size && filterData->Size <= 100*1024)
639645
{
640646
data = new byte[filterData->Size];
641647
Marshal.Copy((IntPtr)filterData->Ptr, data, 0, data.Length);

0 commit comments

Comments
 (0)