Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Roughly handles WPP events to avoid RegisteredTraceEventParser assertion #2160

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/TraceEvent/ETWTraceEventSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public override bool Process()
/// <summary>
/// Reprocess a pre-constructed event which this processor has presumably created. Helpful to re-examine
/// "unknown" events, perhaps after a manifest has been received from the ETW stream.
/// Note when queuing events to reprocess you must <see cref="TraceEvent.Clone">Clone</see> them first
/// Note when queuing events to reprocess you must <see cref="TraceEvent.Clone()">Clone</see> them first
/// or certain internal data may no longer be available and you may receive memory access violations.
/// </summary>
/// <param name="ev">Event to re-process.</param>
Expand Down
17 changes: 11 additions & 6 deletions src/TraceEvent/RegisteredTraceEventParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,12 @@ internal override DynamicTraceEventData TryLookup(TraceEvent unknownEvent)
/// </summary>
internal static DynamicTraceEventData TryLookupWorker(TraceEvent unknownEvent, Dictionary<MapKey, IDictionary<long, string>> mapTable = null)
{
// We are not able to handle WPP events in this parser.
if (unknownEvent.lookupAsWPP)
{
return null;
}

// Is this a TraceLogging style
DynamicTraceEventData ret = null;

Expand Down Expand Up @@ -1192,7 +1198,7 @@ protected unsafe ExternalTraceEventParser(TraceEventSource source, bool dontRegi
parsedTemplate = TryLookup(unknown);
if (parsedTemplate == null)
{
m_state.m_templates.Add(unknown.Clone(), null); // add an entry to remember that we tried and failed.
m_state.m_templates.Add(unknown.Clone(true), null); // add an entry to remember that we tried and failed.
}
}
if (parsedTemplate == null)
Expand Down Expand Up @@ -1369,7 +1375,6 @@ internal class TraceEventComparer : IEqualityComparer<TraceEvent>
{
public bool Equals(TraceEvent x, TraceEvent y)
{
Debug.Assert(!(x.lookupAsWPP && x.lookupAsClassic));
if (x.lookupAsClassic != y.lookupAsClassic)
{
return false;
Expand All @@ -1380,15 +1385,15 @@ public bool Equals(TraceEvent x, TraceEvent y)
return false;
}

if (x.lookupAsClassic)
if (x.lookupAsWPP)
{
Debug.Assert(x.taskGuid != Guid.Empty && y.taskGuid != Guid.Empty);
return (x.taskGuid == y.taskGuid) && (x.Opcode == y.Opcode);
return (x.taskGuid == y.taskGuid) && (x.ID == y.ID);
}
else if (x.lookupAsWPP)
else if (x.lookupAsClassic)
{
Debug.Assert(x.taskGuid != Guid.Empty && y.taskGuid != Guid.Empty);
return (x.taskGuid == y.taskGuid) && (x.ID == y.ID);
return (x.taskGuid == y.taskGuid) && (x.Opcode == y.Opcode);
}
else
{
Expand Down
45 changes: 33 additions & 12 deletions src/TraceEvent/TraceEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,14 @@ public bool IsClassicProvider
// [SecuritySafeCritical]
get { return (eventRecord->EventHeader.Flags & TraceEventNativeMethods.EVENT_HEADER_FLAG_CLASSIC_HEADER) != 0; }
}
/// <summary>
/// Returns true if this event is from the TraceMessage function (typically indicates from a WPP provider)
/// </summary>
public bool IsTraceMessage
{
// [SecuritySafeCritical]
get { return (eventRecord->EventHeader.Flags & TraceEventNativeMethods.EVENT_HEADER_FLAG_TRACE_MESSAGE) != 0; }
}

/// <summary>
/// The ID of the container that emitted the event, if available.
Expand Down Expand Up @@ -1341,10 +1349,30 @@ public byte[] EventData(byte[] targetBuffer, int targetStartIndex, int sourceSta
/// <para>This method is more expensive than copy out all the event data from the TraceEvent instance
/// to a type of your construction.</para>
/// </summary>
public virtual unsafe TraceEvent Clone()
public virtual TraceEvent Clone()
{
TraceEvent ret = (TraceEvent)MemberwiseClone(); // Clone myself.
ret.next = null; // the clone is not in any linked list.
return Clone(false);
}

internal unsafe TraceEvent Clone(bool toTemplate)
{
TraceEvent ret = (TraceEvent)MemberwiseClone(); // Clone myself.
ret.next = null; // the clone is not in any linked list.

if (toTemplate)
{
// We are cloning to a template, so we don't need to clone the data.
ret.eventRecord = null;
ret.myBuffer = IntPtr.Zero;
ret.instanceContainerID = null;

// Also zero out the dispatch-related fields.
ret.traceEventSource = null;
ret.Target = null;

return ret;
}

if (eventRecord != null)
{
int userDataLength = (EventDataLength + 3) / 4 * 4; // DWORD align
Expand Down Expand Up @@ -2013,15 +2041,6 @@ internal int ThreadIDforStacks()
/// </summary>
protected internal virtual void SetState(object state) { }

protected internal TraceEvent CloneToTemplate()
{
TraceEvent ret = Clone();
ret.traceEventSource = null;
ret.eventRecord = null;
ret.Target = null;
return ret;
}

#endregion
#region Private
private static char HexDigit(int digit)
Expand Down Expand Up @@ -3663,6 +3682,7 @@ internal TraceEvent Lookup(TraceEventNativeMethods.EVENT_RECORD* eventRecord)

#if DEBUG // ASSERT we found the event using the mechanism we expected to use.
Debug.Assert(((eventRecord->EventHeader.Flags & TraceEventNativeMethods.EVENT_HEADER_FLAG_CLASSIC_HEADER) != 0) == curTemplate.lookupAsClassic);
Debug.Assert(((eventRecord->EventHeader.Flags & TraceEventNativeMethods.EVENT_HEADER_FLAG_TRACE_MESSAGE) != 0) == curTemplate.lookupAsWPP);
if (curTemplate.lookupAsClassic)
{
Debug.Assert(curTemplate.taskGuid == eventRecord->EventHeader.ProviderId);
Expand Down Expand Up @@ -3710,6 +3730,7 @@ internal TraceEvent Lookup(TraceEventNativeMethods.EVENT_RECORD* eventRecord)
unhandledEventTemplate.userData = eventRecord->UserData;
unhandledEventTemplate.eventIndex = currentID;
unhandledEventTemplate.lookupAsClassic = unhandledEventTemplate.IsClassicProvider;
unhandledEventTemplate.lookupAsWPP = unhandledEventTemplate.IsTraceMessage;
if ((((int)currentID) & 0xFFFF) == 0) // Every 64K events allow Thread.Interrupt.
{
System.Threading.Thread.Sleep(0);
Expand Down
1 change: 1 addition & 0 deletions src/TraceEvent/TraceEventNativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ internal static extern int TraceQueryInformation(
*/

internal const ushort EVENT_HEADER_FLAG_STRING_ONLY = 0x0004;
internal const ushort EVENT_HEADER_FLAG_TRACE_MESSAGE = 0x0008;
internal const ushort EVENT_HEADER_FLAG_NO_CPUTIME = 0x0010;
internal const ushort EVENT_HEADER_FLAG_32_BIT_HEADER = 0x0020;
internal const ushort EVENT_HEADER_FLAG_64_BIT_HEADER = 0x0040;
Expand Down
2 changes: 1 addition & 1 deletion src/TraceEvent/TraceLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,7 @@ private unsafe TraceLog(TraceEventDispatcher source)
}
if (toSend.containsSelfDescribingMetadata)
{
var template = toSend.CloneToTemplate();
var template = toSend.Clone(true);
realTimeSource.Dynamic.OnNewEventDefintion(template, true);
return true;
}
Expand Down