Skip to content

Commit c19133d

Browse files
committed
Roughly handles WPP events to avoid RegisteredTraceEventParser assertions
1 parent 08fd134 commit c19133d

File tree

5 files changed

+47
-20
lines changed

5 files changed

+47
-20
lines changed

src/TraceEvent/ETWTraceEventSource.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ public override bool Process()
151151
/// <summary>
152152
/// Reprocess a pre-constructed event which this processor has presumably created. Helpful to re-examine
153153
/// "unknown" events, perhaps after a manifest has been received from the ETW stream.
154-
/// Note when queuing events to reprocess you must <see cref="TraceEvent.Clone">Clone</see> them first
154+
/// Note when queuing events to reprocess you must <see cref="TraceEvent.Clone()">Clone</see> them first
155155
/// or certain internal data may no longer be available and you may receive memory access violations.
156156
/// </summary>
157157
/// <param name="ev">Event to re-process.</param>

src/TraceEvent/RegisteredTraceEventParser.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,12 @@ internal override DynamicTraceEventData TryLookup(TraceEvent unknownEvent)
621621
/// </summary>
622622
internal static DynamicTraceEventData TryLookupWorker(TraceEvent unknownEvent, Dictionary<MapKey, IDictionary<long, string>> mapTable = null)
623623
{
624+
// We are not able to handle WPP events in this parser.
625+
if (unknownEvent.lookupAsWPP)
626+
{
627+
return null;
628+
}
629+
624630
// Is this a TraceLogging style
625631
DynamicTraceEventData ret = null;
626632

@@ -1192,7 +1198,7 @@ protected unsafe ExternalTraceEventParser(TraceEventSource source, bool dontRegi
11921198
parsedTemplate = TryLookup(unknown);
11931199
if (parsedTemplate == null)
11941200
{
1195-
m_state.m_templates.Add(unknown.Clone(), null); // add an entry to remember that we tried and failed.
1201+
m_state.m_templates.Add(unknown.Clone(true), null); // add an entry to remember that we tried and failed.
11961202
}
11971203
}
11981204
if (parsedTemplate == null)
@@ -1369,7 +1375,6 @@ internal class TraceEventComparer : IEqualityComparer<TraceEvent>
13691375
{
13701376
public bool Equals(TraceEvent x, TraceEvent y)
13711377
{
1372-
Debug.Assert(!(x.lookupAsWPP && x.lookupAsClassic));
13731378
if (x.lookupAsClassic != y.lookupAsClassic)
13741379
{
13751380
return false;
@@ -1380,15 +1385,15 @@ public bool Equals(TraceEvent x, TraceEvent y)
13801385
return false;
13811386
}
13821387

1383-
if (x.lookupAsClassic)
1388+
if (x.lookupAsWPP)
13841389
{
13851390
Debug.Assert(x.taskGuid != Guid.Empty && y.taskGuid != Guid.Empty);
1386-
return (x.taskGuid == y.taskGuid) && (x.Opcode == y.Opcode);
1391+
return (x.taskGuid == y.taskGuid) && (x.ID == y.ID);
13871392
}
1388-
else if (x.lookupAsWPP)
1393+
else if (x.lookupAsClassic)
13891394
{
13901395
Debug.Assert(x.taskGuid != Guid.Empty && y.taskGuid != Guid.Empty);
1391-
return (x.taskGuid == y.taskGuid) && (x.ID == y.ID);
1396+
return (x.taskGuid == y.taskGuid) && (x.Opcode == y.Opcode);
13921397
}
13931398
else
13941399
{

src/TraceEvent/TraceEvent.cs

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,14 @@ public bool IsClassicProvider
977977
// [SecuritySafeCritical]
978978
get { return (eventRecord->EventHeader.Flags & TraceEventNativeMethods.EVENT_HEADER_FLAG_CLASSIC_HEADER) != 0; }
979979
}
980+
/// <summary>
981+
/// Returns true if this event is from the TraceMessage function (typically indicates from a WPP provider)
982+
/// </summary>
983+
public bool IsTraceMessage
984+
{
985+
// [SecuritySafeCritical]
986+
get { return (eventRecord->EventHeader.Flags & TraceEventNativeMethods.EVENT_HEADER_FLAG_TRACE_MESSAGE) != 0; }
987+
}
980988

981989
/// <summary>
982990
/// The ID of the container that emitted the event, if available.
@@ -1341,10 +1349,30 @@ public byte[] EventData(byte[] targetBuffer, int targetStartIndex, int sourceSta
13411349
/// <para>This method is more expensive than copy out all the event data from the TraceEvent instance
13421350
/// to a type of your construction.</para>
13431351
/// </summary>
1344-
public virtual unsafe TraceEvent Clone()
1352+
public virtual TraceEvent Clone()
13451353
{
1346-
TraceEvent ret = (TraceEvent)MemberwiseClone(); // Clone myself.
1347-
ret.next = null; // the clone is not in any linked list.
1354+
return Clone(false);
1355+
}
1356+
1357+
internal unsafe TraceEvent Clone(bool toTemplate)
1358+
{
1359+
TraceEvent ret = (TraceEvent)MemberwiseClone(); // Clone myself.
1360+
ret.next = null; // the clone is not in any linked list.
1361+
1362+
if (toTemplate)
1363+
{
1364+
// We are cloning to a template, so we don't need to clone the data.
1365+
ret.eventRecord = null;
1366+
ret.myBuffer = IntPtr.Zero;
1367+
ret.instanceContainerID = null;
1368+
1369+
// Also zero out the dispatch-related fields.
1370+
ret.traceEventSource = null;
1371+
ret.Target = null;
1372+
1373+
return ret;
1374+
}
1375+
13481376
if (eventRecord != null)
13491377
{
13501378
int userDataLength = (EventDataLength + 3) / 4 * 4; // DWORD align
@@ -2013,15 +2041,6 @@ internal int ThreadIDforStacks()
20132041
/// </summary>
20142042
protected internal virtual void SetState(object state) { }
20152043

2016-
protected internal TraceEvent CloneToTemplate()
2017-
{
2018-
TraceEvent ret = Clone();
2019-
ret.traceEventSource = null;
2020-
ret.eventRecord = null;
2021-
ret.Target = null;
2022-
return ret;
2023-
}
2024-
20252044
#endregion
20262045
#region Private
20272046
private static char HexDigit(int digit)
@@ -3663,6 +3682,7 @@ internal TraceEvent Lookup(TraceEventNativeMethods.EVENT_RECORD* eventRecord)
36633682

36643683
#if DEBUG // ASSERT we found the event using the mechanism we expected to use.
36653684
Debug.Assert(((eventRecord->EventHeader.Flags & TraceEventNativeMethods.EVENT_HEADER_FLAG_CLASSIC_HEADER) != 0) == curTemplate.lookupAsClassic);
3685+
Debug.Assert(((eventRecord->EventHeader.Flags & TraceEventNativeMethods.EVENT_HEADER_FLAG_TRACE_MESSAGE) != 0) == curTemplate.lookupAsWPP);
36663686
if (curTemplate.lookupAsClassic)
36673687
{
36683688
Debug.Assert(curTemplate.taskGuid == eventRecord->EventHeader.ProviderId);
@@ -3710,6 +3730,7 @@ internal TraceEvent Lookup(TraceEventNativeMethods.EVENT_RECORD* eventRecord)
37103730
unhandledEventTemplate.userData = eventRecord->UserData;
37113731
unhandledEventTemplate.eventIndex = currentID;
37123732
unhandledEventTemplate.lookupAsClassic = unhandledEventTemplate.IsClassicProvider;
3733+
unhandledEventTemplate.lookupAsWPP = unhandledEventTemplate.IsTraceMessage;
37133734
if ((((int)currentID) & 0xFFFF) == 0) // Every 64K events allow Thread.Interrupt.
37143735
{
37153736
System.Threading.Thread.Sleep(0);

src/TraceEvent/TraceEventNativeMethods.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ internal static extern int TraceQueryInformation(
399399
*/
400400

401401
internal const ushort EVENT_HEADER_FLAG_STRING_ONLY = 0x0004;
402+
internal const ushort EVENT_HEADER_FLAG_TRACE_MESSAGE = 0x0008;
402403
internal const ushort EVENT_HEADER_FLAG_NO_CPUTIME = 0x0010;
403404
internal const ushort EVENT_HEADER_FLAG_32_BIT_HEADER = 0x0020;
404405
internal const ushort EVENT_HEADER_FLAG_64_BIT_HEADER = 0x0040;

src/TraceEvent/TraceLog.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,7 @@ private unsafe TraceLog(TraceEventDispatcher source)
783783
}
784784
if (toSend.containsSelfDescribingMetadata)
785785
{
786-
var template = toSend.CloneToTemplate();
786+
var template = toSend.Clone(true);
787787
realTimeSource.Dynamic.OnNewEventDefintion(template, true);
788788
return true;
789789
}

0 commit comments

Comments
 (0)